OR-Tools  9.3
gurobi_proto_solver.cc
Go to the documentation of this file.
1// Copyright 2010-2021 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
15
16#include <limits>
17#include <memory>
18#include <numeric>
19#include <string>
20#include <vector>
21
22#include "absl/status/status.h"
23#include "absl/status/statusor.h"
24#include "absl/strings/str_cat.h"
25#include "absl/strings/str_format.h"
26#include "absl/strings/str_join.h"
27#include "absl/strings/str_split.h"
28#include "absl/types/optional.h"
31#include "ortools/base/timer.h"
34#include "ortools/linear_solver/linear_solver.pb.h"
37
38namespace operations_research {
39
40namespace {
41constexpr int GRB_OK = 0;
42
43inline absl::Status GurobiCodeToUtilStatus(int error_code,
44 const char* source_file,
45 int source_line,
46 const char* statement,
47 GRBenv* const env) {
48 if (error_code == GRB_OK) return absl::OkStatus();
49 return absl::InvalidArgumentError(absl::StrFormat(
50 "Gurobi error code %d (file '%s', line %d) on '%s': %s", error_code,
51 source_file, source_line, statement, GRBgeterrormsg(env)));
52}
53
54int AddIndicatorConstraint(const MPGeneralConstraintProto& gen_cst,
55 GRBmodel* gurobi_model,
56 std::vector<int>* tmp_variables,
57 std::vector<double>* tmp_coefficients) {
58 CHECK(gurobi_model != nullptr);
59 CHECK(tmp_variables != nullptr);
60 CHECK(tmp_coefficients != nullptr);
61
62 const auto& ind_cst = gen_cst.indicator_constraint();
63 MPConstraintProto cst = ind_cst.constraint();
64 if (cst.lower_bound() > -std::numeric_limits<double>::infinity()) {
66 gurobi_model, gen_cst.name().c_str(), ind_cst.var_index(),
67 ind_cst.var_value(), cst.var_index_size(),
68 cst.mutable_var_index()->mutable_data(),
69 cst.mutable_coefficient()->mutable_data(),
70 cst.upper_bound() == cst.lower_bound() ? GRB_EQUAL : GRB_GREATER_EQUAL,
71 cst.lower_bound());
72 if (status != GRB_OK) return status;
73 }
74 if (cst.upper_bound() < std::numeric_limits<double>::infinity() &&
75 cst.lower_bound() != cst.upper_bound()) {
76 return GRBaddgenconstrIndicator(gurobi_model, gen_cst.name().c_str(),
77 ind_cst.var_index(), ind_cst.var_value(),
78 cst.var_index_size(),
79 cst.mutable_var_index()->mutable_data(),
80 cst.mutable_coefficient()->mutable_data(),
81 GRB_LESS_EQUAL, cst.upper_bound());
82 }
83
84 return GRB_OK;
85}
86
87int AddSosConstraint(const MPSosConstraint& sos_cst, GRBmodel* gurobi_model,
88 std::vector<int>* tmp_variables,
89 std::vector<double>* tmp_weights) {
90 CHECK(gurobi_model != nullptr);
91 CHECK(tmp_variables != nullptr);
92 CHECK(tmp_weights != nullptr);
93
94 tmp_variables->resize(sos_cst.var_index_size(), 0);
95 for (int v = 0; v < sos_cst.var_index_size(); ++v) {
96 (*tmp_variables)[v] = sos_cst.var_index(v);
97 }
98 tmp_weights->resize(sos_cst.var_index_size(), 0);
99 if (sos_cst.weight_size() == sos_cst.var_index_size()) {
100 for (int w = 0; w < sos_cst.weight_size(); ++w) {
101 (*tmp_weights)[w] = sos_cst.weight(w);
102 }
103 } else {
104 DCHECK_EQ(sos_cst.weight_size(), 0);
105 // Gurobi requires variable weights in their SOS constraints.
106 std::iota(tmp_weights->begin(), tmp_weights->end(), 1);
107 }
108
109 std::vector<int> types = {sos_cst.type() == MPSosConstraint::SOS1_DEFAULT
111 : GRB_SOS_TYPE2};
112 std::vector<int> begins = {0};
113 return GRBaddsos(gurobi_model, /*numsos=*/1,
114 /*nummembers=*/sos_cst.var_index_size(),
115 /*types=*/types.data(),
116 /*beg=*/begins.data(), /*ind=*/tmp_variables->data(),
117 /*weight*/ tmp_weights->data());
118}
119
120int AddQuadraticConstraint(const MPGeneralConstraintProto& gen_cst,
121 GRBmodel* gurobi_model) {
122 CHECK(gurobi_model != nullptr);
123 constexpr double kInfinity = std::numeric_limits<double>::infinity();
124
125 CHECK(gen_cst.has_quadratic_constraint());
126 const MPQuadraticConstraint& quad_cst = gen_cst.quadratic_constraint();
127
128 auto addqconstr = [](GRBmodel* gurobi_model, MPQuadraticConstraint quad_cst,
129 char sense, double rhs, const std::string& name) {
130 return GRBaddqconstr(
131 gurobi_model,
132 /*numlnz=*/quad_cst.var_index_size(),
133 /*lind=*/quad_cst.mutable_var_index()->mutable_data(),
134 /*lval=*/quad_cst.mutable_coefficient()->mutable_data(),
135 /*numqnz=*/quad_cst.qvar1_index_size(),
136 /*qrow=*/quad_cst.mutable_qvar1_index()->mutable_data(),
137 /*qcol=*/quad_cst.mutable_qvar2_index()->mutable_data(),
138 /*qval=*/quad_cst.mutable_qcoefficient()->mutable_data(),
139 /*sense=*/sense,
140 /*rhs=*/rhs,
141 /*QCname=*/name.c_str());
142 };
143
144 if (quad_cst.has_lower_bound() && quad_cst.lower_bound() > -kInfinity) {
145 const int grb_status =
146 addqconstr(gurobi_model, gen_cst.quadratic_constraint(),
147 GRB_GREATER_EQUAL, quad_cst.lower_bound(),
148 gen_cst.has_name() ? gen_cst.name() + "_lb" : "");
149 if (grb_status != GRB_OK) return grb_status;
150 }
151 if (quad_cst.has_upper_bound() && quad_cst.upper_bound() < kInfinity) {
152 const int grb_status =
153 addqconstr(gurobi_model, gen_cst.quadratic_constraint(), GRB_LESS_EQUAL,
154 quad_cst.upper_bound(),
155 gen_cst.has_name() ? gen_cst.name() + "_ub" : "");
156 if (grb_status != GRB_OK) return grb_status;
157 }
158
159 return GRB_OK;
160}
161
162int AddAndConstraint(const MPGeneralConstraintProto& gen_cst,
163 GRBmodel* gurobi_model, std::vector<int>* tmp_variables) {
164 CHECK(gurobi_model != nullptr);
165 CHECK(tmp_variables != nullptr);
166
167 auto and_cst = gen_cst.and_constraint();
168 return GRBaddgenconstrAnd(
169 gurobi_model,
170 /*name=*/gen_cst.name().c_str(),
171 /*resvar=*/and_cst.resultant_var_index(),
172 /*nvars=*/and_cst.var_index_size(),
173 /*vars=*/and_cst.mutable_var_index()->mutable_data());
174}
175
176int AddOrConstraint(const MPGeneralConstraintProto& gen_cst,
177 GRBmodel* gurobi_model, std::vector<int>* tmp_variables) {
178 CHECK(gurobi_model != nullptr);
179 CHECK(tmp_variables != nullptr);
180
181 auto or_cst = gen_cst.or_constraint();
182 return GRBaddgenconstrOr(gurobi_model,
183 /*name=*/gen_cst.name().c_str(),
184 /*resvar=*/or_cst.resultant_var_index(),
185 /*nvars=*/or_cst.var_index_size(),
186 /*vars=*/or_cst.mutable_var_index()->mutable_data());
187}
188
189int AddMinConstraint(const MPGeneralConstraintProto& gen_cst,
190 GRBmodel* gurobi_model, std::vector<int>* tmp_variables) {
191 CHECK(gurobi_model != nullptr);
192 CHECK(tmp_variables != nullptr);
193
194 auto min_cst = gen_cst.min_constraint();
195 return GRBaddgenconstrMin(
196 gurobi_model,
197 /*name=*/gen_cst.name().c_str(),
198 /*resvar=*/min_cst.resultant_var_index(),
199 /*nvars=*/min_cst.var_index_size(),
200 /*vars=*/min_cst.mutable_var_index()->mutable_data(),
201 /*constant=*/min_cst.has_constant()
202 ? min_cst.constant()
203 : std::numeric_limits<double>::infinity());
204}
205
206int AddMaxConstraint(const MPGeneralConstraintProto& gen_cst,
207 GRBmodel* gurobi_model, std::vector<int>* tmp_variables) {
208 CHECK(gurobi_model != nullptr);
209 CHECK(tmp_variables != nullptr);
210
211 auto max_cst = gen_cst.max_constraint();
212 return GRBaddgenconstrMax(
213 gurobi_model,
214 /*name=*/gen_cst.name().c_str(),
215 /*resvar=*/max_cst.resultant_var_index(),
216 /*nvars=*/max_cst.var_index_size(),
217 /*vars=*/max_cst.mutable_var_index()->mutable_data(),
218 /*constant=*/max_cst.has_constant()
219 ? max_cst.constant()
220 : -std::numeric_limits<double>::infinity());
221}
222} // namespace
223
224absl::Status SetSolverSpecificParameters(const std::string& parameters,
225 GRBenv* gurobi) {
226 if (parameters.empty()) return absl::OkStatus();
227 std::vector<std::string> error_messages;
228 for (absl::string_view line : absl::StrSplit(parameters, '\n')) {
229 // Comment tokens end at the next new-line, or the end of the string.
230 // The first character must be '#'
231 if (line[0] == '#') continue;
232 for (absl::string_view token :
233 absl::StrSplit(line, ',', absl::SkipWhitespace())) {
234 if (token.empty()) continue;
235 std::vector<std::string> key_value =
236 absl::StrSplit(token, absl::ByAnyChar(" ="), absl::SkipWhitespace());
237 // If one parameter fails, we keep processing the list of parameters.
238 if (key_value.size() != 2) {
239 const std::string current_message =
240 absl::StrCat("Cannot parse parameter '", token,
241 "'. Expected format is 'ParameterName value' or "
242 "'ParameterName=value'");
243 error_messages.push_back(current_message);
244 continue;
245 }
246 const int gurobi_code =
247 GRBsetparam(gurobi, key_value[0].c_str(), key_value[1].c_str());
248 if (gurobi_code != GRB_OK) {
249 const std::string current_message = absl::StrCat(
250 "Error setting parameter '", key_value[0], "' to value '",
251 key_value[1], "': ", GRBgeterrormsg(gurobi));
252 error_messages.push_back(current_message);
253 continue;
254 }
255 VLOG(2) << absl::StrCat("Set parameter '", key_value[0], "' to value '",
256 key_value[1]);
257 }
258 }
259
260 if (error_messages.empty()) return absl::OkStatus();
261 return absl::InvalidArgumentError(absl::StrJoin(error_messages, "\n"));
262}
263
264absl::StatusOr<MPSolutionResponse> GurobiSolveProto(
265 const MPModelRequest& request, GRBenv* gurobi_env) {
266 MPSolutionResponse response;
267 const absl::optional<LazyMutableCopy<MPModelProto>> optional_model =
269 if (!optional_model) return response;
270 const MPModelProto& model = optional_model->get();
271
272 // We set `gurobi_env` to point to a new environment if no existing one is
273 // provided. We must make sure that we free this environment when we exit this
274 // function.
275 bool gurobi_env_was_created = false;
276 auto gurobi_env_deleter = absl::MakeCleanup([&]() {
277 if (gurobi_env_was_created && gurobi_env != nullptr) {
278 GRBfreeenv(gurobi_env);
279 }
280 });
281 if (gurobi_env == nullptr) {
282 ASSIGN_OR_RETURN(gurobi_env, GetGurobiEnv());
283 gurobi_env_was_created = true;
284 }
285
286 GRBmodel* gurobi_model = nullptr;
287 auto gurobi_model_deleter = absl::MakeCleanup([&]() {
288 const int error_code = GRBfreemodel(gurobi_model);
289 LOG_IF(DFATAL, error_code != GRB_OK)
290 << "GRBfreemodel failed with error " << error_code << ": "
291 << GRBgeterrormsg(gurobi_env);
292 });
293
294// `gurobi_env` references ther GRBenv argument.
295#define RETURN_IF_GUROBI_ERROR(x) \
296 RETURN_IF_ERROR( \
297 GurobiCodeToUtilStatus(x, __FILE__, __LINE__, #x, gurobi_env));
298
299 RETURN_IF_GUROBI_ERROR(GRBnewmodel(gurobi_env, &gurobi_model,
300 model.name().c_str(),
301 /*numvars=*/0,
302 /*obj=*/nullptr,
303 /*lb=*/nullptr,
304 /*ub=*/nullptr,
305 /*vtype=*/nullptr,
306 /*varnames=*/nullptr));
307 GRBenv* const model_env = GRBgetenv(gurobi_model);
308
309 if (request.has_solver_specific_parameters()) {
310 const auto parameters_status = SetSolverSpecificParameters(
311 request.solver_specific_parameters(), model_env);
312 if (!parameters_status.ok()) {
313 response.set_status(MPSOLVER_MODEL_INVALID_SOLVER_PARAMETERS);
314 response.set_status_str(
315 std::string(parameters_status.message())); // NOLINT
316 return response;
317 }
318 }
319 if (request.solver_time_limit_seconds() > 0) {
321 request.solver_time_limit_seconds()));
322 }
325 request.enable_internal_solver_output()));
326
327 const int variable_size = model.variable_size();
328 bool has_integer_variables = false;
329 {
330 std::vector<double> obj_coeffs(variable_size, 0);
331 std::vector<double> lb(variable_size);
332 std::vector<double> ub(variable_size);
333 std::vector<char> ctype(variable_size);
334 std::vector<const char*> varnames(variable_size);
335 for (int v = 0; v < variable_size; ++v) {
336 const MPVariableProto& variable = model.variable(v);
337 obj_coeffs[v] = variable.objective_coefficient();
338 lb[v] = variable.lower_bound();
339 ub[v] = variable.upper_bound();
340 ctype[v] = variable.is_integer() && SolverTypeIsMip(request.solver_type())
343 if (variable.is_integer()) has_integer_variables = true;
344 if (!variable.name().empty()) varnames[v] = variable.name().c_str();
345 }
346
348 GRBaddvars(gurobi_model, variable_size, 0, nullptr, nullptr, nullptr,
349 /*obj=*/obj_coeffs.data(),
350 /*lb=*/lb.data(), /*ub=*/ub.data(), /*vtype=*/ctype.data(),
351 /*varnames=*/const_cast<char**>(varnames.data())));
352
353 // Set solution hints if any.
354 for (int i = 0; i < model.solution_hint().var_index_size(); ++i) {
356 gurobi_model, GRB_DBL_ATTR_START, model.solution_hint().var_index(i),
357 model.solution_hint().var_value(i)));
358 }
359 }
360
361 {
362 std::vector<int> ct_variables;
363 std::vector<double> ct_coefficients;
364 for (int c = 0; c < model.constraint_size(); ++c) {
365 const MPConstraintProto& constraint = model.constraint(c);
366 const int size = constraint.var_index_size();
367 ct_variables.resize(size, 0);
368 ct_coefficients.resize(size, 0);
369 for (int i = 0; i < size; ++i) {
370 ct_variables[i] = constraint.var_index(i);
371 ct_coefficients[i] = constraint.coefficient(i);
372 }
373 // Using GRBaddrangeconstr for constraints that don't require it adds
374 // a slack which is not always removed by presolve.
375 if (constraint.lower_bound() == constraint.upper_bound()) {
377 gurobi_model, /*numnz=*/size, /*cind=*/ct_variables.data(),
378 /*cval=*/ct_coefficients.data(),
379 /*sense=*/GRB_EQUAL, /*rhs=*/constraint.lower_bound(),
380 /*constrname=*/constraint.name().c_str()));
381 } else if (constraint.lower_bound() ==
382 -std::numeric_limits<double>::infinity()) {
384 gurobi_model, /*numnz=*/size, /*cind=*/ct_variables.data(),
385 /*cval=*/ct_coefficients.data(),
386 /*sense=*/GRB_LESS_EQUAL, /*rhs=*/constraint.upper_bound(),
387 /*constrname=*/constraint.name().c_str()));
388 } else if (constraint.upper_bound() ==
389 std::numeric_limits<double>::infinity()) {
391 gurobi_model, /*numnz=*/size, /*cind=*/ct_variables.data(),
392 /*cval=*/ct_coefficients.data(),
393 /*sense=*/GRB_GREATER_EQUAL, /*rhs=*/constraint.lower_bound(),
394 /*constrname=*/constraint.name().c_str()));
395 } else {
397 gurobi_model, /*numnz=*/size, /*cind=*/ct_variables.data(),
398 /*cval=*/ct_coefficients.data(),
399 /*lower=*/constraint.lower_bound(),
400 /*upper=*/constraint.upper_bound(),
401 /*constrname=*/constraint.name().c_str()));
402 }
403 }
404
405 for (const auto& gen_cst : model.general_constraint()) {
406 switch (gen_cst.general_constraint_case()) {
407 case MPGeneralConstraintProto::kIndicatorConstraint: {
408 RETURN_IF_GUROBI_ERROR(AddIndicatorConstraint(
409 gen_cst, gurobi_model, &ct_variables, &ct_coefficients));
410 break;
411 }
412 case MPGeneralConstraintProto::kSosConstraint: {
413 RETURN_IF_GUROBI_ERROR(AddSosConstraint(gen_cst.sos_constraint(),
414 gurobi_model, &ct_variables,
415 &ct_coefficients));
416 break;
417 }
418 case MPGeneralConstraintProto::kQuadraticConstraint: {
419 RETURN_IF_GUROBI_ERROR(AddQuadraticConstraint(gen_cst, gurobi_model));
420 break;
421 }
422 case MPGeneralConstraintProto::kAbsConstraint: {
424 gurobi_model,
425 /*name=*/gen_cst.name().c_str(),
426 /*resvar=*/gen_cst.abs_constraint().resultant_var_index(),
427 /*argvar=*/gen_cst.abs_constraint().var_index()));
428 break;
429 }
430 case MPGeneralConstraintProto::kAndConstraint: {
432 AddAndConstraint(gen_cst, gurobi_model, &ct_variables));
433 break;
434 }
435 case MPGeneralConstraintProto::kOrConstraint: {
437 AddOrConstraint(gen_cst, gurobi_model, &ct_variables));
438 break;
439 }
440 case MPGeneralConstraintProto::kMinConstraint: {
442 AddMinConstraint(gen_cst, gurobi_model, &ct_variables));
443 break;
444 }
445 case MPGeneralConstraintProto::kMaxConstraint: {
447 AddMaxConstraint(gen_cst, gurobi_model, &ct_variables));
448 break;
449 }
450 default:
451 return absl::UnimplementedError(
452 absl::StrFormat("General constraints of type %i not supported.",
453 gen_cst.general_constraint_case()));
454 }
455 }
456 }
457
459 model.maximize() ? -1 : 1));
461 model.objective_offset()));
462 if (model.has_quadratic_objective()) {
463 MPQuadraticObjective qobj = model.quadratic_objective();
464 if (qobj.coefficient_size() > 0) {
466 GRBaddqpterms(gurobi_model, /*numqnz=*/qobj.coefficient_size(),
467 /*qrow=*/qobj.mutable_qvar1_index()->mutable_data(),
468 /*qcol=*/qobj.mutable_qvar2_index()->mutable_data(),
469 /*qval=*/qobj.mutable_coefficient()->mutable_data()));
470 }
471 }
472
474
475 const absl::Time time_before = absl::Now();
476 UserTimer user_timer;
477 user_timer.Start();
478
479 RETURN_IF_GUROBI_ERROR(GRBoptimize(gurobi_model));
480
481 const absl::Duration solving_duration = absl::Now() - time_before;
482 user_timer.Stop();
483 VLOG(1) << "Finished solving in GurobiSolveProto(), walltime = "
484 << solving_duration << ", usertime = " << user_timer.GetDuration();
485 response.mutable_solve_info()->set_solve_wall_time_seconds(
486 absl::ToDoubleSeconds(solving_duration));
487 response.mutable_solve_info()->set_solve_user_time_seconds(
488 absl::ToDoubleSeconds(user_timer.GetDuration()));
489
490 int optimization_status = 0;
492 GRBgetintattr(gurobi_model, GRB_INT_ATTR_STATUS, &optimization_status));
493 int solution_count = 0;
495 GRBgetintattr(gurobi_model, GRB_INT_ATTR_SOLCOUNT, &solution_count));
496 switch (optimization_status) {
497 case GRB_OPTIMAL:
498 response.set_status(MPSOLVER_OPTIMAL);
499 break;
500 case GRB_INF_OR_UNBD:
501 DLOG(INFO) << "Gurobi solve returned GRB_INF_OR_UNBD, which we treat as "
502 "INFEASIBLE even though it may mean UNBOUNDED.";
503 response.set_status_str(
504 "The model may actually be unbounded: Gurobi returned "
505 "GRB_INF_OR_UNBD");
506 ABSL_FALLTHROUGH_INTENDED;
507 case GRB_INFEASIBLE:
508 response.set_status(MPSOLVER_INFEASIBLE);
509 break;
510 case GRB_UNBOUNDED:
511 response.set_status(MPSOLVER_UNBOUNDED);
512 break;
513 default: {
514 if (solution_count > 0) {
515 response.set_status(MPSOLVER_FEASIBLE);
516 } else {
517 response.set_status(MPSOLVER_NOT_SOLVED);
518 response.set_status_str(
519 absl::StrFormat("Gurobi status code %d", optimization_status));
520 }
521 break;
522 }
523 }
524
525 if (solution_count > 0 && (response.status() == MPSOLVER_FEASIBLE ||
526 response.status() == MPSOLVER_OPTIMAL)) {
527 double objective_value = 0;
530 response.set_objective_value(objective_value);
531 double best_objective_bound = 0;
532 const int error = GRBgetdblattr(gurobi_model, GRB_DBL_ATTR_OBJBOUND,
533 &best_objective_bound);
534 if (response.status() == MPSOLVER_OPTIMAL &&
536 // If the presolve deletes all variables, there's no best bound.
537 response.set_best_objective_bound(objective_value);
538 } else {
540 response.set_best_objective_bound(best_objective_bound);
541 }
542
543 response.mutable_variable_value()->Resize(variable_size, 0);
545 GRBgetdblattrarray(gurobi_model, GRB_DBL_ATTR_X, 0, variable_size,
546 response.mutable_variable_value()->mutable_data()));
547 // NOTE, GurobiSolveProto() is exposed to external clients via MPSolver API,
548 // which assumes the solution values of integer variables are rounded to
549 // integer values.
550 auto round_values_of_integer_variables_fn =
551 [&](google::protobuf::RepeatedField<double>* values) {
552 for (int v = 0; v < variable_size; ++v) {
553 if (model.variable(v).is_integer()) {
554 (*values)[v] = std::round((*values)[v]);
555 }
556 }
557 };
558 round_values_of_integer_variables_fn(response.mutable_variable_value());
559 if (!has_integer_variables && model.general_constraint_size() == 0) {
560 response.mutable_dual_value()->Resize(model.constraint_size(), 0);
562 gurobi_model, GRB_DBL_ATTR_PI, 0, model.constraint_size(),
563 response.mutable_dual_value()->mutable_data()));
564 }
565 const int additional_solutions = std::min(
566 solution_count, std::min(request.populate_additional_solutions_up_to(),
568 1);
569 for (int i = 1; i < additional_solutions; ++i) {
572 MPSolution* solution = response.add_additional_solutions();
573 solution->mutable_variable_value()->Resize(variable_size, 0);
574 double objective_value = 0;
577 solution->set_objective_value(objective_value);
579 gurobi_model, GRB_DBL_ATTR_XN, 0, variable_size,
580 solution->mutable_variable_value()->mutable_data()));
581 round_values_of_integer_variables_fn(solution->mutable_variable_value());
582 }
583 }
584#undef RETURN_IF_GUROBI_ERROR
585
586 return response;
587}
588
589} // namespace operations_research
int64_t max
Definition: alldiff_cst.cc:140
int64_t min
Definition: alldiff_cst.cc:139
#define LOG_IF(severity, condition)
Definition: base/logging.h:479
#define DLOG(severity)
Definition: base/logging.h:881
#define CHECK(condition)
Definition: base/logging.h:495
#define DCHECK_EQ(val1, val2)
Definition: base/logging.h:891
#define VLOG(verboselevel)
Definition: base/logging.h:984
#define ASSIGN_OR_RETURN(lhs, rexpr)
void Start()
Definition: timer.h:31
void Stop()
Definition: timer.h:39
absl::Duration GetDuration() const
Definition: timer.h:48
SatParameters parameters
SharedResponseManager * response
const std::string name
#define GRB_DBL_ATTR_START
Definition: environment.h:182
#define GRB_ERROR_DATA_NOT_AVAILABLE
Definition: environment.h:71
#define GRB_INT_ATTR_MODELSENSE
Definition: environment.h:170
struct _GRBenv GRBenv
Definition: environment.h:25
#define GRB_GREATER_EQUAL
Definition: environment.h:97
#define GRB_OPTIMAL
Definition: environment.h:457
#define GRB_INTEGER
Definition: environment.h:101
#define GRB_DBL_ATTR_PI
Definition: environment.h:236
#define GRB_DBL_ATTR_OBJVAL
Definition: environment.h:218
#define GRB_DBL_ATTR_XN
Definition: environment.h:231
#define GRB_CONTINUOUS
Definition: environment.h:99
#define GRB_SOS_TYPE1
Definition: environment.h:106
struct _GRBmodel GRBmodel
Definition: environment.h:24
#define GRB_DBL_ATTR_OBJCON
Definition: environment.h:171
#define GRB_INF_OR_UNBD
Definition: environment.h:459
#define GRB_DBL_ATTR_X
Definition: environment.h:230
#define GRB_INFEASIBLE
Definition: environment.h:458
#define GRB_EQUAL
Definition: environment.h:98
#define GRB_SOS_TYPE2
Definition: environment.h:107
#define GRB_UNBOUNDED
Definition: environment.h:460
#define GRB_INT_ATTR_STATUS
Definition: environment.h:217
#define GRB_LESS_EQUAL
Definition: environment.h:96
#define GRB_DBL_ATTR_POOLOBJVAL
Definition: environment.h:222
#define GRB_INT_PAR_SOLUTIONNUMBER
Definition: environment.h:526
#define GRB_INT_ATTR_SOLCOUNT
Definition: environment.h:224
#define GRB_INT_PAR_OUTPUTFLAG
Definition: environment.h:565
#define GRB_DBL_PAR_TIMELIMIT
Definition: environment.h:481
#define GRB_DBL_ATTR_OBJBOUND
Definition: environment.h:219
absl::Status status
Definition: g_gurobi.cc:35
Gurobi * gurobi
Definition: g_gurobi.cc:36
GRBmodel * model
#define RETURN_IF_GUROBI_ERROR(x)
A C++ wrapper that provides a simple and unified interface to several linear programming and mixed in...
const int INFO
Definition: log_severity.h:31
absl::Cleanup< absl::decay_t< Callback > > MakeCleanup(Callback &&callback)
Definition: cleanup.h:125
const double kInfinity
Definition: lp_types.h:84
Collection of objects used to extend the Constraint Solver library.
std::function< int(GRBmodel *model, const char *name, int resvar, int nvars, const int *vars, double constant)> GRBaddgenconstrMin
Definition: environment.cc:297
std::function< int(GRBmodel *model, int numnz, int *cind, double *cval, char sense, double rhs, const char *constrname)> GRBaddconstr
Definition: environment.cc:269
std::function< int(GRBmodel *model, const char *attrname, double *valueP)> GRBgetdblattr
Definition: environment.cc:95
std::function< int(GRBmodel *model, int numlnz, int *lind, double *lval, int numqnz, int *qrow, int *qcol, double *qval, char sense, double rhs, const char *QCname)> GRBaddqconstr
Definition: environment.cc:313
std::function< int(GRBenv *env, const char *paramname, const char *value)> GRBsetparam
Definition: environment.cc:375
std::function< int(GRBmodel *model, const char *attrname, int newvalue)> GRBsetintattr
Definition: environment.cc:57
bool SolverTypeIsMip(MPModelRequest::SolverType solver_type)
std::function< int(GRBenv *env, const char *paramname, int value)> GRBsetintparam
Definition: environment.cc:377
std::function< int(GRBmodel *model, const char *name, int resvar, int argvar)> GRBaddgenconstrAbs
Definition: environment.cc:299
std::function< int(GRBmodel *model)> GRBfreemodel
Definition: environment.cc:335
std::function< int(GRBmodel *model, int numqnz, int *qrow, int *qcol, double *qval)> GRBaddqpterms
Definition: environment.cc:318
std::function< const char *(GRBenv *env)> GRBgeterrormsg
Definition: environment.cc:424
absl::StatusOr< GRBenv * > GetGurobiEnv()
Definition: environment.cc:752
std::function< GRBenv *(GRBmodel *model)> GRBgetenv
Definition: environment.cc:417
std::function< int(GRBmodel *model, const char *name, int resvar, int nvars, const int *vars, double constant)> GRBaddgenconstrMax
Definition: environment.cc:294
std::function< int(GRBmodel *model, const char *attrname, int element, double newvalue)> GRBsetdblattrelement
Definition: environment.cc:103
std::function< int(GRBmodel *lp, const char *name, int binvar, int binval, int nvars, const int *vars, const double *vals, char sense, double rhs)> GRBaddgenconstrIndicator
Definition: environment.cc:309
std::function< int(GRBmodel *model, const char *attrname, int first, int len, double *values)> GRBgetdblattrarray
Definition: environment.cc:106
std::function< int(GRBmodel *model)> GRBupdatemodel
Definition: environment.cc:333
std::function< int(GRBmodel *model, const char *name, int resvar, int nvars, const int *vars)> GRBaddgenconstrAnd
Definition: environment.cc:302
absl::Status SetSolverSpecificParameters(const std::string &parameters, GRBenv *gurobi)
std::function< int(GRBmodel *model, int numnz, int *cind, double *cval, double lower, double upper, const char *constrname)> GRBaddrangeconstr
Definition: environment.cc:280
absl::optional< LazyMutableCopy< MPModelProto > > ExtractValidMPModelOrPopulateResponseStatus(const MPModelRequest &request, MPSolutionResponse *response)
If the model is valid and non-empty, returns it (possibly after extracting the model_delta).
absl::StatusOr< MPSolutionResponse > GurobiSolveProto(const MPModelRequest &request, GRBenv *gurobi_env)
std::function< int(GRBmodel *model, const char *name, int resvar, int nvars, const int *vars)> GRBaddgenconstrOr
Definition: environment.cc:305
std::function< int(GRBmodel *model)> GRBoptimize
Definition: environment.cc:207
std::function< int(GRBenv *env, GRBmodel **modelP, const char *Pname, int numvars, double *obj, double *lb, double *ub, char *vtype, char **varnames)> GRBnewmodel
Definition: environment.cc:242
std::function< void(GRBenv *env)> GRBfreeenv
Definition: environment.cc:423
std::function< int(GRBmodel *model, int numsos, int nummembers, int *types, int *beg, int *ind, double *weight)> GRBaddsos
Definition: environment.cc:291
std::function< int(GRBmodel *model, const char *attrname, double newvalue)> GRBsetdblattr
Definition: environment.cc:97
std::function< int(GRBmodel *model, int numvars, int numnz, int *vbeg, int *vind, double *vval, double *obj, double *lb, double *ub, char *vtype, char **varnames)> GRBaddvars
Definition: environment.cc:262
std::function< int(GRBmodel *model, const char *attrname, int *valueP)> GRBgetintattr
Definition: environment.cc:55
std::function< int(GRBenv *env, const char *paramname, double value)> GRBsetdblparam
Definition: environment.cc:379
double objective_value