| 571 | } |
| 572 | |
| 573 | void HEkkDual::solvePhase1() { |
| 574 | // Performs dual phase 1 iterations. Returns solve_phase with value |
| 575 | // |
| 576 | // kSolvePhaseError => Solver error |
| 577 | // |
| 578 | // kSolvePhaseTabooBasis => Only basis change is taboo |
| 579 | // |
| 580 | // kSolvePhaseExit => LP identified as dual infeasible |
| 581 | // |
| 582 | // kSolvePhaseUnknown => Back-tracking due to singularity |
| 583 | // |
| 584 | // kSolvePhase1 => Dual infeasibility suspected, but have to go out |
| 585 | // and back in to solvePhase1 to perform fresh rebuild. Also if |
| 586 | // bailing out due to reaching time/iteration limit. |
| 587 | // |
| 588 | // kSolvePhase2 => Continue with dual phase 2 iterations |
| 589 | |
| 590 | HighsSimplexInfo& info = ekk_instance_.info_; |
| 591 | HighsSimplexStatus& status = ekk_instance_.status_; |
| 592 | HighsModelStatus& model_status = ekk_instance_.model_status_; |
| 593 | // When starting a new phase the (updated) dual objective function |
| 594 | // value isn't known. Indicate this so that when the value computed |
| 595 | // from scratch in build() isn't checked against the updated |
| 596 | // value |
| 597 | status.has_primal_objective_value = false; |
| 598 | status.has_dual_objective_value = false; |
| 599 | // Set rebuild_reason so that it's assigned when first tested |
| 600 | rebuild_reason = kRebuildReasonNo; |
| 601 | // Use to set solve_phase = kSolvePhase1 and ekk_instance_.solve_bailout_ = |
| 602 | // false so they are set if solvePhase1() is called directly - but it never is |
| 603 | assert(solve_phase == kSolvePhase1); |
| 604 | assert(!ekk_instance_.solve_bailout_); |
| 605 | if (ekk_instance_.bailout()) return; |
| 606 | // Report the phase start |
| 607 | highsLogDev(ekk_instance_.options_->log_options, HighsLogType::kDetailed, |
| 608 | "dual-phase-1-start\n"); |
| 609 | // Switch to dual phase 1 bounds |
| 610 | ekk_instance_.initialiseBound(SimplexAlgorithm::kDual, solve_phase); |
| 611 | ekk_instance_.initialiseNonbasicValueAndMove(); |
| 612 | |
| 613 | // If there's no backtracking basis, save the initial basis in case of |
| 614 | // backtracking |
| 615 | if (!info.valid_backtracking_basis_) ekk_instance_.putBacktrackingBasis(); |
| 616 | |
| 617 | // Main solving structure |
| 618 | analysis->simplexTimerStart(IterateClock); |
| 619 | for (;;) { |
| 620 | analysis->simplexTimerStart(IterateDualRebuildClock); |
| 621 | rebuild(); |
| 622 | analysis->simplexTimerStop(IterateDualRebuildClock); |
| 623 | if (solve_phase == kSolvePhaseError) { |
| 624 | model_status = HighsModelStatus::kSolveError; |
| 625 | return; |
| 626 | } |
| 627 | if (solve_phase == kSolvePhaseUnknown) { |
| 628 | // If backtracking, may change phase, so drop out |
| 629 | analysis->simplexTimerStop(IterateClock); |
| 630 | return; |
nothing calls this directly
no test coverage detected