| 2063 | } |
| 2064 | |
| 2065 | void HEkkDual::updateDual() { |
| 2066 | // Update the dual values |
| 2067 | // |
| 2068 | // If reinversion is needed then skip this method |
| 2069 | if (rebuild_reason) return; |
| 2070 | |
| 2071 | // Update - dual (shift and back) |
| 2072 | if (theta_dual == 0) { |
| 2073 | // Little to do if theta_dual is zero |
| 2074 | // debugUpdatedObjectiveValue(ekk_instance_, algorithm, solve_phase, |
| 2075 | // "Before shift_cost"); |
| 2076 | shiftCost(variable_in, -workDual[variable_in]); |
| 2077 | // debugUpdatedObjectiveValue(ekk_instance_, algorithm, solve_phase, |
| 2078 | // "After shift_cost"); |
| 2079 | } else { |
| 2080 | // Update the whole vector of dual values |
| 2081 | // debugUpdatedObjectiveValue(ekk_instance_, algorithm, solve_phase, |
| 2082 | // "Before calling dualRow.updateDual"); |
| 2083 | dualRow.updateDual(theta_dual); |
| 2084 | if (ekk_instance_.info_.simplex_strategy != kSimplexStrategyDualPlain && |
| 2085 | slice_PRICE) { |
| 2086 | // Update the slice-by-slice copy of dual variables |
| 2087 | for (HighsInt i = 0; i < slice_num; i++) |
| 2088 | slice_dualRow[i].updateDual(theta_dual); |
| 2089 | } |
| 2090 | // debugUpdatedObjectiveValue(ekk_instance_, algorithm, solve_phase, |
| 2091 | // "After calling dualRow.updateDual"); |
| 2092 | } |
| 2093 | // Identify the changes in the dual objective |
| 2094 | double dual_objective_value_change; |
| 2095 | const double variable_in_delta_dual = workDual[variable_in]; |
| 2096 | const double variable_in_value = workValue[variable_in]; |
| 2097 | const HighsInt variable_in_nonbasicFlag = |
| 2098 | ekk_instance_.basis_.nonbasicFlag_[variable_in]; |
| 2099 | dual_objective_value_change = |
| 2100 | variable_in_nonbasicFlag * (-variable_in_value * variable_in_delta_dual); |
| 2101 | dual_objective_value_change *= ekk_instance_.cost_scale_; |
| 2102 | ekk_instance_.info_.updated_dual_objective_value += |
| 2103 | dual_objective_value_change; |
| 2104 | // Surely variable_out_nonbasicFlag is always 0 since it's basic - so there's |
| 2105 | // no dual objective change |
| 2106 | const HighsInt variable_out_nonbasicFlag = |
| 2107 | ekk_instance_.basis_.nonbasicFlag_[variable_out]; |
| 2108 | assert(variable_out_nonbasicFlag == 0); |
| 2109 | if (variable_out_nonbasicFlag) { |
| 2110 | const double variable_out_delta_dual = workDual[variable_out] - theta_dual; |
| 2111 | const double variable_out_value = workValue[variable_out]; |
| 2112 | dual_objective_value_change = |
| 2113 | variable_out_nonbasicFlag * |
| 2114 | (-variable_out_value * variable_out_delta_dual); |
| 2115 | dual_objective_value_change *= ekk_instance_.cost_scale_; |
| 2116 | ekk_instance_.info_.updated_dual_objective_value += |
| 2117 | dual_objective_value_change; |
| 2118 | } |
| 2119 | workDual[variable_in] = 0; |
| 2120 | workDual[variable_out] = -theta_dual; |
| 2121 | |
| 2122 | // debugUpdatedObjectiveValue(ekk_instance_, algorithm, solve_phase, "Before |