51 const std::optional<LazyMutableCopy<MPModelProto>> optional_model =
53 if (!optional_model)
return response;
59 const std::string model_name = model.
name();
60 highs.passModelName(model_name);
63 if (request->has_solver_specific_parameters()) {
65 request->solver_specific_parameters(), highs);
66 if (!parameters_status.ok()) {
73 if (request->solver_time_limit_seconds() > 0) {
74 HighsStatus status = highs.setOptionValue(
75 "time_limit", request->solver_time_limit_seconds());
76 if (status == HighsStatus::kError) {
84 bool has_integer_variables =
false;
86 std::vector<double> obj_coeffs(variable_size, 0);
87 std::vector<double> lb(variable_size);
88 std::vector<double> ub(variable_size);
89 std::vector<HighsVarType> integrality(variable_size);
90 for (
int v = 0; v < variable_size; ++v) {
97 request->solver_type() ==
99 ? HighsVarType::kInteger
100 : HighsVarType::kContinuous;
101 if (integrality[v] == HighsVarType::kInteger) {
102 has_integer_variables =
true;
106 highs.addVars(variable_size, lb.data(), ub.data());
109 if (has_integer_variables) {
110 for (
int v = 0; v < variable_size; ++v) {
111 highs.changeColIntegrality(v, integrality[v]);
116 for (
int column = 0; column < variable_size; column++) {
117 highs.changeColCost(column, obj_coeffs[column]);
121 for (
int v = 0; v < variable_size; ++v) {
123 std::string varname_str =
"";
124 if (!variable.
name().empty()) {
125 varname_str = variable.
name();
126 highs.passColName(v, varname_str);
133 std::vector<HighsInt> hint_index(0, num_hints);
134 std::vector<double> hint_value(0, num_hints);
135 for (
int i = 0; i < num_hints; ++i) {
139 const int* hint_indices = &hint_index[0];
140 const double* hint_values = &hint_value[0];
141 highs.setSolution((HighsInt)num_hints, hint_indices, hint_values);
149 -std::numeric_limits<double>::infinity()) {
151 highs.addRow(-kHighsInf,
156 if (status == HighsStatus::kError) {
162 std::numeric_limits<double>::infinity()) {
169 if (status == HighsStatus::kError) {
181 if (status == HighsStatus::kError) {
189 std::string constraint_name_str =
"";
190 if (!constraint.
name().empty()) {
191 constraint_name_str = constraint.
name();
192 highs.passRowName(c, constraint_name_str);
198 response.
set_status_str(
"general constraints are not supported in Highs");
204 const ObjSense pass_sense = ObjSense::kMaximize;
205 highs.changeObjectiveSense(pass_sense);
210 highs.changeObjectiveOffset(offset);
214 if (request->enable_internal_solver_output()) {
215 highs.setOptionValue(
"log_to_console",
true);
216 highs.setOptionValue(
"output_flag",
true);
218 highs.setOptionValue(
"log_to_console",
false);
219 highs.setOptionValue(
"output_flag",
false);
222 const absl::Time time_before = absl::Now();
225 HighsStatus run_status = highs.run();
226 switch (run_status) {
227 case HighsStatus::kError: {
232 case HighsStatus::kWarning: {
236 case HighsStatus::kOk: {
237 HighsModelStatus model_status = highs.getModelStatus();
238 switch (model_status) {
239 case HighsModelStatus::kOptimal:
242 case HighsModelStatus::kUnboundedOrInfeasible:
244 "The model may actually be unbounded: HiGHS returned "
245 "kUnboundedOrInfeasible");
248 case HighsModelStatus::kInfeasible:
251 case HighsModelStatus::kUnbounded:
256 const HighsInfo& info = highs.getInfo();
257 if (info.primal_solution_status == kSolutionStatusFeasible)
265 const absl::Duration solving_duration = absl::Now() - time_before;
268 absl::ToDoubleSeconds(solving_duration));
273 double objective_value = highs.getObjectiveValue();
278 for (
int column = 0; column < variable_size; column++) {
280 highs.getSolution().col_value[column];
283 if (has_integer_variables) {
284 for (
int v = 0; v < variable_size; ++v) {
305 if (parameters.empty())
return absl::OkStatus();
306 std::vector<std::string> error_messages;
307 for (absl::string_view line : absl::StrSplit(parameters,
'\n')) {
310 if (line[0] ==
'#')
continue;
311 for (absl::string_view token :
312 absl::StrSplit(line,
',', absl::SkipWhitespace())) {
313 if (token.empty())
continue;
314 std::vector<std::string> key_value =
315 absl::StrSplit(token, absl::ByAnyChar(
" ="), absl::SkipWhitespace());
317 if (key_value.size() != 2) {
318 const std::string current_message =
319 absl::StrCat(
"Cannot parse parameter '", token,
320 "'. Expected format is 'ParameterName value' or "
321 "'ParameterName=value'");
322 error_messages.push_back(current_message);
325 HighsStatus status = highs.setOptionValue(key_value[0], key_value[1]);
326 if (status == HighsStatus::kError) {
327 const std::string current_message =
328 absl::StrCat(
"Error setting parameter '", key_value[0],
329 "' to value '", key_value[1],
"': ");
330 error_messages.push_back(current_message);
336 if (error_messages.empty())
return absl::OkStatus();
337 return absl::InvalidArgumentError(absl::StrJoin(error_messages,
"\n"));