| 2490 | } |
| 2491 | |
| 2492 | HighsStatus Highs::setSolution(const HighsSolution& solution) { |
| 2493 | HighsStatus return_status = HighsStatus::kOk; |
| 2494 | // Determine whether a new solution will be defined. If so, |
| 2495 | // the old solution and any basis are cleared |
| 2496 | const bool new_primal_solution = |
| 2497 | model_.lp_.num_col_ > 0 && |
| 2498 | solution.col_value.size() >= static_cast<size_t>(model_.lp_.num_col_); |
| 2499 | const bool new_dual_solution = |
| 2500 | model_.lp_.num_row_ > 0 && |
| 2501 | solution.row_dual.size() >= static_cast<size_t>(model_.lp_.num_row_); |
| 2502 | const bool new_solution = new_primal_solution || new_dual_solution; |
| 2503 | |
| 2504 | if (new_solution) { |
| 2505 | invalidateSolverData(); |
| 2506 | } else { |
| 2507 | // Solution is rejected, so give a logging message and error |
| 2508 | // return |
| 2509 | highsLogUser( |
| 2510 | options_.log_options, HighsLogType::kError, |
| 2511 | "setSolution: User solution is rejected due to mismatch between " |
| 2512 | "size of col_value and row_dual vectors (%d, %d) and number " |
| 2513 | "of columns and rows in the model (%d, %d)\n", |
| 2514 | int(solution.col_value.size()), int(solution.row_dual.size()), |
| 2515 | int(model_.lp_.num_col_), int(model_.lp_.num_row_)); |
| 2516 | return_status = HighsStatus::kError; |
| 2517 | } |
| 2518 | |
| 2519 | if (new_primal_solution) { |
| 2520 | solution_.col_value = solution.col_value; |
| 2521 | if (model_.lp_.num_row_ > 0) { |
| 2522 | // Worth computing the row values |
| 2523 | solution_.row_value.resize(model_.lp_.num_row_); |
| 2524 | // Matrix must be column-wise |
| 2525 | model_.lp_.a_matrix_.ensureColwise(); |
| 2526 | return_status = interpretCallStatus( |
| 2527 | options_.log_options, calculateRowValuesQuad(model_.lp_, solution_), |
| 2528 | return_status, "calculateRowValuesQuad"); |
| 2529 | if (return_status == HighsStatus::kError) return return_status; |
| 2530 | } |
| 2531 | solution_.value_valid = true; |
| 2532 | } |
| 2533 | if (new_dual_solution) { |
| 2534 | solution_.row_dual = solution.row_dual; |
| 2535 | if (model_.lp_.num_col_ > 0) { |
| 2536 | // Worth computing the column duals |
| 2537 | solution_.col_dual.resize(model_.lp_.num_col_); |
| 2538 | // Matrix must be column-wise |
| 2539 | model_.lp_.a_matrix_.ensureColwise(); |
| 2540 | return_status = interpretCallStatus( |
| 2541 | options_.log_options, calculateColDualsQuad(model_.lp_, solution_), |
| 2542 | return_status, "calculateColDuals"); |
| 2543 | if (return_status == HighsStatus::kError) return return_status; |
| 2544 | } |
| 2545 | solution_.dual_valid = true; |
| 2546 | } |
| 2547 | return returnFromHighs(return_status); |
| 2548 | } |
| 2549 | |