27 #include "absl/container/flat_hash_map.h" 28 #include "absl/container/flat_hash_set.h" 29 #include "absl/memory/memory.h" 30 #include "absl/status/status.h" 31 #include "absl/status/statusor.h" 32 #include "absl/strings/str_cat.h" 33 #include "absl/strings/str_format.h" 34 #include "absl/strings/string_view.h" 35 #include "absl/types/span.h" 43 #include "scip/cons_linear.h" 44 #include "scip/cons_quadratic.h" 45 #include "scip/scip.h" 46 #include "scip/scip_general.h" 47 #include "scip/scip_param.h" 48 #include "scip/scip_prob.h" 49 #include "scip/scip_solvingstats.h" 50 #include "scip/scipdefplugins.h" 51 #include "scip/type_cons.h" 52 #include "scip/type_scip.h" 53 #include "scip/type_var.h" 57 #define RETURN_ERROR_UNLESS(x) \ 59 return util::StatusBuilder(absl::InvalidArgumentError(absl::StrFormat( \ 60 "Condition violated at %s:%d: %s", __FILE__, __LINE__, #x))) 64 constexpr absl::string_view kLinearConstraintHandlerName =
"linear";
66 SCIP_VARTYPE ConvertVarType(
const GScipVarType var_type) {
69 return SCIP_VARTYPE_CONTINUOUS;
71 return SCIP_VARTYPE_IMPLINT;
73 return SCIP_VARTYPE_INTEGER;
77 GScipVarType ConvertVarType(
const SCIP_VARTYPE var_type) {
79 case SCIP_VARTYPE_CONTINUOUS:
81 case SCIP_VARTYPE_IMPLINT:
83 case SCIP_VARTYPE_INTEGER:
84 case SCIP_VARTYPE_BINARY:
90 switch (scip_status) {
91 case SCIP_STATUS_UNKNOWN:
93 case SCIP_STATUS_USERINTERRUPT:
95 case SCIP_STATUS_BESTSOLLIMIT:
97 case SCIP_STATUS_MEMLIMIT:
99 case SCIP_STATUS_NODELIMIT:
101 case SCIP_STATUS_RESTARTLIMIT:
103 case SCIP_STATUS_SOLLIMIT:
105 case SCIP_STATUS_STALLNODELIMIT:
107 case SCIP_STATUS_TIMELIMIT:
109 case SCIP_STATUS_TOTALNODELIMIT:
111 case SCIP_STATUS_OPTIMAL:
113 case SCIP_STATUS_GAPLIMIT:
115 case SCIP_STATUS_INFEASIBLE:
117 case SCIP_STATUS_UNBOUNDED:
119 case SCIP_STATUS_INFORUNBD:
121 case SCIP_STATUS_TERMINATE:
124 LOG(
FATAL) <<
"Unrecognized scip status: " << scip_status;
128 SCIP_PARAMEMPHASIS ConvertEmphasis(
130 switch (gscip_emphasis) {
132 return SCIP_PARAMEMPHASIS_DEFAULT;
134 return SCIP_PARAMEMPHASIS_CPSOLVER;
136 return SCIP_PARAMEMPHASIS_EASYCIP;
138 return SCIP_PARAMEMPHASIS_FEASIBILITY;
140 return SCIP_PARAMEMPHASIS_HARDLP;
142 return SCIP_PARAMEMPHASIS_OPTIMALITY;
144 return SCIP_PARAMEMPHASIS_COUNTER;
146 return SCIP_PARAMEMPHASIS_PHASEFEAS;
148 return SCIP_PARAMEMPHASIS_PHASEIMPROVE;
150 return SCIP_PARAMEMPHASIS_PHASEPROOF;
152 LOG(
FATAL) <<
"Unrecognized gscip_emphasis: " 157 SCIP_PARAMSETTING ConvertMetaParamValue(
159 switch (gscip_meta_param_value) {
161 return SCIP_PARAMSETTING_DEFAULT;
163 return SCIP_PARAMSETTING_AGGRESSIVE;
165 return SCIP_PARAMSETTING_FAST;
167 return SCIP_PARAMSETTING_OFF;
169 LOG(
FATAL) <<
"Unrecognized gscip_meta_param_value: " 183 return constraint_options;
186 absl::Status GScip::SetParams(
const GScipParameters& params,
187 const std::string& legacy_params) {
188 if (params.has_silence_output()) {
189 SCIPsetMessagehdlrQuiet(scip_, params.silence_output());
191 if (!params.search_logs_filename().empty()) {
192 SCIPsetMessagehdlrLogfile(scip_, params.search_logs_filename().c_str());
195 const SCIP_Bool set_param_quiet =
196 static_cast<SCIP_Bool>(!params.silence_output());
199 scip_, ConvertEmphasis(params.emphasis()), set_param_quiet));
200 if (params.has_heuristics()) {
202 scip_, ConvertMetaParamValue(params.heuristics()), set_param_quiet));
204 if (params.has_presolve()) {
206 scip_, ConvertMetaParamValue(params.presolve()), set_param_quiet));
208 if (params.has_separating()) {
210 scip_, ConvertMetaParamValue(params.separating()), set_param_quiet));
212 for (
const auto& bool_param : params.bool_params()) {
214 (SCIPsetBoolParam(scip_, bool_param.first.c_str(), bool_param.second)));
216 for (
const auto& int_param : params.int_params()) {
218 (SCIPsetIntParam(scip_, int_param.first.c_str(), int_param.second)));
220 for (
const auto& long_param : params.long_params()) {
222 long_param.second)));
224 for (
const auto& char_param : params.char_params()) {
225 if (char_param.second.size() != 1) {
226 return absl::InvalidArgumentError(
227 absl::StrCat(
"Character parameters must be single character strings, " 229 char_param.first,
" was: ", char_param.second));
232 char_param.second[0])));
234 for (
const auto& string_param : params.string_params()) {
236 string_param.second.c_str())));
238 for (
const auto& real_param : params.real_params()) {
240 (SCIPsetRealParam(scip_, real_param.first.c_str(), real_param.second)));
242 if (!legacy_params.empty()) {
246 return absl::OkStatus();
250 const std::string& problem_name) {
251 SCIP*
scip =
nullptr;
256 return absl::WrapUnique(
new GScip(
scip));
259 GScip::GScip(SCIP* scip) : scip_(scip) {}
263 absl::Status GScip::FreeTransform() {
268 return absl::StrFormat(
"SCIP %d.%d.%d [LP solver: %s]", SCIPmajorVersion(),
269 SCIPminorVersion(), SCIPtechVersion(),
274 if (scip_ ==
nullptr) {
277 return SCIPinterruptSolve(scip_) == SCIP_OKAY;
280 absl::Status GScip::CleanUp() {
281 if (scip_ !=
nullptr) {
282 for (SCIP_VAR* variable : variables_) {
283 if (variable !=
nullptr) {
287 for (SCIP_CONS* constraint : constraints_) {
288 if (constraint !=
nullptr) {
294 return absl::OkStatus();
298 const absl::Status clean_up_status = CleanUp();
299 LOG_IF(DFATAL, !clean_up_status.ok()) << clean_up_status;
303 double lb,
double ub,
double obj_coef,
GScipVarType var_type,
305 SCIP_VAR*
var =
nullptr;
306 lb = ScipInfClamp(lb);
307 ub = ScipInfClamp(ub);
312 ConvertVarType(var_type)));
317 variables_.insert(
var);
324 absl::Status GScip::MaybeKeepConstraintAlive(
327 constraints_.insert(constraint);
331 return absl::OkStatus();
337 SCIP_CONS* constraint =
nullptr;
339 <<
"Error adding constraint: " <<
name <<
".";
342 const_cast<SCIP_VAR**>(range.
variables.data()),
363 SCIP_CONS* constraint =
nullptr;
366 <<
"Error adding quadratic constraint: " <<
name <<
" in linear term.";
369 <<
"Error adding quadratic constraint: " <<
name <<
" in quadratic term.";
371 <<
"Error adding quadratic constraint: " <<
name <<
" in quadratic term.";
373 scip_, &constraint,
name.c_str(), num_lin_vars,
399 <<
"Error adding indicator constraint: " <<
name <<
".";
404 SCIP_CONS* constraint =
nullptr;
407 <<
"Error adding indicator constraint: " <<
name <<
".";
409 scip_, &constraint,
name.c_str(), indicator,
411 const_cast<SCIP_Var**>(indicator_constraint.
variables.data()),
412 const_cast<double*>(indicator_constraint.
coefficients.data()),
432 <<
"Error adding and constraint: " <<
name <<
".";
433 SCIP_CONS* constraint =
nullptr;
435 SCIPcreateConsAnd(scip_, &constraint,
name.c_str(),
437 const_cast<SCIP_VAR**>(logical_data.
operators.data()),
457 <<
"Error adding or constraint: " <<
name <<
".";
458 SCIP_CONS* constraint =
nullptr;
460 SCIPcreateConsOr(scip_, &constraint,
name.c_str(), logical_data.
resultant,
462 const_cast<SCIP_Var**>(logical_data.
operators.data()),
480 absl::Status ValidateSOSData(
const GScipSOSData& sos_data,
481 const std::string&
name) {
483 <<
"Error adding SOS constraint: " <<
name <<
".";
484 if (!sos_data.
weights.empty()) {
486 <<
" Error adding SOS constraint: " <<
name <<
".";
488 absl::flat_hash_set<double> distinct_weights;
489 for (
const double w : sos_data.
weights) {
491 <<
"Error adding SOS constraint: " <<
name 492 <<
", weights must be distinct, but found value " << w <<
" twice.";
493 distinct_weights.insert(w);
495 return absl::OkStatus();
504 SCIP_CONS* constraint =
nullptr;
505 double* weights =
nullptr;
506 if (!sos_data.
weights.empty()) {
507 weights = const_cast<double*>(sos_data.
weights.data());
512 const_cast<SCIP_Var**>(sos_data.
variables.data()), weights,
531 SCIP_CONS* constraint =
nullptr;
532 double* weights =
nullptr;
533 if (!sos_data.
weights.empty()) {
534 weights = const_cast<double*>(sos_data.
weights.data());
538 const_cast<SCIP_Var**>(sos_data.
variables.data()), weights,
555 scip_, is_maximize ? SCIP_OBJSENSE_MAXIMIZE : SCIP_OBJSENSE_MINIMIZE));
556 return absl::OkStatus();
560 double old_offset = SCIPgetOrigObjoffset(scip_);
561 double delta_offset = offset - old_offset;
563 return absl::OkStatus();
567 return SCIPgetObjsense(scip_) == SCIP_OBJSENSE_MAXIMIZE;
574 return absl::OkStatus();
578 lb = ScipInfClamp(lb);
580 return absl::OkStatus();
584 ub = ScipInfClamp(ub);
586 return absl::OkStatus();
591 return absl::OkStatus();
595 SCIP_Bool infeasible;
597 SCIPchgVarType(scip_,
var, ConvertVarType(var_type), &infeasible));
598 return absl::OkStatus();
602 SCIP_Bool did_delete;
605 <<
"Failed to delete variable named: " <<
Name(
var);
606 variables_.erase(
var);
608 return absl::OkStatus();
612 const absl::flat_hash_set<SCIP_VAR*>& vars) {
613 for (SCIP_CONS* constraint : constraints_) {
615 return absl::InvalidArgumentError(absl::StrCat(
616 "Model contains nonlinear constraint: ",
Name(constraint)));
619 return absl::OkStatus();
625 for (SCIP_CONS* constraint : constraints_) {
626 const absl::Span<SCIP_VAR* const> nonzeros =
628 const std::vector<SCIP_VAR*> nonzeros_copy(nonzeros.begin(),
630 for (SCIP_VAR*
var : nonzeros_copy) {
631 if (vars.contains(
var)) {
636 for (SCIP_VAR*
const var : vars) {
639 return absl::OkStatus();
643 return ScipInfUnclamp(SCIPvarGetLbOriginal(
var));
647 return ScipInfUnclamp(SCIPvarGetUbOriginal(
var));
653 return ConvertVarType(SCIPvarGetType(
var));
659 return absl::string_view(SCIPconshdlrGetName(SCIPconsGetHdlr(constraint)));
663 return ConstraintType(constraint) == kLinearConstraintHandlerName;
667 SCIP_CONS* constraint) {
668 int num_vars = SCIPgetNVarsLinear(scip_, constraint);
669 return absl::MakeConstSpan(SCIPgetValsLinear(scip_, constraint), num_vars);
673 SCIP_CONS* constraint) {
674 int num_vars = SCIPgetNVarsLinear(scip_, constraint);
675 return absl::MakeConstSpan(SCIPgetVarsLinear(scip_, constraint), num_vars);
679 return ScipInfUnclamp(SCIPgetLhsLinear(scip_, constraint));
683 return ScipInfUnclamp(SCIPgetRhsLinear(scip_, constraint));
687 return SCIPconsGetName(constraint);
691 lb = ScipInfClamp(lb);
693 return absl::OkStatus();
697 ub = ScipInfClamp(ub);
699 return absl::OkStatus();
704 constraints_.erase(constraint);
706 return absl::OkStatus();
715 return absl::OkStatus();
721 const int scip_num_vars = SCIPgetNOrigVars(scip_);
722 const bool is_solution_partial = partial_solution.size() < scip_num_vars;
723 if (is_solution_partial) {
728 <<
"Error suggesting hint.";
731 for (
const auto& var_value_pair : partial_solution) {
733 var_value_pair.second));
735 if (!is_solution_partial) {
736 SCIP_Bool is_feasible;
738 scip_, solution,
false,
true,
741 if (!static_cast<bool>(is_feasible)) {
748 if (static_cast<bool>(is_stored)) {
767 const absl::Status param_status = SetParams(params, legacy_params);
768 if (!param_status.ok()) {
772 std::string(param_status.message()));
791 if (message_handler !=
nullptr) {
795 SCIPsetMessagehdlr(scip_, new_handler.get());
810 const SCIP_STAGE stage = SCIPgetStage(scip_);
811 if (stage != SCIP_STAGE_PRESOLVING && stage != SCIP_STAGE_SOLVING &&
812 stage != SCIP_STAGE_SOLVED) {
815 absl::StrCat(
"Unpexpected SCIP final stage= ", stage,
816 " was expected to be either SCIP_STAGE_PRESOLVING, " 817 "SCIP_STAGE_SOLVING, or SCIP_STAGE_SOLVED"));
825 if (
file ==
nullptr) {
826 return absl::InvalidArgumentError(absl::StrCat(
828 " to write SCIP solve stats."));
831 int close_result = fclose(
file);
832 if (close_result != 0) {
833 return absl::InvalidArgumentError(absl::StrCat(
834 "Error: ", close_result,
836 " when writing solve stats."));
843 const int num_scip_solutions = SCIPgetNSols(scip_);
844 const int num_returned_solutions =
846 SCIP_SOL** all_solutions = SCIPgetSols(scip_);
848 for (
int i = 0; i < num_returned_solutions; ++i) {
849 SCIP_SOL* scip_sol = all_solutions[i];
850 const double obj_value = ScipInfUnclamp(SCIPgetSolOrigObj(scip_, scip_sol));
852 for (SCIP_VAR* v : variables_) {
853 solution[v] = SCIPgetSolVal(scip_, scip_sol, v);
859 if (stage != SCIP_STAGE_PRESOLVING && SCIPhasPrimalRay(scip_)) {
860 for (SCIP_VAR* v : variables_) {
861 result.
primal_ray[v] = SCIPgetPrimalRayVal(scip_, v);
869 if (stage != SCIP_STAGE_PRESOLVING) {
883 if (message_handler !=
nullptr) {
897 SCIPsetMessagehdlrQuiet(scip_,
false);
898 SCIPsetMessagehdlrLogfile(scip_,
nullptr);
904 const std::string& parameter_name) {
905 SCIP_Bool default_value;
907 SCIPgetBoolParam(scip_, parameter_name.c_str(), &default_value));
908 return static_cast<bool>(default_value);
912 const std::string& parameter_name) {
915 SCIPgetIntParam(scip_, parameter_name.c_str(), &default_value));
916 return default_value;
920 const std::string& parameter_name) {
923 SCIPgetLongintParam(scip_, parameter_name.c_str(), &result));
924 return static_cast<int64_t>(result);
928 const std::string& parameter_name) {
931 SCIPgetRealParam(scip_, parameter_name.c_str(), &result));
936 const std::string& parameter_name) {
939 SCIPgetCharParam(scip_, parameter_name.c_str(), &result));
944 const std::string& parameter_name) {
947 SCIPgetStringParam(scip_, parameter_name.c_str(), &result));
948 return std::string(result);
951 double GScip::ScipInfClamp(
double d) {
952 const double kScipInf =
ScipInf();
953 if (d > kScipInf)
return kScipInf;
954 if (d < -kScipInf)
return -kScipInf;
958 double GScip::ScipInfUnclamp(
double d) {
959 const double kScipInf =
ScipInf();
960 if (d >= kScipInf)
return std::numeric_limits<double>::infinity();
961 if (d <= -kScipInf)
return -std::numeric_limits<double>::infinity();
965 #undef RETURN_ERROR_UNLESS absl::Status SetLinearConstraintUb(SCIP_CONS *constraint, double ub)
absl::Status SetObjCoef(SCIP_VAR *var, double obj_coef)
absl::StatusOr< GScipResult > Solve(const GScipParameters ¶ms=GScipParameters(), const std::string &legacy_params="", GScipMessageHandler message_handler=nullptr)
static constexpr Emphasis COUNTER
void set_root_node_bound(double value)
absl::StatusOr< SCIP_CONS * > AddSOS1Constraint(const GScipSOSData &sos_data, const std::string &name="", const GScipConstraintOptions &options=DefaultGScipConstraintOptions())
void set_total_lp_iterations(::PROTOBUF_NAMESPACE_ID::int64 value)
absl::Status LegacyScipSetSolverSpecificParameters(const std::string ¶meters, SCIP *scip)
static constexpr Status TERMINATE
absl::StatusOr< double > DefaultRealParamValue(const std::string ¶meter_name)
absl::StatusOr< SCIP_VAR * > AddVariable(double lb, double ub, double obj_coef, GScipVarType var_type, const std::string &var_name="", const GScipVariableOptions &options=DefaultGScipVariableOptions())
std::vector< double > objective_values
static constexpr Status TOTAL_NODE_LIMIT
std::vector< SCIP_VAR * > variables
static absl::StatusOr< std::unique_ptr< GScip > > Create(const std::string &problem_name)
bool print_scip_model() const
MessageHandlerPtr CaptureMessageHandlerPtr(SCIP_MESSAGEHDLR *const handler)
std::vector< SCIP_Var * > variables
std::vector< double > quadratic_coefficients
static constexpr Status STALL_NODE_LIMIT
void set_node_count(::PROTOBUF_NAMESPACE_ID::int64 value)
absl::StatusOr< std::string > DefaultStringParamValue(const std::string ¶meter_name)
absl::StatusOr< SCIP_CONS * > AddIndicatorConstraint(const GScipIndicatorConstraint &indicator_constraint, const std::string &name="", const GScipConstraintOptions &options=DefaultGScipConstraintOptions())
GScipParameters_Emphasis Emphasis
std::vector< SCIP_Var * > quadratic_variables1
static constexpr MetaParamValue OFF
bool ObjectiveIsMaximize()
std::vector< SCIP_VAR * > operators
static constexpr Emphasis CP_SOLVER
static constexpr Emphasis OPTIMALITY
std::vector< GScipSolution > solutions
static constexpr Status USER_INTERRUPT
#define SCIP_TO_STATUS(x)
const std::string & detailed_solving_stats_filename() const
absl::StatusOr< MessageHandlerPtr > MakeSCIPMessageHandler(const GScipMessageHandler gscip_message_handler)
const char * SCIPlpiGetSolverName(void)
gets name and version of LP solver
::operations_research::GScipSolvingStats * mutable_stats()
absl::Status SetLinearConstraintLb(SCIP_CONS *constraint, double lb)
static constexpr Status MEM_LIMIT
static constexpr Emphasis EASY_CIP
#define RETURN_ERROR_UNLESS(x)
std::vector< double > coefficients
void set_status_detail(ArgT0 &&arg0, ArgT... args)
absl::Status DeleteConstraint(SCIP_CONS *constraint)
absl::StatusOr< SCIP_CONS * > AddSOS2Constraint(const GScipSOSData &sos_data, const std::string &name="", const GScipConstraintOptions &options=DefaultGScipConstraintOptions())
void set_status(::operations_research::GScipOutput_Status value)
double LinearConstraintLb(SCIP_CONS *constraint)
absl::Status CanSafeBulkDelete(const absl::flat_hash_set< SCIP_VAR * > &vars)
void set_deterministic_time(double value)
GScipVarType VarType(SCIP_VAR *var)
static constexpr Emphasis DEFAULT_EMPHASIS
static constexpr Status BEST_SOL_LIMIT
absl::StatusOr< bool > DefaultBoolParamValue(const std::string ¶meter_name)
static constexpr Status UNKNOWN
static constexpr Emphasis PHASE_PROOF
absl::Status SetLb(SCIP_VAR *var, double lb)
static constexpr MetaParamValue FAST
static constexpr Emphasis HARD_LP
::PROTOBUF_NAMESPACE_ID::int32 num_solutions() const
absl::StatusOr< char > DefaultCharParamValue(const std::string ¶meter_name)
const std::string & scip_model_filename() const
static constexpr Status INF_OR_UNBD
absl::flat_hash_map< SCIP_VAR *, double > primal_ray
absl::Status SetMaximize(bool is_maximize)
absl::StatusOr< GScipHintResult > SuggestHint(const GScipSolution &partial_solution)
std::vector< double > coefficients
const GScipVariableOptions & DefaultGScipVariableOptions()
static constexpr Status GAP_LIMIT
absl::string_view ConstraintType(SCIP_CONS *constraint)
void set_dual_simplex_iterations(::PROTOBUF_NAMESPACE_ID::int64 value)
std::vector< double > linear_coefficients
const GScipConstraintOptions & DefaultGScipConstraintOptions()
static constexpr Status TIME_LIMIT
std::string ProtoEnumToString(ProtoEnumType enum_value)
SCIP_VAR * indicator_variable
static constexpr Emphasis PHASE_FEAS
void set_primal_simplex_iterations(::PROTOBUF_NAMESPACE_ID::int64 value)
absl::StatusOr< SCIP_CONS * > AddQuadraticConstraint(const GScipQuadraticRange &range, const std::string &name="", const GScipConstraintOptions &options=DefaultGScipConstraintOptions())
std::vector< SCIP_Var * > linear_variables
void set_best_bound(double value)
GScipParameters_MetaParamValue MetaParamValue
#define RETURN_IF_SCIP_ERROR(x)
absl::StatusOr< SCIP_CONS * > AddAndConstraint(const GScipLogicalConstraintData &logical_data, const std::string &name="", const GScipConstraintOptions &options=DefaultGScipConstraintOptions())
static constexpr Status NODE_LIMIT
absl::Status SetBranchingPriority(SCIP_VAR *var, int priority)
std::vector< SCIP_Var * > quadratic_variables2
double LinearConstraintUb(SCIP_CONS *constraint)
absl::string_view Name(SCIP_VAR *var)
static constexpr Status INVALID_SOLVER_PARAMETERS
#define LOG_IF(severity, condition)
std::unique_ptr< SCIP_MESSAGEHDLR, ReleaseSCIPMessageHandler > MessageHandlerPtr
static constexpr MetaParamValue DEFAULT_META_PARAM_VALUE
absl::Status SetUb(SCIP_VAR *var, double ub)
static constexpr Status OPTIMAL
int GScipMaxNumThreads(const GScipParameters ¶meters)
absl::Span< const double > LinearConstraintCoefficients(SCIP_CONS *constraint)
absl::StatusOr< SCIP_CONS * > AddLinearConstraint(const GScipLinearRange &range, const std::string &name="", const GScipConstraintOptions &options=DefaultGScipConstraintOptions())
static constexpr MetaParamValue AGGRESSIVE
static constexpr Emphasis FEASIBILITY
absl::StatusOr< int > DefaultIntParamValue(const std::string ¶meter_name)
Collection of objects used to extend the Constraint Solver library.
std::vector< double > weights
absl::StatusOr< SCIP_CONS * > AddOrConstraint(const GScipLogicalConstraintData &logical_data, const std::string &name="", const GScipConstraintOptions &options=DefaultGScipConstraintOptions())
void set_first_lp_relaxation_bound(double value)
absl::StatusOr< int64_t > DefaultLongParamValue(const std::string ¶meter_name)
static constexpr Status RESTART_LIMIT
double ObjCoef(SCIP_VAR *var)
GScipOutput_Status Status
#define RETURN_IF_ERROR(expr)
absl::Status SetVarType(SCIP_VAR *var, GScipVarType var_type)
absl::Status SafeBulkDelete(const absl::flat_hash_set< SCIP_VAR * > &vars)
std::vector< SCIP_VAR * > variables
static constexpr Status INFEASIBLE
absl::Status SetLinearConstraintCoef(SCIP_CONS *constraint, SCIP_VAR *var, double value)
static constexpr Status SOL_LIMIT
static std::string ScipVersion()
absl::Span< SCIP_VAR *const > LinearConstraintVariables(SCIP_CONS *constraint)
absl::Status SetObjectiveOffset(double offset)
absl::Status DeleteVariable(SCIP_VAR *var)
std::function< void(GScipMessageType type, absl::string_view message)> GScipMessageHandler
absl::flat_hash_map< SCIP_VAR *, double > GScipSolution
void set_best_objective(double value)
bool print_detailed_solving_stats() const
#define ASSIGN_OR_RETURN(lhs, rexpr)
bool IsConstraintLinear(SCIP_CONS *constraint)
static constexpr Emphasis PHASE_IMPROVE
static constexpr Status UNBOUNDED