| 3974 | void Highs::clearIis() { iis_.clear(); } |
| 3975 | |
| 3976 | HighsStatus Highs::completeSolutionFromDiscreteAssignment() { |
| 3977 | // Determine whether the current solution of a MIP is feasible and, |
| 3978 | // if not, try to assign values to continuous variables and discrete |
| 3979 | // variables not at integer values to achieve a feasible |
| 3980 | // solution. Valuable in the case where users make a heuristic |
| 3981 | // (partial) assignment of discrete variables |
| 3982 | assert(model_.isMip() && solution_.value_valid); |
| 3983 | HighsLp& lp = model_.lp_; |
| 3984 | // Determine whether the solution contains undefined values, in |
| 3985 | // order to decide whether to check its feasibility |
| 3986 | const bool contains_undefined_values = solution_.hasUndefined(); |
| 3987 | if (!contains_undefined_values) { |
| 3988 | bool valid, integral, feasible; |
| 3989 | // Determine whether this solution is integer feasible |
| 3990 | HighsStatus return_status = assessLpPrimalSolution( |
| 3991 | "", options_, lp, solution_, valid, integral, feasible); |
| 3992 | assert(return_status != HighsStatus::kError); |
| 3993 | assert(valid); |
| 3994 | // If the current solution is integer feasible, then it can be |
| 3995 | // used by MIP solver to get a primal bound |
| 3996 | if (feasible) return HighsStatus::kOk; |
| 3997 | } |
| 3998 | // Save the column bounds and integrality in preparation for fixing |
| 3999 | // the discrete variables when user-supplied values are |
| 4000 | // integer |
| 4001 | std::vector<double> save_col_lower = lp.col_lower_; |
| 4002 | std::vector<double> save_col_upper = lp.col_upper_; |
| 4003 | std::vector<HighsVarType> save_integrality = lp.integrality_; |
| 4004 | const bool have_integrality = (lp.integrality_.size() != 0); |
| 4005 | assert(have_integrality); |
| 4006 | // Count the number of fixed and unfixed discrete variables |
| 4007 | HighsInt num_fixed_discrete_variable = 0; |
| 4008 | HighsInt num_unfixed_discrete_variable = 0; |
| 4009 | for (HighsInt iCol = 0; iCol < lp.num_col_; iCol++) { |
| 4010 | const double primal = solution_.col_value[iCol]; |
| 4011 | // Default value is lower bound, unless primal is integer for a |
| 4012 | // discrete variable |
| 4013 | solution_.col_value[iCol] = lp.col_lower_[iCol]; |
| 4014 | if (lp.integrality_[iCol] == HighsVarType::kContinuous) continue; |
| 4015 | // Fix discrete variable if its value is defined and integer |
| 4016 | if (primal == kHighsUndefined) { |
| 4017 | num_unfixed_discrete_variable++; |
| 4018 | } else { |
| 4019 | const double lower = lp.col_lower_[iCol]; |
| 4020 | const double upper = lp.col_upper_[iCol]; |
| 4021 | const HighsVarType type = |
| 4022 | have_integrality ? lp.integrality_[iCol] : HighsVarType::kContinuous; |
| 4023 | double col_infeasibility = 0; |
| 4024 | double integer_infeasibility = 0; |
| 4025 | assessColPrimalSolution(options_, primal, lower, upper, type, |
| 4026 | col_infeasibility, integer_infeasibility); |
| 4027 | if (integer_infeasibility > options_.mip_feasibility_tolerance) { |
| 4028 | num_unfixed_discrete_variable++; |
| 4029 | } else { |
| 4030 | // Variable is integer feasible, so fix it at this value and |
| 4031 | // remove its integrality |
| 4032 | num_fixed_discrete_variable++; |
| 4033 | lp.col_lower_[iCol] = primal; |
nothing calls this directly
no test coverage detected