| 815 | } |
| 816 | |
| 817 | void HEkkDual::solvePhase2() { |
| 818 | // Performs dual phase 2 iterations. Returns solve_phase with value |
| 819 | // |
| 820 | // kSolvePhaseError => Solver error |
| 821 | // |
| 822 | // kSolvePhaseTabooBasis => Only basis change is taboo |
| 823 | // |
| 824 | // kSolvePhaseExit => LP identified as not having an optimal solution |
| 825 | // |
| 826 | // kSolvePhaseUnknown => Back-tracking due to singularity |
| 827 | // |
| 828 | // kSolvePhaseOptimal => Primal feasible and no dual infeasibilities => |
| 829 | // Optimal |
| 830 | // |
| 831 | // kSolvePhase1 => Primal feasible and dual infeasibilities. |
| 832 | // |
| 833 | // kSolvePhase2 => Dual unboundedness suspected, but have to go out |
| 834 | // and back in to solvePhase2 to perform fresh rebuild. Also if |
| 835 | // bailing out due to reaching time/iteration limit or dual |
| 836 | // objective |
| 837 | // |
| 838 | // kSolvePhaseOptimalCleanup => Continue with primal phase 2 iterations to |
| 839 | // clean up dual infeasibilities |
| 840 | // |
| 841 | // Have to set multi_chooseAgain = 1 since it may come in set to 0 |
| 842 | // from the end of Phase 1, implying that there is a set of |
| 843 | // attractive candidates to choose from in minorChooseRow() so |
| 844 | // majorChooseRow() is unnecessary. If there are no such candidates |
| 845 | // optimality may be declared in error. Previously, the forced |
| 846 | // reinversion in the rebuild at the start of phase 2 led to |
| 847 | // update_count == 0 causing multi_chooseAgain to be set to 1 in |
| 848 | // majorChooseRow! |
| 849 | multi_chooseAgain = 1; |
| 850 | HighsSimplexInfo& info = ekk_instance_.info_; |
| 851 | HighsSimplexStatus& status = ekk_instance_.status_; |
| 852 | HighsModelStatus& model_status = ekk_instance_.model_status_; |
| 853 | // When starting a new phase the (updated) dual objective function |
| 854 | // value isn't known. Indicate this so that when the value computed |
| 855 | // from scratch in build() isn't checked against the updated |
| 856 | // value |
| 857 | status.has_primal_objective_value = false; |
| 858 | status.has_dual_objective_value = false; |
| 859 | // Set rebuild_reason so that it's assigned when first tested |
| 860 | rebuild_reason = kRebuildReasonNo; |
| 861 | // Set solve_phase = kSolvePhase2 and ekk_instance_.solve_bailout_ = false so |
| 862 | // they are set if solvePhase2() is called directly |
| 863 | solve_phase = kSolvePhase2; |
| 864 | ekk_instance_.solve_bailout_ = false; |
| 865 | if (ekk_instance_.bailout()) return; |
| 866 | // Report the phase start |
| 867 | highsLogDev(ekk_instance_.options_->log_options, HighsLogType::kDetailed, |
| 868 | "dual-phase-2-start\n"); |
| 869 | // Collect free variables |
| 870 | dualRow.createFreelist(); |
| 871 | |
| 872 | // If there's no backtracking basis, save the initial basis in case |
| 873 | // of backtracking |
| 874 | if (!info.valid_backtracking_basis_) ekk_instance_.putBacktrackingBasis(); |
nothing calls this directly
no test coverage detected