Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
model_builder_helper.cc
Go to the documentation of this file.
1// Copyright 2010-2024 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 <cmath>
17#include <functional>
18#include <limits>
19#include <optional>
20#include <string>
21#include <utility>
22#include <vector>
23
24#include "absl/log/check.h"
25#include "absl/strings/match.h"
31#include "ortools/linear_solver/linear_solver.pb.h"
38#if defined(USE_SCIP)
40#endif // defined(USE_SCIP)
41#if defined(USE_HIGHS)
43#endif // defined(USE_HIGHS)
44#if defined(USE_PDLP)
46#endif // defined(USE_PDLP)
47#if defined(USE_LP_PARSER)
49#endif // defined(USE_LP_PARSER)
52
53namespace operations_research {
54
56 const ModelBuilderHelper& other_helper) {
57 model_ = other_helper.model();
58}
59
61 const MPModelExportOptions& options) {
63 .value_or("");
64}
65
67 const MPModelExportOptions& options) {
68 return operations_research::ExportModelAsLpFormat(model_, options)
69 .value_or("");
70}
71
72bool ModelBuilderHelper::WriteToMpsFile(const std::string& filename,
73 const MPModelExportOptions& options) {
74 return WriteModelToMpsFile(filename, model_, options).ok();
75}
76
77bool ModelBuilderHelper::ReadModelFromProtoFile(const std::string& filename) {
78 if (file::GetTextProto(filename, &model_, file::Defaults()).ok() ||
79 file::GetBinaryProto(filename, &model_, file::Defaults()).ok()) {
80 return true;
81 }
82 MPModelRequest request;
83 if (file::GetTextProto(filename, &request, file::Defaults()).ok() ||
84 file::GetBinaryProto(filename, &request, file::Defaults()).ok()) {
85 model_ = request.model();
86 return true;
87 }
88 return false;
89}
90
91bool ModelBuilderHelper::WriteModelToProtoFile(const std::string& filename) {
92 if (absl::EndsWith(filename, "txt")) {
93 return file::SetTextProto(filename, model_, file::Defaults()).ok();
94 } else {
95 return file::SetBinaryProto(filename, model_, file::Defaults()).ok();
96 }
97}
98
99// See comment in the header file why we need to wrap absl::Status code with
100// code having simpler APIs.
101bool ModelBuilderHelper::ImportFromMpsString(const std::string& mps_string) {
102 absl::StatusOr<MPModelProto> model_or =
104 if (!model_or.ok()) return false;
105 model_ = model_or.value();
106 return true;
107}
108
109bool ModelBuilderHelper::ImportFromMpsFile(const std::string& mps_file) {
110 absl::StatusOr<MPModelProto> model_or =
112 if (!model_or.ok()) return false;
113 model_ = model_or.value();
114 return true;
115}
116
117#if defined(USE_LP_PARSER)
118bool ModelBuilderHelper::ImportFromLpString(const std::string& lp_string) {
119 absl::StatusOr<MPModelProto> model_or = ModelProtoFromLpFormat(lp_string);
120 if (!model_or.ok()) return false;
121 model_ = model_or.value();
122 return true;
123}
124
125bool ModelBuilderHelper::ImportFromLpFile(const std::string& lp_file) {
126 std::string lp_data;
127 if (!file::GetContents(lp_file, &lp_data, file::Defaults()).ok()) {
128 return false;
129 }
130 absl::StatusOr<MPModelProto> model_or = ModelProtoFromLpFormat(lp_data);
131 if (!model_or.ok()) return false;
132 model_ = model_or.value();
133 return true;
134}
135#endif // #if defined(USE_LP_PARSER)
136
137const MPModelProto& ModelBuilderHelper::model() const { return model_; }
138
139MPModelProto* ModelBuilderHelper::mutable_model() { return &model_; }
140
142 const int index = model_.variable_size();
143 model_.add_variable();
144 return index;
145}
146
148 model_.mutable_variable(var_index)->set_lower_bound(lb);
149}
150
152 model_.mutable_variable(var_index)->set_upper_bound(ub);
153}
154
156 model_.mutable_variable(var_index)->set_is_integer(is_integer);
157}
158
160 double coeff) {
161 model_.mutable_variable(var_index)->set_objective_coefficient(coeff);
162}
163
164void ModelBuilderHelper::SetVarName(int var_index, const std::string& name) {
165 model_.mutable_variable(var_index)->set_name(name);
166}
167
169 return model_.variable(var_index).lower_bound();
170}
171
173 return model_.variable(var_index).upper_bound();
174}
175
177 return model_.variable(var_index).is_integer();
178}
179
181 return model_.variable(var_index).objective_coefficient();
182}
183
185 return model_.variable(var_index).name();
186}
187
189 const int index = model_.constraint_size();
190 model_.add_constraint();
191 return index;
192}
193
195 model_.mutable_constraint(ct_index)->set_lower_bound(lb);
196}
197
199 model_.mutable_constraint(ct_index)->set_upper_bound(ub);
200}
201
203 MPConstraintProto* ct_proto = model_.mutable_constraint(ct_index);
204 ct_proto->clear_var_index();
205 ct_proto->clear_coefficient();
206}
207
209 double coeff) {
210 if (coeff == 0.0) return;
211 MPConstraintProto* ct_proto = model_.mutable_constraint(ct_index);
212 ct_proto->add_var_index(var_index);
213 ct_proto->add_coefficient(coeff);
214}
215
217 double coeff) {
218 if (coeff == 0.0) return;
219 MPConstraintProto* ct_proto = model_.mutable_constraint(ct_index);
220 for (int i = 0; i < ct_proto->var_index_size(); ++i) {
221 if (ct_proto->var_index(i) == var_index) {
222 ct_proto->set_coefficient(i, coeff + ct_proto->coefficient(i));
223 return;
224 }
225 }
226 // If we reach this point, the variable does not exist in the constraint yet,
227 // so we add it to the constraint as a new term.
228 ct_proto->add_var_index(var_index);
229 ct_proto->add_coefficient(coeff);
230}
231
233 const std::string& name) {
234 model_.mutable_constraint(ct_index)->set_name(name);
235}
236
238 double coeff) {
239 MPConstraintProto* ct_proto = model_.mutable_constraint(ct_index);
240 for (int i = 0; i < ct_proto->var_index_size(); ++i) {
241 if (ct_proto->var_index(i) == var_index) {
242 ct_proto->set_coefficient(i, coeff);
243 return;
244 }
245 }
246 // If we reach this point, the variable does not exist in the constraint yet,
247 // so we add it to the constraint as a new term.
248 ct_proto->add_var_index(var_index);
249 ct_proto->add_coefficient(coeff);
250}
251
253 return model_.constraint(ct_index).lower_bound();
254}
255
257 return model_.constraint(ct_index).upper_bound();
258}
259
261 return model_.constraint(ct_index).name();
262}
263
265 const MPConstraintProto& ct_proto = model_.constraint(ct_index);
266 return {ct_proto.var_index().begin(), ct_proto.var_index().end()};
267}
268
270 int ct_index) const {
271 const MPConstraintProto& ct_proto = model_.constraint(ct_index);
272 return {ct_proto.coefficient().begin(), ct_proto.coefficient().end()};
273}
274
276 const int index = model_.general_constraint_size();
277 // Create the new general constraint, and force the type to indicator ct.
278 model_.add_general_constraint()->mutable_indicator_constraint();
279 return index;
280}
281
283 const MPGeneralConstraintProto& gen = model_.general_constraint(ct_index);
284 return gen.general_constraint_case() ==
285 MPGeneralConstraintProto::kIndicatorConstraint;
286}
287
289 double lb) {
291 MPGeneralConstraintProto* gen = model_.mutable_general_constraint(ct_index);
292 MPConstraintProto* ct_proto =
293 gen->mutable_indicator_constraint()->mutable_constraint();
294 ct_proto->set_lower_bound(lb);
295}
296
298 double ub) {
300 MPGeneralConstraintProto* gen = model_.mutable_general_constraint(ct_index);
301 MPConstraintProto* ct_proto =
302 gen->mutable_indicator_constraint()->mutable_constraint();
303 ct_proto->set_upper_bound(ub);
304}
305
307 MPConstraintProto* ct_proto = model_.mutable_general_constraint(ct_index)
308 ->mutable_indicator_constraint()
309 ->mutable_constraint();
310 ct_proto->clear_var_index();
311 ct_proto->clear_coefficient();
312}
313
315 double coeff) {
317 if (coeff == 0.0) return;
318 MPGeneralConstraintProto* gen = model_.mutable_general_constraint(ct_index);
319 MPConstraintProto* ct_proto =
320 gen->mutable_indicator_constraint()->mutable_constraint();
321 ct_proto->add_var_index(var_index);
322 ct_proto->add_coefficient(coeff);
323}
324
326 int var_index,
327 double coeff) {
329 if (coeff == 0.0) return;
330 MPGeneralConstraintProto* gen = model_.mutable_general_constraint(ct_index);
331 MPConstraintProto* ct_proto =
332 gen->mutable_indicator_constraint()->mutable_constraint();
333 for (int i = 0; i < ct_proto->var_index_size(); ++i) {
334 if (ct_proto->var_index(i) == var_index) {
335 ct_proto->set_coefficient(i, coeff + ct_proto->coefficient(i));
336 return;
337 }
338 }
339 // If we reach this point, the variable does not exist in the constraint yet,
340 // so we add it to the constraint as a new term.
341 ct_proto->add_var_index(var_index);
342 ct_proto->add_coefficient(coeff);
343}
344
346 const std::string& name) {
347 model_.mutable_general_constraint(ct_index)->set_name(name);
348}
349
351 int var_index,
352 double coeff) {
354 MPGeneralConstraintProto* gen = model_.mutable_general_constraint(ct_index);
355 MPConstraintProto* ct_proto =
356 gen->mutable_indicator_constraint()->mutable_constraint();
357 for (int i = 0; i < ct_proto->var_index_size(); ++i) {
358 if (ct_proto->var_index(i) == var_index) {
359 ct_proto->set_coefficient(i, coeff);
360 return;
361 }
362 }
363 // If we reach this point, the variable does not exist in the constraint yet,
364 // so we add it to the constraint as a new term.
365 ct_proto->add_var_index(var_index);
366 ct_proto->add_coefficient(coeff);
367}
368
370 int var_index) {
372 MPGeneralConstraintProto* gen = model_.mutable_general_constraint(ct_index);
373 gen->mutable_indicator_constraint()->set_var_index(var_index);
374}
375
377 bool positive) {
379 MPGeneralConstraintProto* gen = model_.mutable_general_constraint(ct_index);
380 gen->mutable_indicator_constraint()->set_var_value(positive);
381}
382
385 return model_.general_constraint(ct_index)
386 .indicator_constraint()
387 .constraint()
388 .lower_bound();
389}
390
393 return model_.general_constraint(ct_index)
394 .indicator_constraint()
395 .constraint()
396 .upper_bound();
397}
398
401 return model_.general_constraint(ct_index).name();
402}
403
405 int ct_index) const {
407 const MPConstraintProto& ct_proto =
408 model_.general_constraint(ct_index).indicator_constraint().constraint();
409 return {ct_proto.var_index().begin(), ct_proto.var_index().end()};
410}
411
413 int ct_index) const {
415 const MPConstraintProto& ct_proto =
416 model_.general_constraint(ct_index).indicator_constraint().constraint();
417 return {ct_proto.coefficient().begin(), ct_proto.coefficient().end()};
418}
419
422 return model_.general_constraint(ct_index).indicator_constraint().var_index();
423}
424
427 return model_.general_constraint(ct_index)
428 .indicator_constraint()
429 .var_value() != 0;
430}
431
432int ModelBuilderHelper::num_variables() const { return model_.variable_size(); }
433
435 return model_.constraint_size() + model_.general_constraint_size();
436}
437
438std::string ModelBuilderHelper::name() const { return model_.name(); }
439
440void ModelBuilderHelper::SetName(const std::string& name) {
441 model_.set_name(name);
442}
444 for (MPVariableProto& var : *model_.mutable_variable()) {
445 var.clear_objective_coefficient();
446 }
447}
448
449bool ModelBuilderHelper::maximize() const { return model_.maximize(); }
450
452 model_.set_maximize(maximize);
453}
454
456 return model_.objective_offset();
457}
458
460 model_.set_objective_offset(offset);
461}
462
463void ModelBuilderHelper::ClearHints() { model_.clear_solution_hint(); }
464
465void ModelBuilderHelper::AddHint(int var_index, double var_value) {
466 model_.mutable_solution_hint()->add_var_index(var_index);
467 model_.mutable_solution_hint()->add_var_value(var_value);
468}
469
470std::optional<MPSolutionResponse> ModelSolverHelper::SolveRequest(
471 const MPModelRequest& request) {
474 request.solver_type()))) {
475 return std::nullopt;
476 }
477 return SolveMPModel(request, &interrupter_);
478}
479
480namespace {
481SolveStatus MPSolverResponseStatusToSolveStatus(MPSolverResponseStatus s) {
482 switch (s) {
483 case MPSOLVER_OPTIMAL:
485 case MPSOLVER_FEASIBLE:
487 case MPSOLVER_INFEASIBLE:
489 case MPSOLVER_UNBOUNDED:
491 case MPSOLVER_ABNORMAL:
493 case MPSOLVER_NOT_SOLVED:
495 case MPSOLVER_MODEL_IS_VALID:
497 case MPSOLVER_CANCELLED_BY_USER:
499 case MPSOLVER_UNKNOWN_STATUS:
501 case MPSOLVER_MODEL_INVALID:
503 case MPSOLVER_MODEL_INVALID_SOLUTION_HINT:
505 case MPSOLVER_MODEL_INVALID_SOLVER_PARAMETERS:
507 case MPSOLVER_SOLVER_TYPE_UNAVAILABLE:
509 case MPSOLVER_INCOMPATIBLE_OPTIONS:
511 default:
513 }
514}
515} // namespace
516
517ModelSolverHelper::ModelSolverHelper(const std::string& solver_name) {
518 if (solver_name.empty()) return;
520 if (!MPSolver::ParseSolverType(solver_name, &parsed_type)) {
521 VLOG(1) << "Unsupported type " << solver_name;
522 } else {
523 solver_type_ = static_cast<MPModelRequest::SolverType>(parsed_type);
524 }
525}
526
528 if (!solver_type_.has_value()) return false;
529 if (solver_type_.value() == MPModelRequest::GLOP_LINEAR_PROGRAMMING) {
530 return true;
531 }
532#ifdef USE_PDLP
533 if (solver_type_.value() == MPModelRequest::PDLP_LINEAR_PROGRAMMING) {
534 return true;
535 }
536#endif // USE_PDLP
537 if (solver_type_.value() == MPModelRequest::SAT_INTEGER_PROGRAMMING) {
538 return true;
539 }
540#ifdef USE_SCIP
541 if (solver_type_.value() == MPModelRequest::SCIP_MIXED_INTEGER_PROGRAMMING) {
542 return true;
543 }
544#endif // USE_SCIP
545#ifdef USE_HIGHS
546 if (solver_type_.value() == MPModelRequest::HIGHS_LINEAR_PROGRAMMING ||
547 solver_type_.value() == MPModelRequest::HIGHS_MIXED_INTEGER_PROGRAMMING) {
548 return true;
549 }
550#endif // USE_HIGHS
551 if (solver_type_.value() ==
552 MPModelRequest::GUROBI_MIXED_INTEGER_PROGRAMMING ||
553 solver_type_.value() == MPModelRequest::GUROBI_LINEAR_PROGRAMMING) {
555 }
556 if (solver_type_.value() ==
557 MPModelRequest::XPRESS_MIXED_INTEGER_PROGRAMMING ||
558 solver_type_.value() == MPModelRequest::XPRESS_LINEAR_PROGRAMMING) {
560 }
561 return false;
562}
563
565 response_.reset();
566 if (!solver_type_.has_value()) {
567 response_->set_status(
568 MPSolverResponseStatus::MPSOLVER_SOLVER_TYPE_UNAVAILABLE);
569 return;
570 }
571
572 MPModelRequest request;
573 *request.mutable_model() = model.model();
574 request.set_solver_type(solver_type_.value());
575 request.set_enable_internal_solver_output(solver_output_);
576 if (time_limit_in_second_.has_value()) {
577 request.set_solver_time_limit_seconds(time_limit_in_second_.value());
578 }
579 if (!solver_specific_parameters_.empty()) {
580 request.set_solver_specific_parameters(solver_specific_parameters_);
581 }
582 switch (solver_type_.value()) {
583 case MPModelRequest::GLOP_LINEAR_PROGRAMMING: {
584 response_ =
585 GlopSolveProto(std::move(request), &interrupt_solve_, log_callback_);
586 break;
587 }
588 case MPModelRequest::SAT_INTEGER_PROGRAMMING: {
589 response_ = SatSolveProto(std::move(request), &interrupt_solve_,
590 log_callback_, nullptr);
591 break;
592 }
593#if defined(USE_SCIP)
594 case MPModelRequest::SCIP_MIXED_INTEGER_PROGRAMMING: {
595 // TODO(user): Enable log_callback support.
596 // TODO(user): Enable interrupt_solve.
597 const auto temp = ScipSolveProto(std::move(request));
598 if (temp.ok()) {
599 response_ = std::move(temp.value());
600 }
601 break;
602 }
603#endif // defined(USE_SCIP)
604#if defined(USE_PDLP)
605 case MPModelRequest::PDLP_LINEAR_PROGRAMMING: {
606 const auto temp = PdlpSolveProto(std::move(request));
607 if (temp.ok()) {
608 response_ = std::move(temp.value());
609 }
610 break;
611 }
612#endif // defined(USE_PDLP)
613 case MPModelRequest::
614 GUROBI_LINEAR_PROGRAMMING: // ABSL_FALLTHROUGH_INTENDED
615 case MPModelRequest::GUROBI_MIXED_INTEGER_PROGRAMMING: {
616 const auto temp = GurobiSolveProto(std::move(request));
617 if (temp.ok()) {
618 response_ = std::move(temp.value());
619 }
620 break;
621 }
622#if defined(USE_HIGHS)
623 case MPModelRequest::HIGHS_LINEAR_PROGRAMMING: // ABSL_FALLTHROUGH_INTENDED
624 case MPModelRequest::HIGHS_MIXED_INTEGER_PROGRAMMING: {
625 // TODO(user): Enable log_callback support.
626 // TODO(user): Enable interrupt_solve.
627 const auto temp = HighsSolveProto(std::move(request));
628 if (temp.ok()) {
629 response_ = std::move(temp.value());
630 }
631 break;
632 }
633#endif // defined(USE_HIGHS)
634 case MPModelRequest::
635 XPRESS_LINEAR_PROGRAMMING: // ABSL_FALLTHROUGH_INTENDED
636 case MPModelRequest::XPRESS_MIXED_INTEGER_PROGRAMMING: {
637 response_ = XPressSolveProto(request);
638 break;
639 }
640 default: {
641 response_->set_status(
642 MPSolverResponseStatus::MPSOLVER_SOLVER_TYPE_UNAVAILABLE);
643 }
644 }
645 if (response_->status() == MPSOLVER_OPTIMAL ||
646 response_->status() == MPSOLVER_FEASIBLE) {
647 model_of_last_solve_ = &model.model();
648 activities_.assign(model.num_constraints(),
649 std::numeric_limits<double>::quiet_NaN());
650 } else {
651 activities_.clear();
652 }
653}
654
656 std::function<void(const std::string&)> log_callback) {
657 log_callback_ = std::move(log_callback);
658}
659
661 MbLogCallback* log_callback) {
662 log_callback_ = [log_callback](const std::string& message) {
663 log_callback->NewMessage(message);
664 };
665}
666
667void ModelSolverHelper::ClearLogCallback() { log_callback_ = nullptr; }
668
670 interrupter_.Interrupt();
671 interrupt_solve_ = true;
672 return true;
673}
674
675bool ModelSolverHelper::has_response() const { return response_.has_value(); }
676
678 return response_.has_value() &&
679 (response_.value().status() ==
680 MPSolverResponseStatus::MPSOLVER_OPTIMAL ||
681 response_.value().status() ==
682 MPSolverResponseStatus::MPSOLVER_FEASIBLE);
683}
684
685const MPSolutionResponse& ModelSolverHelper::response() const {
686 return response_.value();
687}
688
690 if (!response_.has_value()) {
692 }
693 return MPSolverResponseStatusToSolveStatus(response_.value().status());
694}
695
697 if (!has_response()) return 0.0;
698 return response_.value().objective_value();
699}
700
702 if (!has_response()) return 0.0;
703 return response_.value().best_objective_bound();
704}
705
707 if (!has_response()) return 0.0;
708 if (var_index >= response_.value().variable_value_size()) return 0.0;
709 return response_.value().variable_value(var_index);
710}
711
713 if (!has_response()) return 0.0;
714 if (var_index >= response_.value().reduced_cost_size()) return 0.0;
715 return response_.value().reduced_cost(var_index);
716}
717
719 if (!has_response()) return 0.0;
720 if (ct_index >= response_.value().dual_value_size()) return 0.0;
721 return response_.value().dual_value(ct_index);
722}
723
725 if (!has_response() || ct_index >= activities_.size() ||
726 !model_of_last_solve_.has_value()) {
727 return 0.0;
728 }
729
730 if (std::isnan(activities_[ct_index])) {
731 const MPConstraintProto& ct_proto =
732 model_of_last_solve_.value()->constraint(ct_index);
733 double result = 0.0;
734 for (int i = 0; i < ct_proto.var_index_size(); ++i) {
735 result += response_->variable_value(ct_proto.var_index(i)) *
736 ct_proto.coefficient(i);
737 }
738 activities_[ct_index] = result;
739 }
740 return activities_[ct_index];
741}
742
744 if (!has_response()) return "";
745 return response_.value().status_str();
746}
747
749 if (!response_.has_value()) return 0.0;
750 if (!response_.value().has_solve_info()) return 0.0;
751 return response_.value().solve_info().solve_wall_time_seconds();
752}
753
755 if (!response_.has_value()) return 0.0;
756 if (!response_.value().has_solve_info()) return 0.0;
757 return response_.value().solve_info().solve_user_time_seconds();
758}
759
761 time_limit_in_second_ = limit;
762}
763
765 const std::string& solver_specific_parameters) {
766 solver_specific_parameters_ = solver_specific_parameters;
767}
768
769void ModelSolverHelper::EnableOutput(bool enabled) { solver_output_ = enabled; }
770
771} // namespace operations_research
static bool SupportsProblemType(OptimizationProblemType problem_type)
static
static bool ParseSolverType(absl::string_view solver_id, OptimizationProblemType *type)
static
Simple director class for C#.
virtual void NewMessage(const std::string &message)=0
void SetEnforcedConstraintLowerBound(int ct_index, double lb)
std::string ExportToLpString(const operations_research::MPModelExportOptions &options=MPModelExportOptions())
bool ReadModelFromProtoFile(const std::string &filename)
void SetConstraintCoefficient(int ct_index, int var_index, double coeff)
void SafeAddEnforcedConstraintTerm(int ct_index, int var_index, double coeff)
void SetConstraintUpperBound(int ct_index, double ub)
void SetConstraintName(int ct_index, const std::string &name)
void SafeAddConstraintTerm(int ct_index, int var_index, double coeff)
void AddHint(int var_index, double var_value)
std::string VarName(int var_index) const
void SetVarObjectiveCoefficient(int var_index, double coeff)
void SetVarName(int var_index, const std::string &name)
int AddVar()
Direct low level model building API.
bool ImportFromMpsFile(const std::string &mps_file)
void SetEnforcedConstraintUpperBound(int ct_index, double ub)
void SetEnforcedConstraintName(int ct_index, const std::string &name)
double VarObjectiveCoefficient(int var_index) const
double EnforcedConstraintLowerBound(int ct_index) const
void AddConstraintTerm(int ct_index, int var_index, double coeff)
void SetEnforcedIndicatorVariableIndex(int ct_index, int var_index)
std::vector< double > ConstraintCoefficients(int ct_index) const
void SetConstraintLowerBound(int ct_index, double lb)
void SetEnforcedConstraintCoefficient(int ct_index, int var_index, double coeff)
bool ImportFromMpsString(const std::string &mps_string)
void AddEnforcedConstraintTerm(int ct_index, int var_index, double coeff)
bool WriteToMpsFile(const std::string &filename, const operations_research::MPModelExportOptions &options=MPModelExportOptions())
std::string ConstraintName(int ct_index) const
std::vector< double > EnforcedConstraintCoefficients(int ct_index) const
void SetEnforcedIndicatorValue(int ct_index, bool positive)
void SetVarIntegrality(int var_index, bool is_integer)
std::string EnforcedConstraintName(int ct_index) const
std::vector< int > EnforcedConstraintVarIndices(int ct_index) const
void SetVarUpperBound(int var_index, double ub)
std::string ExportToMpsString(const operations_research::MPModelExportOptions &options=MPModelExportOptions())
double EnforcedConstraintUpperBound(int ct_index) const
void SetVarLowerBound(int var_index, double lb)
bool WriteModelToProtoFile(const std::string &filename)
std::vector< int > ConstraintVarIndices(int ct_index) const
void OverwriteModel(const ModelBuilderHelper &other_helper)
void Solve(const ModelBuilderHelper &model)
void SetSolverSpecificParameters(const std::string &solver_specific_parameters)
double objective_value() const
If not defined, or no solution, they will silently return 0.
std::optional< MPSolutionResponse > SolveRequest(const MPModelRequest &request)
Only used by the CVXPY interface. Does not store the response internally.
void SetLogCallback(std::function< void(const std::string &)> log_callback)
const MPSolutionResponse & response() const
void SetLogCallbackFromDirectorClass(MbLogCallback *log_callback)
ModelSolverHelper(const std::string &solver_name)
void SetTimeLimitInSeconds(double limit)
Solve parameters.
const std::string name
A name for logging purposes.
IntVar * var
GRBmodel * model
int ct_index
int index
absl::Status SetTextProto(absl::string_view filename, const google::protobuf::Message &proto, Options options)
Definition file.cc:337
absl::StatusOr< std::string > GetContents(absl::string_view path, Options options)
Definition file.cc:191
absl::Status SetBinaryProto(absl::string_view filename, const google::protobuf::Message &proto, Options options)
Definition file.cc:360
Options Defaults()
Definition file.h:109
absl::Status GetTextProto(absl::string_view filename, google::protobuf::Message *proto, Options options)
Definition file.cc:327
absl::Status GetBinaryProto(const absl::string_view filename, google::protobuf::Message *proto, Options options)
Definition file.cc:348
absl::StatusOr< MPModelProto > MpsFileToMPModelProto(absl::string_view mps_file)
Parses an MPS model from a file.
absl::StatusOr< MPModelProto > MpsDataToMPModelProto(absl::string_view mps_data)
Parses an MPS model from a string.
In SWIG mode, we don't want anything besides these top-level includes.
MPSolutionResponse SatSolveProto(LazyMutableCopy< MPModelRequest > request, std::atomic< bool > *interrupt_solve, std::function< void(const std::string &)> logging_callback, std::function< void(const MPSolution &)> solution_callback)
absl::Status WriteModelToMpsFile(absl::string_view filename, const MPModelProto &model, const MPModelExportOptions &options)
MPSolutionResponse SolveMPModel(LazyMutableCopy< MPModelRequest > request, const SolveInterrupter *interrupter)
absl::StatusOr< MPSolutionResponse > PdlpSolveProto(LazyMutableCopy< MPModelRequest > request, const bool relax_integer_variables, const std::atomic< bool > *interrupt_solve)
absl::StatusOr< std::string > ExportModelAsLpFormat(const MPModelProto &model, const MPModelExportOptions &options)
bool GurobiIsCorrectlyInstalled()
absl::StatusOr< MPSolutionResponse > ScipSolveProto(LazyMutableCopy< MPModelRequest > request)
MPSolutionResponse GlopSolveProto(LazyMutableCopy< MPModelRequest > request, std::atomic< bool > *interrupt_solve, std::function< void(const std::string &)> logging_callback)
bool XpressIsCorrectlyInstalled()
absl::StatusOr< MPSolutionResponse > GurobiSolveProto(LazyMutableCopy< MPModelRequest > request, GRBenv *gurobi_env)
absl::StatusOr< MPSolutionResponse > HighsSolveProto(LazyMutableCopy< MPModelRequest > request)
Solve the input MIP model with the HIGHS solver.
absl::StatusOr< std::string > ExportModelAsMpsFormat(const MPModelProto &model, const MPModelExportOptions &options)
MPSolutionResponse XPressSolveProto(LazyMutableCopy< MPModelRequest > request)
Solves the input request.
int var_index
Definition search.cc:3268
std::string message
Definition trace.cc:397