@@ -192,6 +192,7 @@ void HEkk::clearEkkDataInfo() {
192192 info.backtracking_basis_ .clear ();
193193 info.backtracking_basis_costs_shifted_ = false ;
194194 info.backtracking_basis_costs_perturbed_ = false ;
195+ info.backtracking_basis_bounds_shifted_ = false ;
195196 info.backtracking_basis_bounds_perturbed_ = false ;
196197 info.backtracking_basis_workShift_ .clear ();
197198 info.backtracking_basis_workLowerShift_ .clear ();
@@ -221,6 +222,7 @@ void HEkk::clearEkkDataInfo() {
221222 info.allow_bound_perturbation = true ;
222223 info.costs_shifted = false ;
223224 info.costs_perturbed = false ;
225+ info.bounds_shifted = false ;
224226 info.bounds_perturbed = false ;
225227
226228 info.num_primal_infeasibilities = kHighsIllegalInfeasibilityCount ;
@@ -1052,8 +1054,8 @@ HighsStatus HEkk::solve(const bool force_phase2) {
10521054 algorithm_name = " primal" ;
10531055 reportSimplexPhaseIterations (options_->log_options , iteration_count_, info_,
10541056 true );
1055- highsLogUser (options_->log_options , HighsLogType::kInfo ,
1056- " Using EKK primal simplex solver \n " );
1057+ highsLogUser (options_->log_options , HighsLogType::kInfo , " Using %s \n " ,
1058+ simplexStrategyToString ( kSimplexStrategyPrimal ). c_str () );
10571059 HEkkPrimal primal_solver (*this );
10581060 call_status = primal_solver.solve (force_phase2);
10591061 assert (called_return_from_solve_);
@@ -1066,17 +1068,17 @@ HighsStatus HEkk::solve(const bool force_phase2) {
10661068 // Solve, depending on the particular strategy
10671069 if (simplex_strategy == kSimplexStrategyDualTasks ) {
10681070 highsLogUser (options_->log_options , HighsLogType::kInfo ,
1069- " Using EKK parallel dual simplex solver - SIP with "
1070- " concurrency of %d \n " ,
1071+ " Using %s with concurrency of %d \n " ,
1072+ simplexStrategyToString ( kSimplexStrategyDualTasks ). c_str () ,
10711073 int (info_.num_concurrency ));
10721074 } else if (simplex_strategy == kSimplexStrategyDualMulti ) {
10731075 highsLogUser (options_->log_options , HighsLogType::kInfo ,
1074- " Using EKK parallel dual simplex solver - PAMI with "
1075- " concurrency of %d \n " ,
1076+ " Using %s with concurrency of %d \n " ,
1077+ simplexStrategyToString ( kSimplexStrategyDualMulti ). c_str () ,
10761078 int (info_.num_concurrency ));
10771079 } else {
1078- highsLogUser (options_->log_options , HighsLogType::kInfo ,
1079- " Using EKK dual simplex solver - serial \n " );
1080+ highsLogUser (options_->log_options , HighsLogType::kInfo , " Using %s \n " ,
1081+ simplexStrategyToString ( kSimplexStrategyDual ). c_str () );
10801082 }
10811083 HEkkDual dual_solver (*this );
10821084 call_status = dual_solver.solve (force_phase2);
@@ -1101,7 +1103,7 @@ HighsStatus HEkk::solve(const bool force_phase2) {
11011103 if (return_status == HighsStatus::kError )
11021104 return returnFromEkkSolve (return_status);
11031105 highsLogDev (options_->log_options , HighsLogType::kInfo ,
1104- " EKK %s simplex solver returns %" HIGHSINT_FORMAT
1106+ " %s simplex solver returns %" HIGHSINT_FORMAT
11051107 " primal and %" HIGHSINT_FORMAT
11061108 " dual infeasibilities: "
11071109 " Status %s\n " ,
@@ -1877,6 +1879,8 @@ bool HEkk::getBacktrackingBasis() {
18771879 basis_ = info_.backtracking_basis_ ;
18781880 info_.costs_shifted = (info_.backtracking_basis_costs_shifted_ != 0 );
18791881 info_.costs_perturbed = (info_.backtracking_basis_costs_perturbed_ != 0 );
1882+ info_.bounds_shifted = (info_.backtracking_basis_bounds_shifted_ != 0 );
1883+ info_.bounds_perturbed = (info_.backtracking_basis_bounds_perturbed_ != 0 );
18801884 info_.workShift_ = info_.backtracking_basis_workShift_ ;
18811885 const HighsInt num_tot = lp_.num_col_ + lp_.num_row_ ;
18821886 for (HighsInt iVar = 0 ; iVar < num_tot; iVar++)
@@ -1901,6 +1905,7 @@ void HEkk::putBacktrackingBasis(
19011905 info_.backtracking_basis_ .basicIndex_ = basicIndex_before_compute_factor;
19021906 info_.backtracking_basis_costs_shifted_ = info_.costs_shifted ;
19031907 info_.backtracking_basis_costs_perturbed_ = info_.costs_perturbed ;
1908+ info_.backtracking_basis_bounds_shifted_ = info_.bounds_shifted ;
19041909 info_.backtracking_basis_bounds_perturbed_ = info_.bounds_perturbed ;
19051910 info_.backtracking_basis_workShift_ = info_.workShift_ ;
19061911 const HighsInt num_tot = lp_.num_col_ + lp_.num_row_ ;
@@ -2291,6 +2296,24 @@ bool HEkk::lpFactorRowCompatible(const HighsInt expectedNumRow) const {
22912296 return consistent_num_row;
22922297}
22932298
2299+ std::string HEkk::simplexStrategyToString (
2300+ const HighsInt simplex_strategy) const {
2301+ assert (kSimplexStrategyMin <= simplex_strategy &&
2302+ simplex_strategy <= kSimplexStrategyMax );
2303+ if (simplex_strategy == kSimplexStrategyChoose )
2304+ return " choose simplex solver" ;
2305+ if (simplex_strategy == kSimplexStrategyDual ) return " dual simplex solver" ;
2306+ if (simplex_strategy == kSimplexStrategyDualPlain )
2307+ return " serial dual simplex solver" ;
2308+ if (simplex_strategy == kSimplexStrategyDualTasks )
2309+ return " parallel dual simplex solver - SIP" ;
2310+ if (simplex_strategy == kSimplexStrategyDualMulti )
2311+ return " parallel dual simplex solver - PAMI" ;
2312+ if (simplex_strategy == kSimplexStrategyPrimal )
2313+ return " primal simplex solver" ;
2314+ return " Unknown" ;
2315+ }
2316+
22942317void HEkk::zeroBasicDuals () {
22952318 for (HighsInt iRow = 0 ; iRow < lp_.num_row_ ; iRow++)
22962319 info_.workDual_ [basis_.basicIndex_ [iRow]] = 0 ;
@@ -2544,6 +2567,7 @@ void HEkk::initialiseBound(const SimplexAlgorithm algorithm,
25442567 const HighsInt solve_phase, const bool perturb) {
25452568 initialiseLpColBound ();
25462569 initialiseLpRowBound ();
2570+ info_.bounds_shifted = false ;
25472571 info_.bounds_perturbed = false ;
25482572 // Primal simplex bounds are either from the LP or perturbed
25492573 if (algorithm == SimplexAlgorithm::kPrimal ) {
@@ -3523,7 +3547,8 @@ HighsStatus HEkk::returnFromSolve(const HighsStatus return_status) {
35233547 case HighsModelStatus::kInfeasible : {
35243548 // Primal infeasibility has been identified in primal phase 1,
35253549 // or proved in dual phase 2. There should be no primal
3526- // perturbations
3550+ // perturbations or shifts
3551+ assert (!info_.bounds_shifted );
35273552 assert (!info_.bounds_perturbed );
35283553 if (exit_algorithm_ == SimplexAlgorithm::kPrimal ) {
35293554 // Reset the simplex costs and recompute duals after primal
@@ -3540,6 +3565,7 @@ HighsStatus HEkk::returnFromSolve(const HighsStatus return_status) {
35403565 // Dual simplex has identified dual infeasibility in phase
35413566 // 1. There should be no dual perturbations
35423567 assert (exit_algorithm_ == SimplexAlgorithm::kDual );
3568+ assert (!info_.costs_shifted );
35433569 assert (!info_.costs_perturbed );
35443570 // Reset the simplex bounds and recompute primals
35453571 initialiseBound (SimplexAlgorithm::kDual , kSolvePhase2 );
@@ -3553,7 +3579,10 @@ HighsStatus HEkk::returnFromSolve(const HighsStatus return_status) {
35533579 // Primal simplex has identified unboundedness in phase 2. There
35543580 // should be no primal or dual perturbations
35553581 assert (exit_algorithm_ == SimplexAlgorithm::kPrimal );
3556- assert (!info_.costs_perturbed && !info_.bounds_perturbed );
3582+ assert (!info_.costs_shifted );
3583+ assert (!info_.costs_perturbed );
3584+ assert (!info_.bounds_shifted );
3585+ assert (!info_.bounds_perturbed );
35573586 computeSimplexInfeasible ();
35583587 // Primal solution should be feasible
35593588 assert (info_.num_primal_infeasibilities == 0 );
@@ -3583,7 +3612,7 @@ HighsStatus HEkk::returnFromSolve(const HighsStatus return_status) {
35833612 default : {
35843613 highsLogDev (
35853614 options_->log_options , HighsLogType::kError ,
3586- " EKK %s simplex solver returns status %s\n " ,
3615+ " %s simplex solver returns status %s\n " ,
35873616 exit_algorithm_ == SimplexAlgorithm::kPrimal ? " primal" : " dual" ,
35883617 utilModelStatusToString (model_status_).c_str ());
35893618 return HighsStatus::kError ;
@@ -3603,6 +3632,7 @@ HighsStatus HEkk::returnFromSolve(const HighsStatus return_status) {
36033632 } else {
36043633 return_dual_solution_status_ = kSolutionStatusInfeasible ;
36053634 }
3635+ assert (debugNoShiftsOrPerturbations ());
36063636 computePrimalObjectiveValue ();
36073637 if (!options_->log_dev_level ) {
36083638 const bool force = true ;
0 commit comments