OR-Tools  8.1
gscip.cc
Go to the documentation of this file.
1 // Copyright 2010-2018 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 
14 #include "ortools/gscip/gscip.h"
15 
16 #include <cstdint>
17 
18 #include "absl/container/flat_hash_set.h"
19 #include "absl/status/statusor.h"
20 #include "absl/strings/str_cat.h"
21 #include "ortools/base/logging.h"
28 #include "scip/cons_linear.h"
29 #include "scip/scip_general.h"
30 #include "scip/scip_param.h"
31 #include "scip/scip_solvingstats.h"
32 #include "scip/scipdefplugins.h"
33 #include "scip/type_cons.h"
34 
35 namespace operations_research {
36 
37 #define RETURN_ERROR_UNLESS(x) \
38  if (!(x)) \
39  return util::StatusBuilder(absl::InvalidArgumentError(absl::StrFormat( \
40  "Condition violated at %s:%d: %s", __FILE__, __LINE__, #x)))
41 
42 namespace {
43 
44 constexpr absl::string_view kLinearConstraintHandlerName = "linear";
45 
46 SCIP_VARTYPE ConvertVarType(const GScipVarType var_type) {
47  switch (var_type) {
48  case GScipVarType::kContinuous:
49  return SCIP_VARTYPE_CONTINUOUS;
51  return SCIP_VARTYPE_IMPLINT;
52  case GScipVarType::kInteger:
53  return SCIP_VARTYPE_INTEGER;
54  }
55 }
56 
57 GScipVarType ConvertVarType(const SCIP_VARTYPE var_type) {
58  switch (var_type) {
59  case SCIP_VARTYPE_CONTINUOUS:
60  return GScipVarType::kContinuous;
61  case SCIP_VARTYPE_IMPLINT:
63  case SCIP_VARTYPE_INTEGER:
64  case SCIP_VARTYPE_BINARY:
65  return GScipVarType::kInteger;
66  }
67 }
68 
69 GScipOutput::Status ConvertStatus(const SCIP_STATUS scip_status) {
70  switch (scip_status) {
71  case SCIP_STATUS_UNKNOWN:
72  return GScipOutput::UNKNOWN;
73  case SCIP_STATUS_USERINTERRUPT:
74  return GScipOutput::USER_INTERRUPT;
75  case SCIP_STATUS_BESTSOLLIMIT:
76  return GScipOutput::BEST_SOL_LIMIT;
77  case SCIP_STATUS_MEMLIMIT:
78  return GScipOutput::MEM_LIMIT;
79  case SCIP_STATUS_NODELIMIT:
80  return GScipOutput::NODE_LIMIT;
81  case SCIP_STATUS_RESTARTLIMIT:
82  return GScipOutput::RESTART_LIMIT;
83  case SCIP_STATUS_SOLLIMIT:
84  return GScipOutput::SOL_LIMIT;
85  case SCIP_STATUS_STALLNODELIMIT:
86  return GScipOutput::STALL_NODE_LIMIT;
87  case SCIP_STATUS_TIMELIMIT:
88  return GScipOutput::TIME_LIMIT;
89  case SCIP_STATUS_TOTALNODELIMIT:
90  return GScipOutput::TOTAL_NODE_LIMIT;
91  case SCIP_STATUS_OPTIMAL:
92  return GScipOutput::OPTIMAL;
93  case SCIP_STATUS_GAPLIMIT:
94  return GScipOutput::GAP_LIMIT;
95  case SCIP_STATUS_INFEASIBLE:
96  return GScipOutput::INFEASIBLE;
97  case SCIP_STATUS_UNBOUNDED:
98  return GScipOutput::UNBOUNDED;
99  case SCIP_STATUS_INFORUNBD:
100  return GScipOutput::INF_OR_UNBD;
101  case SCIP_STATUS_TERMINATE:
102  return GScipOutput::TERMINATE;
103  default:
104  LOG(FATAL) << "Unrecognized scip status: " << scip_status;
105  }
106 }
107 
108 SCIP_PARAMEMPHASIS ConvertEmphasis(
109  const GScipParameters::Emphasis gscip_emphasis) {
110  switch (gscip_emphasis) {
111  case GScipParameters::DEFAULT_EMPHASIS:
112  return SCIP_PARAMEMPHASIS_DEFAULT;
113  case GScipParameters::CP_SOLVER:
114  return SCIP_PARAMEMPHASIS_CPSOLVER;
115  case GScipParameters::EASY_CIP:
116  return SCIP_PARAMEMPHASIS_EASYCIP;
117  case GScipParameters::FEASIBILITY:
118  return SCIP_PARAMEMPHASIS_FEASIBILITY;
119  case GScipParameters::HARD_LP:
120  return SCIP_PARAMEMPHASIS_HARDLP;
121  case GScipParameters::OPTIMALITY:
122  return SCIP_PARAMEMPHASIS_OPTIMALITY;
124  return SCIP_PARAMEMPHASIS_COUNTER;
125  case GScipParameters::PHASE_FEAS:
126  return SCIP_PARAMEMPHASIS_PHASEFEAS;
127  case GScipParameters::PHASE_IMPROVE:
128  return SCIP_PARAMEMPHASIS_PHASEIMPROVE;
129  case GScipParameters::PHASE_PROOF:
130  return SCIP_PARAMEMPHASIS_PHASEPROOF;
131  default:
132  LOG(FATAL) << "Unrecognized gscip_emphasis: "
133  << ProtoEnumToString(gscip_emphasis);
134  }
135 }
136 
137 SCIP_PARAMSETTING ConvertMetaParamValue(
138  const GScipParameters::MetaParamValue gscip_meta_param_value) {
139  switch (gscip_meta_param_value) {
140  case GScipParameters::DEFAULT_META_PARAM_VALUE:
141  return SCIP_PARAMSETTING_DEFAULT;
142  case GScipParameters::AGGRESSIVE:
143  return SCIP_PARAMSETTING_AGGRESSIVE;
144  case GScipParameters::FAST:
145  return SCIP_PARAMSETTING_FAST;
146  case GScipParameters::OFF:
147  return SCIP_PARAMSETTING_OFF;
148  default:
149  LOG(FATAL) << "Unrecognized gscip_meta_param_value: "
150  << ProtoEnumToString(gscip_meta_param_value);
151  }
152 }
153 } // namespace
154 
156  static GScipVariableOptions var_options;
157  return var_options;
158 }
159 
161  static GScipConstraintOptions constraint_options;
162  return constraint_options;
163 }
164 
165 absl::Status GScip::SetParams(const GScipParameters& params,
166  const std::string& legacy_params) {
167  SCIPsetMessagehdlrQuiet(scip_, params.silence_output());
168  if (!params.search_logs_filename().empty()) {
169  SCIPsetMessagehdlrLogfile(scip_, params.search_logs_filename().c_str());
170  }
171  const SCIP_Bool set_param_quiet =
172  static_cast<SCIP_Bool>(!params.silence_output());
173  RETURN_IF_SCIP_ERROR(SCIPsetEmphasis(
174  scip_, ConvertEmphasis(params.emphasis()), set_param_quiet));
175  RETURN_IF_SCIP_ERROR(SCIPsetHeuristics(
176  scip_, ConvertMetaParamValue(params.heuristics()), set_param_quiet));
177  RETURN_IF_SCIP_ERROR(SCIPsetPresolving(
178  scip_, ConvertMetaParamValue(params.presolve()), set_param_quiet));
179  RETURN_IF_SCIP_ERROR(SCIPsetSeparating(
180  scip_, ConvertMetaParamValue(params.separating()), set_param_quiet));
181  for (const auto& bool_param : params.bool_params()) {
183  (SCIPsetBoolParam(scip_, bool_param.first.c_str(), bool_param.second)));
184  }
185  for (const auto& int_param : params.int_params()) {
187  (SCIPsetIntParam(scip_, int_param.first.c_str(), int_param.second)));
188  }
189  for (const auto& long_param : params.long_params()) {
190  RETURN_IF_SCIP_ERROR((SCIPsetLongintParam(scip_, long_param.first.c_str(),
191  long_param.second)));
192  }
193  for (const auto& char_param : params.char_params()) {
194  if (char_param.second.size() != 1) {
195  return absl::InvalidArgumentError(
196  absl::StrCat("Character parameters must be single character strings, "
197  "but parameter: ",
198  char_param.first, " was: ", char_param.second));
199  }
200  RETURN_IF_SCIP_ERROR((SCIPsetCharParam(scip_, char_param.first.c_str(),
201  char_param.second[0])));
202  }
203  for (const auto& string_param : params.string_params()) {
204  RETURN_IF_SCIP_ERROR((SCIPsetStringParam(scip_, string_param.first.c_str(),
205  string_param.second.c_str())));
206  }
207  for (const auto& real_param : params.real_params()) {
209  (SCIPsetRealParam(scip_, real_param.first.c_str(), real_param.second)));
210  }
211  if (!legacy_params.empty()) {
213  LegacyScipSetSolverSpecificParameters(legacy_params, scip_));
214  }
215  return absl::OkStatus();
216 }
217 
218 absl::StatusOr<std::unique_ptr<GScip>> GScip::Create(
219  const std::string& problem_name) {
220  SCIP* scip = nullptr;
221  RETURN_IF_SCIP_ERROR(SCIPcreate(&scip));
222  RETURN_IF_SCIP_ERROR(SCIPincludeDefaultPlugins(scip));
223  RETURN_IF_SCIP_ERROR(SCIPcreateProbBasic(scip, problem_name.c_str()));
224  // NOTE(user): the constructor is private, so we cannot call make_unique.
225  return absl::WrapUnique(new GScip(scip));
226 }
227 
228 GScip::GScip(SCIP* scip) : scip_(scip) {}
229 
230 double GScip::ScipInf() { return SCIPinfinity(scip_); }
231 
232 absl::Status GScip::FreeTransform() {
233  return SCIP_TO_STATUS(SCIPfreeTransform(scip_));
234 }
235 
236 std::string GScip::ScipVersion() {
237  return absl::StrFormat("SCIP %d.%d.%d [LP solver: %s]", SCIPmajorVersion(),
238  SCIPminorVersion(), SCIPtechVersion(),
240 }
241 
243  if (scip_ == nullptr) {
244  return true;
245  }
246  return SCIPinterruptSolve(scip_) == SCIP_OKAY;
247 }
248 
249 absl::Status GScip::CleanUp() {
250  if (scip_ != nullptr) {
251  for (SCIP_VAR* variable : variables_) {
252  if (variable != nullptr) {
253  RETURN_IF_SCIP_ERROR(SCIPreleaseVar(scip_, &variable));
254  }
255  }
256  for (SCIP_CONS* constraint : constraints_) {
257  if (constraint != nullptr) {
258  RETURN_IF_SCIP_ERROR(SCIPreleaseCons(scip_, &constraint));
259  }
260  }
261  RETURN_IF_SCIP_ERROR(SCIPfree(&scip_));
262  }
263  return absl::OkStatus();
264 }
265 
267  const absl::Status clean_up_status = CleanUp();
268  LOG_IF(DFATAL, !clean_up_status.ok()) << clean_up_status;
269 }
270 
271 absl::StatusOr<SCIP_VAR*> GScip::AddVariable(
272  double lb, double ub, double obj_coef, GScipVarType var_type,
273  const std::string& var_name, const GScipVariableOptions& options) {
274  SCIP_VAR* var = nullptr;
275  lb = ScipInfClamp(lb);
276  ub = ScipInfClamp(ub);
277  RETURN_IF_SCIP_ERROR(SCIPcreateVarBasic(scip_, /*var=*/&var,
278  /*name=*/var_name.c_str(),
279  /*lb=*/lb, /*ub=*/ub,
280  /*obj=*/obj_coef,
281  ConvertVarType(var_type)));
282  RETURN_IF_SCIP_ERROR(SCIPvarSetInitial(var, options.initial));
283  RETURN_IF_SCIP_ERROR(SCIPvarSetRemovable(var, options.removable));
284  RETURN_IF_SCIP_ERROR(SCIPaddVar(scip_, var));
285  if (options.keep_alive) {
286  variables_.insert(var);
287  } else {
288  RETURN_IF_SCIP_ERROR(SCIPreleaseVar(scip_, &var));
289  }
290  return var;
291 }
292 
293 absl::Status GScip::MaybeKeepConstraintAlive(
294  SCIP_CONS* constraint, const GScipConstraintOptions& options) {
295  if (options.keep_alive) {
296  constraints_.insert(constraint);
297  } else {
298  RETURN_IF_SCIP_ERROR(SCIPreleaseCons(scip_, &constraint));
299  }
300  return absl::OkStatus();
301 }
302 
303 absl::StatusOr<SCIP_CONS*> GScip::AddLinearConstraint(
304  const GScipLinearRange& range, const std::string& name,
305  const GScipConstraintOptions& options) {
306  SCIP_CONS* constraint = nullptr;
307  RETURN_ERROR_UNLESS(range.variables.size() == range.coefficients.size())
308  << "Error adding constraint: " << name << ".";
309  RETURN_IF_SCIP_ERROR(SCIPcreateConsLinear(
310  scip_, &constraint, name.c_str(), range.variables.size(),
311  const_cast<SCIP_VAR**>(range.variables.data()),
312  const_cast<double*>(range.coefficients.data()),
313  ScipInfClamp(range.lower_bound), ScipInfClamp(range.upper_bound),
314  /*initial=*/options.initial,
315  /*separate=*/options.separate,
316  /*enforce=*/options.enforce,
317  /*check=*/options.check,
318  /*propagate=*/options.propagate,
319  /*local=*/options.local,
320  /*modifiable=*/options.modifiable,
321  /*dynamic=*/options.dynamic,
322  /*removable=*/options.removable,
323  /*stickingatnode=*/options.sticking_at_node));
324  RETURN_IF_SCIP_ERROR(SCIPaddCons(scip_, constraint));
325  RETURN_IF_ERROR(MaybeKeepConstraintAlive(constraint, options));
326  return constraint;
327 }
328 
329 absl::StatusOr<SCIP_CONS*> GScip::AddQuadraticConstraint(
330  const GScipQuadraticRange& range, const std::string& name,
331  const GScipConstraintOptions& options) {
332  SCIP_CONS* constraint = nullptr;
333  const int num_lin_vars = range.linear_variables.size();
334  RETURN_ERROR_UNLESS(num_lin_vars == range.linear_coefficients.size())
335  << "Error adding quadratic constraint: " << name << " in linear term.";
336  const int num_quad_vars = range.quadratic_variables1.size();
337  RETURN_ERROR_UNLESS(num_quad_vars == range.quadratic_variables2.size())
338  << "Error adding quadratic constraint: " << name << " in quadratic term.";
339  RETURN_ERROR_UNLESS(num_quad_vars == range.quadratic_coefficients.size())
340  << "Error adding quadratic constraint: " << name << " in quadratic term.";
341  RETURN_IF_SCIP_ERROR(SCIPcreateConsQuadratic(
342  scip_, &constraint, name.c_str(), num_lin_vars,
343  const_cast<SCIP_Var**>(range.linear_variables.data()),
344  const_cast<double*>(range.linear_coefficients.data()), num_quad_vars,
345  const_cast<SCIP_Var**>(range.quadratic_variables1.data()),
346  const_cast<SCIP_Var**>(range.quadratic_variables2.data()),
347  const_cast<double*>(range.quadratic_coefficients.data()),
348  ScipInfClamp(range.lower_bound), ScipInfClamp(range.upper_bound),
349  /*initial=*/options.initial,
350  /*separate=*/options.separate,
351  /*enforce=*/options.enforce,
352  /*check=*/options.check,
353  /*propagate=*/options.propagate,
354  /*local=*/options.local,
355  /*modifiable=*/options.modifiable,
356  /*dynamic=*/options.dynamic,
357  /*removable=*/options.removable));
358  RETURN_IF_SCIP_ERROR(SCIPaddCons(scip_, constraint));
359  RETURN_IF_ERROR(MaybeKeepConstraintAlive(constraint, options));
360  return constraint;
361 }
362 
363 absl::StatusOr<SCIP_CONS*> GScip::AddIndicatorConstraint(
364  const GScipIndicatorConstraint& indicator_constraint,
365  const std::string& name, const GScipConstraintOptions& options) {
366  SCIP_VAR* indicator = indicator_constraint.indicator_variable;
367  RETURN_ERROR_UNLESS(indicator != nullptr)
368  << "Error adding indicator constraint: " << name << ".";
369  if (indicator_constraint.negate_indicator) {
370  RETURN_IF_SCIP_ERROR(SCIPgetNegatedVar(scip_, indicator, &indicator));
371  }
372 
373  SCIP_CONS* constraint = nullptr;
374  RETURN_ERROR_UNLESS(indicator_constraint.variables.size() ==
375  indicator_constraint.coefficients.size())
376  << "Error adding indicator constraint: " << name << ".";
377  RETURN_IF_SCIP_ERROR(SCIPcreateConsIndicator(
378  scip_, &constraint, name.c_str(), indicator,
379  indicator_constraint.variables.size(),
380  const_cast<SCIP_Var**>(indicator_constraint.variables.data()),
381  const_cast<double*>(indicator_constraint.coefficients.data()),
382  ScipInfClamp(indicator_constraint.upper_bound),
383  /*initial=*/options.initial,
384  /*separate=*/options.separate,
385  /*enforce=*/options.enforce,
386  /*check=*/options.check,
387  /*propagate=*/options.propagate,
388  /*local=*/options.local,
389  /*dynamic=*/options.dynamic,
390  /*removable=*/options.removable,
391  /*stickingatnode=*/options.sticking_at_node));
392  RETURN_IF_SCIP_ERROR(SCIPaddCons(scip_, constraint));
393  RETURN_IF_ERROR(MaybeKeepConstraintAlive(constraint, options));
394  return constraint;
395 }
396 
397 absl::StatusOr<SCIP_CONS*> GScip::AddAndConstraint(
398  const GScipLogicalConstraintData& logical_data, const std::string& name,
399  const GScipConstraintOptions& options) {
400  RETURN_ERROR_UNLESS(logical_data.resultant != nullptr)
401  << "Error adding and constraint: " << name << ".";
402  SCIP_CONS* constraint = nullptr;
404  SCIPcreateConsAnd(scip_, &constraint, name.c_str(),
405  logical_data.resultant, logical_data.operators.size(),
406  const_cast<SCIP_VAR**>(logical_data.operators.data()),
407  /*initial=*/options.initial,
408  /*separate=*/options.separate,
409  /*enforce=*/options.enforce,
410  /*check=*/options.check,
411  /*propagate=*/options.propagate,
412  /*local=*/options.local,
413  /*modifiable=*/options.modifiable,
414  /*dynamic=*/options.dynamic,
415  /*removable=*/options.removable,
416  /*stickingatnode=*/options.sticking_at_node));
417  RETURN_IF_SCIP_ERROR(SCIPaddCons(scip_, constraint));
418  RETURN_IF_ERROR(MaybeKeepConstraintAlive(constraint, options));
419  return constraint;
420 }
421 
422 absl::StatusOr<SCIP_CONS*> GScip::AddOrConstraint(
423  const GScipLogicalConstraintData& logical_data, const std::string& name,
424  const GScipConstraintOptions& options) {
425  RETURN_ERROR_UNLESS(logical_data.resultant != nullptr)
426  << "Error adding or constraint: " << name << ".";
427  SCIP_CONS* constraint = nullptr;
429  SCIPcreateConsOr(scip_, &constraint, name.c_str(), logical_data.resultant,
430  logical_data.operators.size(),
431  const_cast<SCIP_Var**>(logical_data.operators.data()),
432  /*initial=*/options.initial,
433  /*separate=*/options.separate,
434  /*enforce=*/options.enforce,
435  /*check=*/options.check,
436  /*propagate=*/options.propagate,
437  /*local=*/options.local,
438  /*modifiable=*/options.modifiable,
439  /*dynamic=*/options.dynamic,
440  /*removable=*/options.removable,
441  /*stickingatnode=*/options.sticking_at_node));
442  RETURN_IF_SCIP_ERROR(SCIPaddCons(scip_, constraint));
443  RETURN_IF_ERROR(MaybeKeepConstraintAlive(constraint, options));
444  return constraint;
445 }
446 
447 namespace {
448 
449 absl::Status ValidateSOSData(const GScipSOSData& sos_data,
450  const std::string& name) {
451  RETURN_ERROR_UNLESS(!sos_data.variables.empty())
452  << "Error adding SOS constraint: " << name << ".";
453  if (!sos_data.weights.empty()) {
454  RETURN_ERROR_UNLESS(sos_data.variables.size() == sos_data.weights.size())
455  << " Error adding SOS constraint: " << name << ".";
456  }
457  absl::flat_hash_set<double> distinct_weights;
458  for (const double w : sos_data.weights) {
459  RETURN_ERROR_UNLESS(!distinct_weights.contains(w))
460  << "Error adding SOS constraint: " << name
461  << ", weights must be distinct, but found value " << w << " twice.";
462  distinct_weights.insert(w);
463  }
464  return absl::OkStatus();
465 }
466 
467 } // namespace
468 
469 absl::StatusOr<SCIP_CONS*> GScip::AddSOS1Constraint(
470  const GScipSOSData& sos_data, const std::string& name,
471  const GScipConstraintOptions& options) {
472  RETURN_IF_ERROR(ValidateSOSData(sos_data, name));
473  SCIP_CONS* constraint = nullptr;
474  double* weights = nullptr;
475  if (!sos_data.weights.empty()) {
476  weights = const_cast<double*>(sos_data.weights.data());
477  }
478 
479  RETURN_IF_SCIP_ERROR(SCIPcreateConsSOS1(
480  scip_, &constraint, name.c_str(), sos_data.variables.size(),
481  const_cast<SCIP_Var**>(sos_data.variables.data()), weights,
482  /*initial=*/options.initial,
483  /*separate=*/options.separate,
484  /*enforce=*/options.enforce,
485  /*check=*/options.check,
486  /*propagate=*/options.propagate,
487  /*local=*/options.local,
488  /*dynamic=*/options.dynamic,
489  /*removable=*/options.removable,
490  /*stickingatnode=*/options.sticking_at_node));
491  RETURN_IF_SCIP_ERROR(SCIPaddCons(scip_, constraint));
492  RETURN_IF_ERROR(MaybeKeepConstraintAlive(constraint, options));
493  return constraint;
494 }
495 
496 absl::StatusOr<SCIP_CONS*> GScip::AddSOS2Constraint(
497  const GScipSOSData& sos_data, const std::string& name,
498  const GScipConstraintOptions& options) {
499  RETURN_IF_ERROR(ValidateSOSData(sos_data, name));
500  SCIP_CONS* constraint = nullptr;
501  double* weights = nullptr;
502  if (!sos_data.weights.empty()) {
503  weights = const_cast<double*>(sos_data.weights.data());
504  }
505  RETURN_IF_SCIP_ERROR(SCIPcreateConsSOS2(
506  scip_, &constraint, name.c_str(), sos_data.variables.size(),
507  const_cast<SCIP_Var**>(sos_data.variables.data()), weights,
508  /*initial=*/options.initial,
509  /*separate=*/options.separate,
510  /*enforce=*/options.enforce,
511  /*check=*/options.check,
512  /*propagate=*/options.propagate,
513  /*local=*/options.local,
514  /*dynamic=*/options.dynamic,
515  /*removable=*/options.removable,
516  /*stickingatnode=*/options.sticking_at_node));
517  RETURN_IF_SCIP_ERROR(SCIPaddCons(scip_, constraint));
518  RETURN_IF_ERROR(MaybeKeepConstraintAlive(constraint, options));
519  return constraint;
520 }
521 
522 absl::Status GScip::SetMaximize(bool is_maximize) {
523  RETURN_IF_SCIP_ERROR(SCIPsetObjsense(
524  scip_, is_maximize ? SCIP_OBJSENSE_MAXIMIZE : SCIP_OBJSENSE_MINIMIZE));
525  return absl::OkStatus();
526 }
527 
528 absl::Status GScip::SetObjectiveOffset(double offset) {
529  double old_offset = SCIPgetOrigObjoffset(scip_);
530  double delta_offset = offset - old_offset;
531  RETURN_IF_SCIP_ERROR(SCIPaddOrigObjoffset(scip_, delta_offset));
532  return absl::OkStatus();
533 }
534 
536  return SCIPgetObjsense(scip_) == SCIP_OBJSENSE_MAXIMIZE;
537 }
538 
539 double GScip::ObjectiveOffset() { return SCIPgetOrigObjoffset(scip_); }
540 
541 absl::Status GScip::SetBranchingPriority(SCIP_VAR* var, int priority) {
542  RETURN_IF_SCIP_ERROR(SCIPchgVarBranchPriority(scip_, var, priority));
543  return absl::OkStatus();
544 }
545 
546 absl::Status GScip::SetLb(SCIP_VAR* var, double lb) {
547  lb = ScipInfClamp(lb);
548  RETURN_IF_SCIP_ERROR(SCIPchgVarLb(scip_, var, lb));
549  return absl::OkStatus();
550 }
551 
552 absl::Status GScip::SetUb(SCIP_VAR* var, double ub) {
553  ub = ScipInfClamp(ub);
554  RETURN_IF_SCIP_ERROR(SCIPchgVarUb(scip_, var, ub));
555  return absl::OkStatus();
556 }
557 
558 absl::Status GScip::SetObjCoef(SCIP_VAR* var, double obj_coef) {
559  RETURN_IF_SCIP_ERROR(SCIPchgVarObj(scip_, var, obj_coef));
560  return absl::OkStatus();
561 }
562 
563 absl::Status GScip::SetVarType(SCIP_VAR* var, GScipVarType var_type) {
564  SCIP_Bool infeasible;
566  SCIPchgVarType(scip_, var, ConvertVarType(var_type), &infeasible));
567  return absl::OkStatus();
568 }
569 
570 absl::Status GScip::DeleteVariable(SCIP_VAR* var) {
571  SCIP_Bool did_delete;
572  RETURN_IF_SCIP_ERROR(SCIPdelVar(scip_, var, &did_delete));
573  RETURN_ERROR_UNLESS(static_cast<bool>(did_delete))
574  << "Failed to delete variable named: " << Name(var);
575  variables_.erase(var);
576  RETURN_IF_SCIP_ERROR(SCIPreleaseVar(scip_, &var));
577  return absl::OkStatus();
578 }
579 
581  const absl::flat_hash_set<SCIP_VAR*>& vars) {
582  for (SCIP_CONS* constraint : constraints_) {
583  if (!IsConstraintLinear(constraint)) {
584  return absl::InvalidArgumentError(absl::StrCat(
585  "Model contains nonlinear constraint: ", Name(constraint)));
586  }
587  }
588  return absl::OkStatus();
589 }
590 
591 absl::Status GScip::SafeBulkDelete(const absl::flat_hash_set<SCIP_VAR*>& vars) {
593  // Now, we can assume that all constraints are linear.
594  for (SCIP_CONS* constraint : constraints_) {
595  const absl::Span<SCIP_VAR* const> nonzeros =
596  LinearConstraintVariables(constraint);
597  const std::vector<SCIP_VAR*> nonzeros_copy(nonzeros.begin(),
598  nonzeros.end());
599  for (SCIP_VAR* var : nonzeros_copy) {
600  if (vars.contains(var)) {
601  RETURN_IF_ERROR(SetLinearConstraintCoef(constraint, var, 0.0));
602  }
603  }
604  }
605  for (SCIP_VAR* const var : vars) {
607  }
608  return absl::OkStatus();
609 }
610 
611 double GScip::Lb(SCIP_VAR* var) {
612  return ScipInfUnclamp(SCIPvarGetLbOriginal(var));
613 }
614 
615 double GScip::Ub(SCIP_VAR* var) {
616  return ScipInfUnclamp(SCIPvarGetUbOriginal(var));
617 }
618 
619 double GScip::ObjCoef(SCIP_VAR* var) { return SCIPvarGetObj(var); }
620 
622  return ConvertVarType(SCIPvarGetType(var));
623 }
624 
625 absl::string_view GScip::Name(SCIP_VAR* var) { return SCIPvarGetName(var); }
626 
627 absl::string_view GScip::ConstraintType(SCIP_CONS* constraint) {
628  return absl::string_view(SCIPconshdlrGetName(SCIPconsGetHdlr(constraint)));
629 }
630 
631 bool GScip::IsConstraintLinear(SCIP_CONS* constraint) {
632  return ConstraintType(constraint) == kLinearConstraintHandlerName;
633 }
634 
635 absl::Span<const double> GScip::LinearConstraintCoefficients(
636  SCIP_CONS* constraint) {
637  int num_vars = SCIPgetNVarsLinear(scip_, constraint);
638  return absl::MakeConstSpan(SCIPgetValsLinear(scip_, constraint), num_vars);
639 }
640 
641 absl::Span<SCIP_VAR* const> GScip::LinearConstraintVariables(
642  SCIP_CONS* constraint) {
643  int num_vars = SCIPgetNVarsLinear(scip_, constraint);
644  return absl::MakeConstSpan(SCIPgetVarsLinear(scip_, constraint), num_vars);
645 }
646 
647 double GScip::LinearConstraintLb(SCIP_CONS* constraint) {
648  return ScipInfUnclamp(SCIPgetLhsLinear(scip_, constraint));
649 }
650 
651 double GScip::LinearConstraintUb(SCIP_CONS* constraint) {
652  return ScipInfUnclamp(SCIPgetRhsLinear(scip_, constraint));
653 }
654 
655 absl::string_view GScip::Name(SCIP_CONS* constraint) {
656  return SCIPconsGetName(constraint);
657 }
658 
659 absl::Status GScip::SetLinearConstraintLb(SCIP_CONS* constraint, double lb) {
660  lb = ScipInfClamp(lb);
661  RETURN_IF_SCIP_ERROR(SCIPchgLhsLinear(scip_, constraint, lb));
662  return absl::OkStatus();
663 }
664 
665 absl::Status GScip::SetLinearConstraintUb(SCIP_CONS* constraint, double ub) {
666  ub = ScipInfClamp(ub);
667  RETURN_IF_SCIP_ERROR(SCIPchgRhsLinear(scip_, constraint, ub));
668  return absl::OkStatus();
669 }
670 
671 absl::Status GScip::DeleteConstraint(SCIP_CONS* constraint) {
672  RETURN_IF_SCIP_ERROR(SCIPdelCons(scip_, constraint));
673  constraints_.erase(constraint);
674  RETURN_IF_SCIP_ERROR(SCIPreleaseCons(scip_, &constraint));
675  return absl::OkStatus();
676 }
677 
678 absl::Status GScip::SetLinearConstraintCoef(SCIP_CONS* constraint,
679  SCIP_VAR* var, double value) {
680  // TODO(user): this operation is slow (linear in the nnz in the constraint).
681  // It would be better to just use a bulk operation, but there doesn't appear
682  // to be any?
683  RETURN_IF_SCIP_ERROR(SCIPchgCoefLinear(scip_, constraint, var, value));
684  return absl::OkStatus();
685 }
686 
687 absl::StatusOr<GScipHintResult> GScip::SuggestHint(
688  const GScipSolution& partial_solution) {
689  SCIP_SOL* solution;
690  const int scip_num_vars = SCIPgetNOrigVars(scip_);
691  const bool is_solution_partial = partial_solution.size() < scip_num_vars;
692  if (is_solution_partial) {
693  RETURN_IF_SCIP_ERROR(SCIPcreatePartialSol(scip_, &solution, nullptr));
694  } else {
695  // This is actually a full solution
696  RETURN_ERROR_UNLESS(partial_solution.size() == scip_num_vars)
697  << "Error suggesting hint.";
698  RETURN_IF_SCIP_ERROR(SCIPcreateSol(scip_, &solution, nullptr));
699  }
700  for (const auto& var_value_pair : partial_solution) {
701  RETURN_IF_SCIP_ERROR(SCIPsetSolVal(scip_, solution, var_value_pair.first,
702  var_value_pair.second));
703  }
704  if (!is_solution_partial) {
705  SCIP_Bool is_feasible;
706  RETURN_IF_SCIP_ERROR(SCIPcheckSol(
707  scip_, solution, /*printreason=*/false, /*completely=*/true,
708  /*checkbounds=*/true, /*checkintegrality=*/true, /*checklprows=*/true,
709  &is_feasible));
710  if (!static_cast<bool>(is_feasible)) {
711  RETURN_IF_SCIP_ERROR(SCIPfreeSol(scip_, &solution));
712  return GScipHintResult::kInfeasible;
713  }
714  }
715  SCIP_Bool is_stored;
716  RETURN_IF_SCIP_ERROR(SCIPaddSolFree(scip_, &solution, &is_stored));
717  if (static_cast<bool>(is_stored)) {
719  } else {
720  return GScipHintResult::kRejected;
721  }
722 }
723 
724 absl::StatusOr<GScipResult> GScip::Solve(const GScipParameters& params,
725  const std::string& legacy_params) {
726  // A four step process:
727  // 1. Apply parameters.
728  // 2. Solve the problem.
729  // 3. Extract solution and solve statistics.
730  // 4. Prepare the solver for further modification/solves (reset parameters,
731  // free the solutions found).
732  GScipResult result;
733 
734  // Step 1: apply parameters.
735  const absl::Status param_status = SetParams(params, legacy_params);
736  if (!param_status.ok()) {
737  result.gscip_output.set_status(GScipOutput::INVALID_SOLVER_PARAMETERS);
738  // Conversion to std::string for open source build.
739  result.gscip_output.set_status_detail(
740  std::string(param_status.message())); // NOLINT
741  return result;
742  }
743  if (params.print_scip_model()) {
744  RETURN_IF_SCIP_ERROR(SCIPwriteOrigProblem(scip_, nullptr, "cip", FALSE));
745  }
746  if (!params.scip_model_filename().empty()) {
747  RETURN_IF_SCIP_ERROR(SCIPwriteOrigProblem(
748  scip_, params.scip_model_filename().c_str(), "cip", FALSE));
749  }
750 
751  // Step 2: Solve.
752  // NOTE(user): after solve, SCIP will either be in stage PRESOLVING,
753  // SOLVING, OR SOLVED.
754  if (GScipMaxNumThreads(params) > 1) {
755  RETURN_IF_SCIP_ERROR(SCIPsolveConcurrent(scip_));
756  } else {
757  RETURN_IF_SCIP_ERROR(SCIPsolve(scip_));
758  }
759  const SCIP_STAGE stage = SCIPgetStage(scip_);
760  if (stage != SCIP_STAGE_PRESOLVING && stage != SCIP_STAGE_SOLVING &&
761  stage != SCIP_STAGE_SOLVED) {
762  result.gscip_output.set_status(GScipOutput::UNKNOWN);
763  result.gscip_output.set_status_detail(
764  absl::StrCat("Unpexpected SCIP final stage= ", stage,
765  " was expected to be either SCIP_STAGE_PRESOLVING, "
766  "SCIP_STAGE_SOLVING, or SCIP_STAGE_SOLVED"));
767  return result;
768  }
769  if (params.print_detailed_solving_stats()) {
770  RETURN_IF_SCIP_ERROR(SCIPprintStatistics(scip_, nullptr));
771  }
772  if (!params.detailed_solving_stats_filename().empty()) {
773  FILE* file = fopen(params.detailed_solving_stats_filename().c_str(), "w");
774  if (file == nullptr) {
775  return absl::InvalidArgumentError(absl::StrCat(
776  "Could not open file: ", params.detailed_solving_stats_filename(),
777  " to write SCIP solve stats."));
778  }
779  RETURN_IF_SCIP_ERROR(SCIPprintStatistics(scip_, file));
780  int close_result = fclose(file);
781  if (close_result != 0) {
782  return absl::InvalidArgumentError(absl::StrCat(
783  "Error: ", close_result,
784  " closing file: ", params.detailed_solving_stats_filename(),
785  " when writing solve stats."));
786  }
787  }
788  // Step 3: Extract solution information.
789  // Some outputs are available unconditionally, and some are only ready if at
790  // least presolve succeeded.
791  GScipSolvingStats* stats = result.gscip_output.mutable_stats();
792  const int num_scip_solutions = SCIPgetNSols(scip_);
793  const int num_returned_solutions =
794  std::min(num_scip_solutions, std::max(1, params.num_solutions()));
795  SCIP_SOL** all_solutions = SCIPgetSols(scip_);
796  stats->set_best_objective(ScipInfUnclamp(SCIPgetPrimalbound(scip_)));
797  for (int i = 0; i < num_returned_solutions; ++i) {
798  SCIP_SOL* scip_sol = all_solutions[i];
799  const double obj_value = ScipInfUnclamp(SCIPgetSolOrigObj(scip_, scip_sol));
800  GScipSolution solution;
801  for (SCIP_VAR* v : variables_) {
802  solution[v] = SCIPgetSolVal(scip_, scip_sol, v);
803  }
804  result.solutions.push_back(solution);
805  result.objective_values.push_back(obj_value);
806  }
807  // Can only check for primal ray if we made it past presolve.
808  if (stage != SCIP_STAGE_PRESOLVING && SCIPhasPrimalRay(scip_)) {
809  for (SCIP_VAR* v : variables_) {
810  result.primal_ray[v] = SCIPgetPrimalRayVal(scip_, v);
811  }
812  }
813  // TODO(user): refactor this into a new method.
814  stats->set_best_bound(ScipInfUnclamp(SCIPgetDualbound(scip_)));
815  stats->set_node_count(SCIPgetNTotalNodes(scip_));
816  stats->set_first_lp_relaxation_bound(SCIPgetFirstLPDualboundRoot(scip_));
817  stats->set_root_node_bound(SCIPgetDualboundRoot(scip_));
818  if (stage != SCIP_STAGE_PRESOLVING) {
819  stats->set_total_lp_iterations(SCIPgetNLPIterations(scip_));
820  stats->set_primal_simplex_iterations(SCIPgetNPrimalLPIterations(scip_));
821  stats->set_dual_simplex_iterations(SCIPgetNDualLPIterations(scip_));
822  stats->set_deterministic_time(SCIPgetDeterministicTime(scip_));
823  }
824  result.gscip_output.set_status(ConvertStatus(SCIPgetStatus(scip_)));
825 
826  // Step 4: clean up.
827  RETURN_IF_ERROR(FreeTransform());
828  RETURN_IF_SCIP_ERROR(SCIPresetParams(scip_));
829  return result;
830 }
831 
832 absl::StatusOr<bool> GScip::DefaultBoolParamValue(
833  const std::string& parameter_name) {
834  SCIP_Bool default_value;
836  SCIPgetBoolParam(scip_, parameter_name.c_str(), &default_value));
837  return static_cast<bool>(default_value);
838 }
839 
840 absl::StatusOr<int> GScip::DefaultIntParamValue(
841  const std::string& parameter_name) {
842  int default_value;
844  SCIPgetIntParam(scip_, parameter_name.c_str(), &default_value));
845  return default_value;
846 }
847 
848 absl::StatusOr<int64_t> GScip::DefaultLongParamValue(
849  const std::string& parameter_name) {
850  SCIP_Longint result;
852  SCIPgetLongintParam(scip_, parameter_name.c_str(), &result));
853  return static_cast<int64_t>(result);
854 }
855 
856 absl::StatusOr<double> GScip::DefaultRealParamValue(
857  const std::string& parameter_name) {
858  double result;
860  SCIPgetRealParam(scip_, parameter_name.c_str(), &result));
861  return result;
862 }
863 
864 absl::StatusOr<char> GScip::DefaultCharParamValue(
865  const std::string& parameter_name) {
866  char result;
868  SCIPgetCharParam(scip_, parameter_name.c_str(), &result));
869  return result;
870 }
871 
872 absl::StatusOr<std::string> GScip::DefaultStringParamValue(
873  const std::string& parameter_name) {
874  char* result;
876  SCIPgetStringParam(scip_, parameter_name.c_str(), &result));
877  return std::string(result);
878 }
879 
880 double GScip::ScipInfClamp(double d) {
881  const double kScipInf = ScipInf();
882  if (d > kScipInf) return kScipInf;
883  if (d < -kScipInf) return -kScipInf;
884  return d;
885 }
886 
887 double GScip::ScipInfUnclamp(double d) {
888  const double kScipInf = ScipInf();
889  if (d >= kScipInf) return std::numeric_limits<double>::infinity();
890  if (d <= -kScipInf) return -std::numeric_limits<double>::infinity();
891  return d;
892 }
893 
894 #undef RETURN_ERROR_UNLESS
895 
896 } // namespace operations_research
operations_research::GScip::InterruptSolve
bool InterruptSolve()
Definition: gscip.cc:242
operations_research::GScipLogicalConstraintData::resultant
SCIP_VAR * resultant
Definition: gscip.h:440
operations_research::GScipVarType::kContinuous
@ kContinuous
var
IntVar * var
Definition: expr_array.cc:1858
operations_research::GScipVarType
GScipVarType
Definition: gscip.h:103
operations_research::GScip::SetObjCoef
absl::Status SetObjCoef(SCIP_VAR *var, double obj_coef)
Definition: gscip.cc:558
operations_research::GScipSolution
absl::flat_hash_map< SCIP_VAR *, double > GScipSolution
Definition: gscip.h:69
operations_research::GScipResult::gscip_output
GScipOutput gscip_output
Definition: gscip.h:74
min
int64 min
Definition: alldiff_cst.cc:138
operations_research::GScip::AddAndConstraint
absl::StatusOr< SCIP_CONS * > AddAndConstraint(const GScipLogicalConstraintData &logical_data, const std::string &name="", const GScipConstraintOptions &options=DefaultGScipConstraintOptions())
Definition: gscip.cc:397
operations_research::GScip::DefaultCharParamValue
absl::StatusOr< char > DefaultCharParamValue(const std::string &parameter_name)
Definition: gscip.cc:864
operations_research::GScipResult::primal_ray
absl::flat_hash_map< SCIP_VAR *, double > primal_ray
Definition: gscip.h:85
operations_research::GScip::SetLinearConstraintLb
absl::Status SetLinearConstraintLb(SCIP_CONS *constraint, double lb)
Definition: gscip.cc:659
operations_research::GScip::AddIndicatorConstraint
absl::StatusOr< SCIP_CONS * > AddIndicatorConstraint(const GScipIndicatorConstraint &indicator_constraint, const std::string &name="", const GScipConstraintOptions &options=DefaultGScipConstraintOptions())
Definition: gscip.cc:363
max
int64 max
Definition: alldiff_cst.cc:139
operations_research::GScipIndicatorConstraint
Definition: gscip.h:423
operations_research::GScipVariableOptions::removable
bool removable
Definition: gscip.h:466
operations_research::GScip::DefaultBoolParamValue
absl::StatusOr< bool > DefaultBoolParamValue(const std::string &parameter_name)
Definition: gscip.cc:832
operations_research::GScipQuadraticRange::linear_variables
std::vector< SCIP_Var * > linear_variables
Definition: gscip.h:375
LOG
#define LOG(severity)
Definition: base/logging.h:420
operations_research::LegacyScipSetSolverSpecificParameters
absl::Status LegacyScipSetSolverSpecificParameters(const std::string &parameters, SCIP *scip)
Definition: legacy_scip_params.cc:32
operations_research::GScipHintResult::kInfeasible
@ kInfeasible
operations_research::GScip::SetUb
absl::Status SetUb(SCIP_VAR *var, double ub)
Definition: gscip.cc:552
operations_research::GScipConstraintOptions
Definition: gscip.h:484
FATAL
const int FATAL
Definition: log_severity.h:32
operations_research::GScipLinearRange
Definition: gscip.h:93
proto_utils.h
scip_helper_macros.h
logging.h
operations_research::GScipLinearRange::upper_bound
double upper_bound
Definition: gscip.h:97
operations_research::GScip::DefaultStringParamValue
absl::StatusOr< std::string > DefaultStringParamValue(const std::string &parameter_name)
Definition: gscip.cc:872
operations_research::GScip::SetMaximize
absl::Status SetMaximize(bool is_maximize)
Definition: gscip.cc:522
operations_research::ProtoEnumToString
std::string ProtoEnumToString(ProtoEnumType enum_value)
Definition: port/proto_utils.h:63
value
int64 value
Definition: demon_profiler.cc:43
operations_research::GScipVariableOptions::keep_alive
bool keep_alive
Definition: gscip.h:480
operations_research::GScipSOSData
Definition: gscip.h:405
operations_research
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
Definition: dense_doubly_linked_list.h:21
operations_research::GScip::SuggestHint
absl::StatusOr< GScipHintResult > SuggestHint(const GScipSolution &partial_solution)
Definition: gscip.cc:687
operations_research::GScip::ObjectiveIsMaximize
bool ObjectiveIsMaximize()
Definition: gscip.cc:535
operations_research::DefaultGScipVariableOptions
const GScipVariableOptions & DefaultGScipVariableOptions()
Definition: gscip.cc:155
operations_research::GScip::DeleteConstraint
absl::Status DeleteConstraint(SCIP_CONS *constraint)
Definition: gscip.cc:671
operations_research::sat::UNKNOWN
@ UNKNOWN
Definition: cp_model.pb.h:223
operations_research::GScipConstraintOptions::enforce
bool enforce
Definition: gscip.h:498
legacy_scip_params.h
operations_research::GScipVariableOptions
Definition: gscip.h:455
operations_research::GScipIndicatorConstraint::negate_indicator
bool negate_indicator
Definition: gscip.h:426
operations_research::DefaultGScipConstraintOptions
const GScipConstraintOptions & DefaultGScipConstraintOptions()
Definition: gscip.cc:160
operations_research::GScip::LinearConstraintLb
double LinearConstraintLb(SCIP_CONS *constraint)
Definition: gscip.cc:647
operations_research::GScipConstraintOptions::check
bool check
Definition: gscip.h:501
operations_research::GScipIndicatorConstraint::coefficients
std::vector< double > coefficients
Definition: gscip.h:430
operations_research::GScip::ScipInf
double ScipInf()
Definition: gscip.cc:230
operations_research::GScip::Solve
absl::StatusOr< GScipResult > Solve(const GScipParameters &params=GScipParameters(), const std::string &legacy_params="")
Definition: gscip.cc:724
operations_research::GScip::Ub
double Ub(SCIP_VAR *var)
Definition: gscip.cc:615
operations_research::GScip::~GScip
~GScip()
Definition: gscip.cc:266
operations_research::GScipQuadraticRange::lower_bound
double lower_bound
Definition: gscip.h:371
operations_research::GScipQuadraticRange::quadratic_variables2
std::vector< SCIP_Var * > quadratic_variables2
Definition: gscip.h:389
operations_research::GScip::AddSOS1Constraint
absl::StatusOr< SCIP_CONS * > AddSOS1Constraint(const GScipSOSData &sos_data, const std::string &name="", const GScipConstraintOptions &options=DefaultGScipConstraintOptions())
Definition: gscip.cc:469
operations_research::GScip::DeleteVariable
absl::Status DeleteVariable(SCIP_VAR *var)
Definition: gscip.cc:570
status_builder.h
operations_research::GScipConstraintOptions::keep_alive
bool keep_alive
Definition: gscip.h:533
operations_research::GScipLinearRange::variables
std::vector< SCIP_VAR * > variables
Definition: gscip.h:95
operations_research::GScipQuadraticRange
Definition: gscip.h:369
operations_research::GScip::AddOrConstraint
absl::StatusOr< SCIP_CONS * > AddOrConstraint(const GScipLogicalConstraintData &logical_data, const std::string &name="", const GScipConstraintOptions &options=DefaultGScipConstraintOptions())
Definition: gscip.cc:422
operations_research::GScip::DefaultRealParamValue
absl::StatusOr< double > DefaultRealParamValue(const std::string &parameter_name)
Definition: gscip.cc:856
operations_research::GScipLinearRange::coefficients
std::vector< double > coefficients
Definition: gscip.h:96
operations_research::GScip::SafeBulkDelete
absl::Status SafeBulkDelete(const absl::flat_hash_set< SCIP_VAR * > &vars)
Definition: gscip.cc:591
operations_research::GScip::IsConstraintLinear
bool IsConstraintLinear(SCIP_CONS *constraint)
Definition: gscip.cc:631
operations_research::GScip::SetVarType
absl::Status SetVarType(SCIP_VAR *var, GScipVarType var_type)
Definition: gscip.cc:563
operations_research::GScip::AddQuadraticConstraint
absl::StatusOr< SCIP_CONS * > AddQuadraticConstraint(const GScipQuadraticRange &range, const std::string &name="", const GScipConstraintOptions &options=DefaultGScipConstraintOptions())
Definition: gscip.cc:329
operations_research::GScip::LinearConstraintCoefficients
absl::Span< const double > LinearConstraintCoefficients(SCIP_CONS *constraint)
Definition: gscip.cc:635
operations_research::GScip
Definition: gscip.h:120
operations_research::GScipLogicalConstraintData
Definition: gscip.h:439
operations_research::GScipQuadraticRange::linear_coefficients
std::vector< double > linear_coefficients
Definition: gscip.h:376
operations_research::GScipConstraintOptions::dynamic
bool dynamic
Definition: gscip.h:512
gscip_parameters.h
SCIPlpiGetSolverName
const char * SCIPlpiGetSolverName(void)
gets name and version of LP solver
Definition: lpi_glop.cc:137
operations_research::GScipQuadraticRange::upper_bound
double upper_bound
Definition: gscip.h:393
operations_research::GScip::DefaultLongParamValue
absl::StatusOr< int64_t > DefaultLongParamValue(const std::string &parameter_name)
Definition: gscip.cc:848
status_macros.h
operations_research::sat::OPTIMAL
@ OPTIMAL
Definition: cp_model.pb.h:227
operations_research::GScip::ObjCoef
double ObjCoef(SCIP_VAR *var)
Definition: gscip.cc:619
operations_research::GScip::SetObjectiveOffset
absl::Status SetObjectiveOffset(double offset)
Definition: gscip.cc:528
operations_research::GScip::ObjectiveOffset
double ObjectiveOffset()
Definition: gscip.cc:539
LOG_IF
#define LOG_IF(severity, condition)
Definition: base/logging.h:479
operations_research::GScipResult::objective_values
std::vector< double > objective_values
Definition: gscip.h:80
operations_research::GScipConstraintOptions::propagate
bool propagate
Definition: gscip.h:503
operations_research::GScip::SetBranchingPriority
absl::Status SetBranchingPriority(SCIP_VAR *var, int priority)
Definition: gscip.cc:541
operations_research::GScipQuadraticRange::quadratic_variables1
std::vector< SCIP_Var * > quadratic_variables1
Definition: gscip.h:388
operations_research::GScip::AddSOS2Constraint
absl::StatusOr< SCIP_CONS * > AddSOS2Constraint(const GScipSOSData &sos_data, const std::string &name="", const GScipConstraintOptions &options=DefaultGScipConstraintOptions())
Definition: gscip.cc:496
operations_research::GScip::CanSafeBulkDelete
absl::Status CanSafeBulkDelete(const absl::flat_hash_set< SCIP_VAR * > &vars)
Definition: gscip.cc:580
operations_research::GScip::ScipVersion
static std::string ScipVersion()
Definition: gscip.cc:236
gscip.h
operations_research::GScip::DefaultIntParamValue
absl::StatusOr< int > DefaultIntParamValue(const std::string &parameter_name)
Definition: gscip.cc:840
operations_research::GScip::SetLb
absl::Status SetLb(SCIP_VAR *var, double lb)
Definition: gscip.cc:546
operations_research::GScipMaxNumThreads
int GScipMaxNumThreads(const GScipParameters &parameters)
Definition: gscip_parameters.cc:64
operations_research::GScip::Create
static absl::StatusOr< std::unique_ptr< GScip > > Create(const std::string &problem_name)
Definition: gscip.cc:218
RETURN_ERROR_UNLESS
#define RETURN_ERROR_UNLESS(x)
Definition: gscip.cc:37
operations_research::GScipLogicalConstraintData::operators
std::vector< SCIP_VAR * > operators
Definition: gscip.h:441
operations_research::GScipSOSData::weights
std::vector< double > weights
Definition: gscip.h:418
operations_research::GScipIndicatorConstraint::indicator_variable
SCIP_VAR * indicator_variable
Definition: gscip.h:425
file
Definition: file.cc:141
SCIP_TO_STATUS
#define SCIP_TO_STATUS(x)
Definition: scip_helper_macros.h:39
operations_research::GScipConstraintOptions::modifiable
bool modifiable
Definition: gscip.h:509
operations_research::GScipVariableOptions::initial
bool initial
Definition: gscip.h:463
operations_research::GScip::Name
absl::string_view Name(SCIP_VAR *var)
Definition: gscip.cc:625
operations_research::GScipQuadraticRange::quadratic_coefficients
std::vector< double > quadratic_coefficients
Definition: gscip.h:390
operations_research::GScipConstraintOptions::separate
bool separate
Definition: gscip.h:495
operations_research::GScip::AddLinearConstraint
absl::StatusOr< SCIP_CONS * > AddLinearConstraint(const GScipLinearRange &range, const std::string &name="", const GScipConstraintOptions &options=DefaultGScipConstraintOptions())
Definition: gscip.cc:303
operations_research::GScip::LinearConstraintUb
double LinearConstraintUb(SCIP_CONS *constraint)
Definition: gscip.cc:651
operations_research::GScipConstraintOptions::sticking_at_node
bool sticking_at_node
Definition: gscip.h:519
operations_research::GScipSOSData::variables
std::vector< SCIP_VAR * > variables
Definition: gscip.h:409
operations_research::GScip::scip
SCIP * scip()
Definition: gscip.h:332
google::COUNTER
@ COUNTER
Definition: base/logging.h:857
operations_research::GScipResult::solutions
std::vector< GScipSolution > solutions
Definition: gscip.h:78
operations_research::GScip::SetLinearConstraintUb
absl::Status SetLinearConstraintUb(SCIP_CONS *constraint, double ub)
Definition: gscip.cc:665
RETURN_IF_ERROR
#define RETURN_IF_ERROR(expr)
Definition: status_macros.h:27
operations_research::GScip::VarType
GScipVarType VarType(SCIP_VAR *var)
Definition: gscip.cc:621
operations_research::GScip::ConstraintType
absl::string_view ConstraintType(SCIP_CONS *constraint)
Definition: gscip.cc:627
operations_research::GScip::AddVariable
absl::StatusOr< SCIP_VAR * > AddVariable(double lb, double ub, double obj_coef, GScipVarType var_type, const std::string &var_name="", const GScipVariableOptions &options=DefaultGScipVariableOptions())
Definition: gscip.cc:271
operations_research::GScipIndicatorConstraint::upper_bound
double upper_bound
Definition: gscip.h:432
operations_research::GScip::Lb
double Lb(SCIP_VAR *var)
Definition: gscip.cc:611
operations_research::GScip::SetLinearConstraintCoef
absl::Status SetLinearConstraintCoef(SCIP_CONS *constraint, SCIP_VAR *var, double value)
Definition: gscip.cc:678
operations_research::GScipConstraintOptions::removable
bool removable
Definition: gscip.h:515
RETURN_IF_SCIP_ERROR
#define RETURN_IF_SCIP_ERROR(x)
Definition: scip_helper_macros.h:43
operations_research::GScipLinearRange::lower_bound
double lower_bound
Definition: gscip.h:94
name
const std::string name
Definition: default_search.cc:808
operations_research::GScip::LinearConstraintVariables
absl::Span< SCIP_VAR *const > LinearConstraintVariables(SCIP_CONS *constraint)
Definition: gscip.cc:641
operations_research::GScipResult
Definition: gscip.h:73
operations_research::GScipConstraintOptions::initial
bool initial
Definition: gscip.h:493
operations_research::GScipIndicatorConstraint::variables
std::vector< SCIP_Var * > variables
Definition: gscip.h:428