25 #include "ortools/linear_solver/linear_solver.pb.h"
31 #if defined(USE_LP_PARSER)
51 if (absl::EndsWith(filename,
"txt")) {
61 absl::StatusOr<MPModelProto> model_or =
63 if (!model_or.ok())
return false;
64 model_ = model_or.value();
69 absl::StatusOr<MPModelProto> model_or =
71 if (!model_or.ok())
return false;
72 model_ = model_or.value();
76 #if defined(USE_LP_PARSER)
77 bool ModelBuilderHelper::ImportFromLpString(
const std::string& lp_string) {
78 absl::StatusOr<MPModelProto> model_or = ModelProtoFromLpFormat(lp_string);
79 if (!model_or.ok())
return false;
80 model_ = model_or.value();
84 bool ModelBuilderHelper::ImportFromLpFile(
const std::string& lp_file) {
89 absl::StatusOr<MPModelProto> model_or = ModelProtoFromLpFormat(lp_data);
90 if (!model_or.ok())
return false;
91 model_ = model_or.value();
101 const int index = model_.variable_size();
102 model_.add_variable();
107 model_.mutable_variable(var_index)->set_lower_bound(lb);
111 model_.mutable_variable(var_index)->set_upper_bound(ub);
115 model_.mutable_variable(var_index)->set_is_integer(is_integer);
120 model_.mutable_variable(var_index)->set_objective_coefficient(coeff);
124 model_.mutable_variable(var_index)->set_name(
name);
128 const int index = model_.constraint_size();
129 model_.add_constraint();
134 model_.mutable_constraint(ct_index)->set_lower_bound(lb);
138 model_.mutable_constraint(ct_index)->set_upper_bound(ub);
143 MPConstraintProto* ct_proto = model_.mutable_constraint(ct_index);
144 ct_proto->add_var_index(var_index);
145 ct_proto->add_coefficient(coeff);
149 const std::string&
name) {
150 model_.mutable_constraint(ct_index)->set_name(
name);
156 return model_.variable(var_index).lower_bound();
160 return model_.variable(var_index).upper_bound();
164 return model_.variable(var_index).is_integer();
168 return model_.variable(var_index).objective_coefficient();
172 return model_.variable(var_index).name();
176 return model_.constraint_size();
180 return model_.constraint(ct_index).lower_bound();
184 return model_.constraint(ct_index).upper_bound();
188 return model_.constraint(ct_index).name();
192 const MPConstraintProto& ct_proto = model_.constraint(ct_index);
193 return {ct_proto.var_index().begin(), ct_proto.var_index().end()};
197 int ct_index)
const {
198 const MPConstraintProto& ct_proto = model_.constraint(ct_index);
199 return {ct_proto.coefficient().begin(), ct_proto.coefficient().end()};
205 model_.set_name(
name);
208 for (MPVariableProto&
var : *model_.mutable_variable()) {
209 var.clear_objective_coefficient();
220 return model_.objective_offset();
224 model_.set_objective_offset(offset);
228 const MPModelRequest& request) {
229 MPSolutionResponse temp;
235 SolveStatus MPSolverResponseStatusToSolveStatus(MPSolverResponseStatus s) {
237 case MPSOLVER_OPTIMAL:
239 case MPSOLVER_FEASIBLE:
241 case MPSOLVER_INFEASIBLE:
243 case MPSOLVER_UNBOUNDED:
245 case MPSOLVER_ABNORMAL:
247 case MPSOLVER_NOT_SOLVED:
249 case MPSOLVER_MODEL_IS_VALID:
251 case MPSOLVER_CANCELLED_BY_USER:
253 case MPSOLVER_UNKNOWN_STATUS:
255 case MPSOLVER_MODEL_INVALID:
257 case MPSOLVER_MODEL_INVALID_SOLUTION_HINT:
259 case MPSOLVER_MODEL_INVALID_SOLVER_PARAMETERS:
261 case MPSOLVER_SOLVER_TYPE_UNAVAILABLE:
263 case MPSOLVER_INCOMPATIBLE_OPTIONS:
272 if (solver_name.empty())
return;
275 VLOG(1) <<
"Unsupported type " << solver_name;
282 return solver_type_.has_value();
287 if (!solver_type_.has_value()) {
288 response_->set_status(
289 MPSolverResponseStatus::MPSOLVER_SOLVER_TYPE_UNAVAILABLE);
293 MPModelRequest request;
294 *request.mutable_model() =
model.model();
295 request.set_solver_type(solver_type_.value());
296 request.set_enable_internal_solver_output(solver_output_);
297 if (time_limit_in_second_.has_value()) {
298 request.set_solver_time_limit_seconds(time_limit_in_second_.value());
300 if (!solver_specific_parameters_.empty()) {
301 request.set_solver_specific_parameters(solver_specific_parameters_);
303 switch (solver_type_.value()) {
304 case MPModelRequest::GLOP_LINEAR_PROGRAMMING: {
306 MPSolutionResponse temp;
308 response_ = std::move(temp);
311 case MPModelRequest::SAT_INTEGER_PROGRAMMING: {
313 SatSolveProto(request, &interrupt_solve_, log_callback_,
nullptr);
315 response_ = std::move(temp.value());
319 #if defined(USE_SCIP)
320 case MPModelRequest::SCIP_MIXED_INTEGER_PROGRAMMING: {
325 response_ = std::move(temp.value());
330 #if defined(USE_HIGHS)
331 case MPModelRequest::HIGHS_MIXED_INTEGER_PROGRAMMING:
332 case MPModelRequest::HIGHS_LINEAR_PROGRAMMING: {
335 response_ = std::move(temp.value());
341 response_->set_status(
342 MPSolverResponseStatus::MPSOLVER_SOLVER_TYPE_UNAVAILABLE);
345 if (response_->status() == MPSOLVER_OPTIMAL ||
346 response_->status() == MPSOLVER_FEASIBLE) {
347 model_of_last_solve_ = &
model.model();
348 activities_.assign(
model.num_constraints(),
349 std::numeric_limits<double>::quiet_NaN());
356 std::function<
void(
const std::string&)> log_callback) {
357 log_callback_ = std::move(log_callback);
362 log_callback_ = [log_callback](
const std::string&
message) {
370 interrupt_solve_ =
true;
377 return response_.has_value() &&
378 (response_.value().status() ==
379 MPSolverResponseStatus::MPSOLVER_OPTIMAL ||
380 response_.value().status() ==
381 MPSolverResponseStatus::MPSOLVER_FEASIBLE);
385 return response_.value();
389 if (!response_.has_value()) {
392 return MPSolverResponseStatusToSolveStatus(response_.value().status());
397 return response_.value().objective_value();
402 return response_.value().best_objective_bound();
407 if (var_index >= response_.value().variable_value_size())
return 0.0;
408 return response_.value().variable_value(var_index);
413 if (var_index >= response_.value().reduced_cost_size())
return 0.0;
414 return response_.value().reduced_cost(var_index);
419 if (ct_index >= response_.value().dual_value_size())
return 0.0;
420 return response_.value().dual_value(ct_index);
424 if (!
has_response() || ct_index >= activities_.size() ||
425 !model_of_last_solve_.has_value()) {
429 if (std::isnan(activities_[ct_index])) {
430 const MPConstraintProto& ct_proto =
431 model_of_last_solve_.value()->constraint(ct_index);
433 for (
int i = 0; i < ct_proto.var_index_size(); ++i) {
434 result += response_->variable_value(ct_proto.var_index(i)) *
435 ct_proto.coefficient(i);
437 activities_[ct_index] = result;
439 return activities_[ct_index];
444 return response_.value().status_str();
448 if (!response_.has_value())
return 0.0;
449 if (!response_.value().has_solve_info())
return 0.0;
450 return response_.value().solve_info().solve_wall_time_seconds();
454 if (!response_.has_value())
return 0.0;
455 if (!response_.value().has_solve_info())
return 0.0;
456 return response_.value().solve_info().solve_user_time_seconds();
460 time_limit_in_second_ = limit;
464 const std::string& solver_specific_parameters) {
465 solver_specific_parameters_ = solver_specific_parameters;
virtual void NewMessage(const std::string &message)=0
OptimizationProblemType
The type of problems (LP or MIP) that will be solved and the underlying solver (GLOP,...
static bool ParseSolverType(absl::string_view solver_id, OptimizationProblemType *type)
Parses the name of the solver.
static void SolveWithProto(const MPModelRequest &model_request, MPSolutionResponse *response, std::atomic< bool > *interrupt=nullptr)
Solves the model encoded by a MPModelRequest protocol buffer and fills the solution encoded as a MPSo...
void SetMaximize(bool maximize)
bool WriteModelToFile(const std::string &filename)
double VarLowerBound(int var_index) const
void SetObjectiveOffset(double offset)
bool VarIsIntegral(int var_index) const
void SetVarUpperBound(int var_index, double ub)
int num_constraints() const
void SetConstraintUpperBound(int ct_index, double ub)
double VarObjectiveCoefficient(int var_index) const
void SetVarObjectiveCoefficient(int var_index, double coeff)
void AddConstraintTerm(int ct_index, int var_index, double coeff)
double ConstraintUpperBound(int ct_index) const
std::string VarName(int var_index) const
std::string ExportToMpsString(const operations_research::MPModelExportOptions &options=MPModelExportOptions())
std::string ConstraintName(int ct_index) const
void SetVarName(int var_index, const std::string &name)
double ObjectiveOffset() const
int num_variables() const
void SetConstraintName(int ct_index, const std::string &name)
std::vector< double > ConstraintCoefficients(int ct_index) const
const MPModelProto & model() const
void SetName(const std::string &name)
int AddLinearConstraint()
MPModelProto * mutable_model()
double VarUpperBound(int var_index) const
bool ImportFromMpsFile(const std::string &mps_file)
std::vector< int > ConstraintVarIndices(int ct_index) const
double ConstraintLowerBound(int ct_index) const
std::string ExportToLpString(const operations_research::MPModelExportOptions &options=MPModelExportOptions())
void SetConstraintLowerBound(int ct_index, double lb)
void SetVarLowerBound(int var_index, double lb)
void SetVarIntegrality(int var_index, bool is_integer)
bool ImportFromMpsString(const std::string &mps_string)
void SetTimeLimitInSeconds(double limit)
double best_objective_bound() const
double reduced_cost(int var_index) const
void EnableOutput(bool enabled)
double activity(int ct_index)
double variable_value(int var_index) const
void SetSolverSpecificParameters(const std::string &solver_specific_parameters)
bool has_response() const
double dual_value(int ct_index) const
bool has_solution() const
double objective_value() const
void SetLogCallbackFromDirectorClass(LogCallback *log_callback)
std::string status_string() const
void SetLogCallback(std::function< void(const std::string &)> log_callback)
bool SolverIsSupported() const
void Solve(const ModelBuilderHelper &model)
const MPSolutionResponse & response() const
std::optional< MPSolutionResponse > SolveRequest(const MPModelRequest &request)
ModelSolverHelper(const std::string &solver_name)
SolveStatus status() const
A C++ wrapper that provides a simple and unified interface to several linear programming and mixed in...
absl::Status GetContents(const absl::string_view &filename, std::string *output, int flags)
absl::Status SetTextProto(const absl::string_view &filename, const google::protobuf::Message &proto, int flags)
absl::Status SetBinaryProto(const absl::string_view &filename, const google::protobuf::Message &proto, int flags)
absl::StatusOr< MPModelProto > MpsDataToMPModelProto(const std::string &mps_data)
absl::StatusOr< MPModelProto > MpsFileToMPModelProto(const std::string &mps_file)
Collection of objects used to extend the Constraint Solver library.
absl::StatusOr< MPSolutionResponse > ScipSolveProto(const MPModelRequest &request)
absl::StatusOr< std::string > ExportModelAsMpsFormat(const MPModelProto &model, const MPModelExportOptions &options)
Outputs the current model (variables, constraints, objective) as a string encoded in MPS file format,...
@ SOLVER_TYPE_UNAVAILABLE
@ INVALID_SOLVER_PARAMETERS
absl::StatusOr< MPSolutionResponse > SatSolveProto(MPModelRequest request, std::atomic< bool > *interrupt_solve, std::function< void(const std::string &)> logging_callback, std::function< void(const MPSolution &)> solution_callback)
absl::StatusOr< MPSolutionResponse > HighsSolveProto(MPModelRequest request)
absl::StatusOr< std::string > ExportModelAsLpFormat(const MPModelProto &model, const MPModelExportOptions &options)
Outputs the current model (variables, constraints, objective) as a string encoded in the so-called "C...
#define VLOG(verboselevel)