Google OR-Tools: ortools/linear_solver/scip_interface.cc Source File

1

2

3

4

5

6

7

8

9

10

11

12

13

14#include <stddef.h>

15

16#include <algorithm>

17#include <atomic>

18#include <cstdint>

19#include <limits>

20#include <memory>

21#include <string>

22#include <utility>

23#include <vector>

24

25#include "absl/base/attributes.h"

26#include "absl/cleanup/cleanup.h"

27#include "absl/flags/flag.h"

28#include "absl/status/status.h"

29#include "absl/strings/str_format.h"

30#include "absl/synchronization/mutex.h"

31#include "absl/time/time.h"

32#include "lpi/lpi.h"

44#include "scip/cons_indicator.h"

45#include "scip/cons_linear.h"

46#include "scip/def.h"

47#include "scip/scip_cons.h"

48#include "scip/scip_copy.h"

49#include "scip/scip_general.h"

50#include "scip/scip_message.h"

51#include "scip/scip_numerics.h"

52#include "scip/scip_param.h"

53#include "scip/scip_prob.h"

54#include "scip/scip_sol.h"

55#include "scip/scip_solve.h"

56#include "scip/scip_solvingstats.h"

57#include "scip/scip_var.h"

58#include "scip/scipdefplugins.h"

59#include "scip/type_clock.h"

60#include "scip/type_cons.h"

61#include "scip/type_paramset.h"

62#include "scip/type_prob.h"

63#include "scip/type_retcode.h"

64#include "scip/type_scip.h"

65#include "scip/type_sol.h"

66#include "scip/type_stat.h"

67#include "scip/type_var.h"

68

69ABSL_FLAG(bool, scip_feasibility_emphasis, false,

70 "When true, emphasize search towards feasibility. This may or "

71 "may not result in speedups in some problems.");

72

74namespace {

75

76struct EmptyStruct {};

77}

78

80

82 public:

85

88

91 std::atomic<bool>* interrupt) override;

92

93 void Reset() override;

94

96

97 void SetVariableBounds(int var_index, double lb, double ub) override;

100

105 double new_value, double old_value) override;

108 double coefficient) override;

112

114 int64_t nodes() const override;

116 LOG(DFATAL) << "Basis status only available for continuous problems";

118 }

120 LOG(DFATAL) << "Basis status only available for continuous problems";

122 }

123

125 bool IsLP() const override { return false; }

126 bool IsMIP() const override { return true; }

127

131

133 return absl::StrFormat("SCIP %d.%d.%d [LP solver: %s]", SCIPmajorVersion(),

134 SCIPminorVersion(), SCIPtechVersion(),

135 SCIPlpiGetSolverName());

136 }

137

139 const absl::MutexLock lock(hold_interruptions_mutex_);

140 if (scip_ == nullptr) {

141 LOG_IF(DFATAL, status_.ok()) << "scip_ is null is unexpected here, since "

142 "status_ did not report any error";

143 return true;

144 }

145 return SCIPinterruptSolve(scip_) == SCIP_OKAY;

146 }

147

148 void* underlying_solver() override { return reinterpret_cast<void*>(scip_); }

149

150

151

152

153

154

155

156

157

158

159

160

161

163

164

165

166

167

168

169

170

171

172

175

176 private:

178 void SetRelativeMipGap(double value) override;

179 void SetPrimalTolerance(double value) override;

180 void SetDualTolerance(double value) override;

181 void SetPresolveMode(int presolve) override;

182 void SetScalingMode(int scaling) override;

183 void SetLpAlgorithm(int lp_algorithm) override;

184

185

186

187

188

189

190

191

192

193 absl::Status SetNumThreads(int num_threads) override;

194

195 bool SetSolverSpecificParametersAsString(

196 const std::string& parameters) override;

197

198 void SetUnsupportedIntegerParam(

201 int value) override;

202

203 int SolutionCount();

204

205 void SetSolution(SCIP_SOL* solution);

206

207 absl::Status CreateSCIP();

208

209

210

211 SCIP* DeleteSCIP(bool return_scip = false);

212

213

214

215

216

217

218

219 absl::Status status_;

220

222 std::vector<SCIP_VAR*> scip_variables_;

223 std::vector<SCIP_CONS*> scip_constraints_;

224 int current_solution_index_ = 0;

226 std::unique_ptr<ScipConstraintHandlerForMPCallback> scip_constraint_handler_;

227

228 EmptyStruct constraint_data_for_handler_;

229 bool branching_priority_reset_ = false;

230 bool callback_reset_ = false;

231

232

233

234

235 mutable absl::Mutex hold_interruptions_mutex_;

236};

237

240 public:

242

245

248

250

251 private:

252 std::vector<CallbackRangeConstraint> SeparateSolution(

254

256};

257

258#define RETURN_IF_ALREADY_IN_ERROR_STATE \

259 do { \

260 if (!status_.ok()) { \

261 VLOG_EVERY_N(1, 10) << "Early abort: SCIP is in error state."; \

262 return; \

263 } \

264 } while (false)

265

266#define RETURN_AND_STORE_IF_SCIP_ERROR(x) \

267 do { \

268 status_ = SCIP_TO_STATUS(x); \

269 if (!status_.ok()) return; \

270 } while (false)

271

274 status_ = CreateSCIP();

275}

276

278

280

281 const absl::MutexLock lock(hold_interruptions_mutex_);

282

283

284 SCIP* old_scip = DeleteSCIP(true);

285 const auto scip_deleter = absl::MakeCleanup(

286 [&old_scip]() { CHECK_EQ(SCIPfree(&old_scip), SCIP_OKAY); });

287

288 scip_constraint_handler_.reset();

290

291

292 status_ = CreateSCIP();

293 if (!status_.ok()) {

294 return;

295 }

296

297

298

299

300

301

302

304}

305

306absl::Status SCIPInterface::CreateSCIP() {

309

310

311 if (absl::GetFlag(FLAGS_scip_feasibility_emphasis)) {

313 true));

314 }

315

316

317

318

319

320

322 SCIPsetIntParam(scip_, "timing/clocktype", SCIP_CLOCKTYPE_WALL));

324 nullptr, nullptr, nullptr, nullptr,

325 nullptr, nullptr));

327 scip_, maximize_ ? SCIP_OBJSENSE_MAXIMIZE : SCIP_OBJSENSE_MINIMIZE));

328 return absl::OkStatus();

329}

330

332

333SCIP* SCIPInterface::DeleteSCIP(bool return_scip) {

334

335

336

337

338 CHECK(scip_ != nullptr);

339 for (int i = 0; i < scip_variables_.size(); ++i) {

340 CHECK_EQ(SCIPreleaseVar(scip_, &scip_variables_[i]), SCIP_OKAY);

341 }

342 scip_variables_.clear();

343 for (int j = 0; j < scip_constraints_.size(); ++j) {

344 CHECK_EQ(SCIPreleaseCons(scip_, &scip_constraints_[j]), SCIP_OKAY);

345 }

346 scip_constraints_.clear();

347

348 SCIP* old_scip = scip_;

349 scip_ = nullptr;

350 if (!return_scip) {

351 CHECK_EQ(SCIPfree(&old_scip), SCIP_OKAY);

352 }

353 return old_scip;

354}

355

356

362 scip_, maximize ? SCIP_OBJSENSE_MAXIMIZE : SCIP_OBJSENSE_MINIMIZE));

363}

364

369

373 SCIPchgVarLb(scip_, scip_variables_[var_index], lb));

375 SCIPchgVarUb(scip_, scip_variables_[var_index], ub));

376 } else {

378 }

379}

380

385

387#if (SCIP_VERSION >= 210)

388 SCIP_Bool infeasible = false;

390 scip_, scip_variables_[var_index],

391 integer ? SCIP_VARTYPE_INTEGER : SCIP_VARTYPE_CONTINUOUS, &infeasible));

392#else

394 scip_, scip_variables_[var_index],

395 integer ? SCIP_VARTYPE_INTEGER : SCIP_VARTYPE_CONTINUOUS));

396#endif

397 } else {

399 }

400}

401

406

410 SCIPchgLhsLinear(scip_, scip_constraints_[index], lb));

412 SCIPchgRhsLinear(scip_, scip_constraints_[index], ub));

413 } else {

415 }

416}

417

419 const MPVariable* variable, double new_value,

420 double old_value) {

425

426

429

430

433 scip_, scip_constraints_[constraint->index()],

434 scip_variables_[variable->index()], new_value - old_value));

435 } else {

436

437

439 }

440}

441

442

446 const int constraint_index = constraint->index();

447

449 for (const auto& entry : constraint->coefficients_) {

450 const int var_index = entry.first->index();

451 const double old_coef_value = entry.second;

454

456 SCIPaddCoefLinear(scip_, scip_constraints_[constraint_index],

457 scip_variables_[var_index], -old_coef_value));

458 }

459}

460

461

465

466

468

469

473

476

477 for (const auto& entry : solver_->objective_->coefficients_) {

478 const int var_index = entry.first->index();

479

482 } else {

484 SCIPchgVarObj(scip_, scip_variables_[var_index], 0.0));

485 }

486 }

487

488

489

490

491

492}

493

495

496

497

498

499

500

502 branching_priority_reset_ = true;

503 }

504}

505

509

514

516

519 int total_num_vars = solver_->variables_.size();

522

527 SCIP_VAR* scip_var = nullptr;

528

529 double tmp_obj_coef = 0.0;

531 scip_, &scip_var, var->name().c_str(), var->lb(), var->ub(),

532 tmp_obj_coef,

533 var->integer() ? SCIP_VARTYPE_INTEGER : SCIP_VARTYPE_CONTINUOUS, true,

534 false, nullptr, nullptr, nullptr, nullptr, nullptr));

536 scip_variables_.push_back(scip_var);

538 if (branching_priority != 0) {

539 const int index = var->index();

541 scip_, scip_variables_[index], branching_priority));

542 }

543 }

544

547 for (const auto& entry : ct->coefficients_) {

548 const int var_index = entry.first->index();

551

552

554 SCIPaddCoefLinear(scip_, scip_constraints_[i],

555 scip_variables_[var_index], entry.second));

556 }

557 }

558 }

559 }

560}

561

564 int total_num_rows = solver_->constraints_.size();

567

568 int max_row_length = 0;

573 if (ct->coefficients_.size() > max_row_length) {

574 max_row_length = ct->coefficients_.size();

575 }

576 }

577 std::unique_ptr<SCIP_VAR*[]> vars(new SCIP_VAR*[max_row_length]);

578 std::unique_ptr<double[]> coeffs(new double[max_row_length]);

579

583 const int size = ct->coefficients_.size();

584 int j = 0;

585 for (const auto& entry : ct->coefficients_) {

586 const int var_index = entry.first->index();

588 vars[j] = scip_variables_[var_index];

589 coeffs[j] = entry.second;

590 j++;

591 }

592 SCIP_CONS* scip_constraint = nullptr;

593 const bool is_lazy = ct->is_lazy();

597 SCIP_VAR* ind_var = scip_variables_[ind_index];

600 SCIPgetNegatedVar(scip_, scip_variables_[ind_index], &ind_var));

601 }

602

603 if (ct->ub() < std::numeric_limits<double>::infinity()) {

605 scip_, &scip_constraint, ct->name().c_str(), ind_var, size,

606 vars.get(), coeffs.get(), ct->ub(),

607 !is_lazy,

608 true,

609 true,

610 true,

611 true,

612 false,

613 false,

614 is_lazy,

615 false));

617 scip_constraints_.push_back(scip_constraint);

618 }

619 if (ct->lb() > -std::numeric_limits<double>::infinity()) {

620 for (int i = 0; i < size; ++i) {

621 coeffs[i] *= -1;

622 }

624 scip_, &scip_constraint, ct->name().c_str(), ind_var, size,

625 vars.get(), coeffs.get(), -ct->lb(),

626 !is_lazy,

627 true,

628 true,

629 true,

630 true,

631 false,

632 false,

633 is_lazy,

634 false));

636 scip_constraints_.push_back(scip_constraint);

637 }

638 } else {

639

640

641

643 scip_, &scip_constraint, ct->name().c_str(), size, vars.get(),

644 coeffs.get(), ct->lb(), ct->ub(),

645 !is_lazy,

646 true,

647 true,

648 true,

649 true,

650 false,

651 false,

652 false,

653 is_lazy,

654 false));

656 scip_constraints_.push_back(scip_constraint);

657 }

658 }

659 }

660}

661

665

666

667 for (const auto& entry : solver_->objective_->coefficients_) {

668 const int var_index = entry.first->index();

669 const double obj_coef = entry.second;

671 SCIPchgVarObj(scip_, scip_variables_[var_index], obj_coef));

672 }

673

674

676 scip_, solver_->Objective().offset() - SCIPgetOrigObjoffset(scip_)));

677}

678

679#define RETURN_ABNORMAL_IF_BAD_STATUS \

680 do { \

681 if (!status_.ok()) { \

682 LOG_IF(INFO, solver_->OutputIsEnabled()) \

683 << "Invalid SCIP status: " << status_; \

684 return result_status_ = MPSolver::ABNORMAL; \

685 } \

686 } while (false)

687

688#define RETURN_ABNORMAL_IF_SCIP_ERROR(x) \

689 do { \

690 RETURN_ABNORMAL_IF_BAD_STATUS; \

691 status_ = SCIP_TO_STATUS(x); \

692 RETURN_ABNORMAL_IF_BAD_STATUS; \

693 } while (false);

694

696

697

698

699

701

704

705

706

709 branching_priority_reset_ || callback_reset_) {

711 branching_priority_reset_ = false;

712 callback_reset_ = false;

713 }

714

715

716 SCIPsetMessagehdlrQuiet(scip_, quiet_);

717

718

719 if (solver_->variables_.empty() && solver_->constraints_.empty()) {

725 }

726

728 VLOG(1) << absl::StrFormat("Model built in %s.",

729 absl::FormatDuration(timer.GetDuration()));

730 if (scip_constraint_handler_ != nullptr) {

731

732

733

734

735 CHECK_EQ(scip_constraint_handler_->mp_callback(), callback_);

736 } else if (callback_ != nullptr) {

737 scip_constraint_handler_ =

738 std::make_unique<ScipConstraintHandlerForMPCallback>(callback_);

740 scip_);

742 "mp_solver_callback_constraint_for_scip",

743 &constraint_data_for_handler_,

745 }

746

747

748 if (solver_->time_limit() != 0) {

749 VLOG(1) << "Setting time limit = " << solver_->time_limit() << " ms.";

751 SCIPsetRealParam(scip_, "limits/time", solver_->time_limit_in_secs()));

752 } else {

754 }

755

756

757

758

759

760

761 SetParameters(param);

762 solver_->SetSolverSpecificParametersAsString(

763 solver_->solver_specific_parameter_string_);

764

765

766 if (!solver_->solution_hint_.empty()) {

768 bool is_solution_partial = false;

769 const int num_vars = solver_->variables_.size();

770 if (solver_->solution_hint_.size() != num_vars) {

771

773 SCIPcreatePartialSol(scip_, &solution, nullptr));

774 is_solution_partial = true;

775 } else {

776

778 }

779

780

781 for (const std::pair<const MPVariable*, double>& p :

782 solver_->solution_hint_) {

784 scip_, solution, scip_variables_[p.first->index()], p.second));

785 }

786

787 if (!is_solution_partial) {

788 SCIP_Bool is_feasible;

790 scip_, solution, false, true,

791 true, true, true,

792 &is_feasible));

793 VLOG(1) << "Solution hint is "

794 << (is_feasible ? "FEASIBLE" : "INFEASIBLE");

795 }

796

797

798

799

800

801 SCIP_Bool is_stored;

802 if (!is_solution_partial && SCIPisTransformed(scip_)) {

804 scip_, &solution, false, true,

805 true, true, true,

806 &is_stored));

807 } else {

809 SCIPaddSolFree(scip_, &solution, &is_stored));

810 }

811 }

812

813

816 ? SCIPsolveConcurrent(scip_)

817 : SCIPsolve(scip_));

818 VLOG(1) << absl::StrFormat("Solved in %s.",

819 absl::FormatDuration(timer.GetDuration()));

820 current_solution_index_ = 0;

821

822 SCIP_SOL* const solution = SCIPgetBestSol(scip_);

824

826 } else {

827 VLOG(1) << "No feasible solution found.";

828 }

829

830

831 SCIP_STATUS scip_status = SCIPgetStatus(scip_);

832 switch (scip_status) {

833 case SCIP_STATUS_OPTIMAL:

835 break;

836 case SCIP_STATUS_GAPLIMIT:

837

839 break;

840 case SCIP_STATUS_INFEASIBLE:

842 break;

843 case SCIP_STATUS_UNBOUNDED:

845 break;

846 case SCIP_STATUS_INFORUNBD:

847

848

850 break;

851 default:

854 } else if (scip_status == SCIP_STATUS_TIMELIMIT ||

855 scip_status == SCIP_STATUS_TOTALNODELIMIT) {

857 } else {

859 }

860 break;

861 }

862

864

867}

868

869void SCIPInterface::SetSolution(SCIP_SOL* solution) {

874 for (int i = 0; i < solver_->variables_.size(); ++i) {

876 const int var_index = var->index();

877 const double val =

878 SCIPgetSolVal(scip_, solution, scip_variables_[var_index]);

880 VLOG(3) << var->name() << "=" << val;

881 }

882}

883

885 std::atomic<bool>* interrupt) const {

886

887 if (solver_->GetNumThreads() > 1) return false;

888

889

890 if (interrupt != nullptr) return false;

891

892 return true;

893}

894

897 const bool log_error = request->enable_internal_solver_output();

900}

901

902int SCIPInterface::SolutionCount() { return SCIPgetNSols(scip_); }

903

905

907 return false;

908 }

909 if (current_solution_index_ + 1 >= SolutionCount()) {

910 return false;

911 }

912 current_solution_index_++;

913 SCIP_SOL** all_solutions = SCIPgetSols(scip_);

914 SetSolution(all_solutions[current_solution_index_]);

915 return true;

916}

917

919

920

922 return SCIPgetNLPIterations(scip_);

923}

924

926

928

929

930

931 return SCIPgetNTotalNodes(scip_);

932}

933

937}

938

939void SCIPInterface::SetRelativeMipGap(double value) {

940

941

942

943

944

945

946

947

948

949

950 const auto status =

951 SCIP_TO_STATUS(SCIPsetRealParam(scip_, "limits/gap", value));

952 if (status_.ok()) status_ = status;

953}

954

955void SCIPInterface::SetPrimalTolerance(double value) {

956

957 const auto status =

958 SCIP_TO_STATUS(SCIPsetRealParam(scip_, "numerics/feastol", value));

959 if (status_.ok()) status_ = status;

960}

961

962void SCIPInterface::SetDualTolerance(double value) {

963 const auto status =

964 SCIP_TO_STATUS(SCIPsetRealParam(scip_, "numerics/dualfeastol", value));

965 if (status_.ok()) status_ = status;

966}

967

968void SCIPInterface::SetPresolveMode(int presolve) {

969

970 switch (presolve) {

972 const auto status =

973 SCIP_TO_STATUS(SCIPsetIntParam(scip_, "presolving/maxrounds", 0));

974 if (status_.ok()) status_ = status;

975 return;

976 }

978 const auto status =

979 SCIP_TO_STATUS(SCIPsetIntParam(scip_, "presolving/maxrounds", -1));

980 if (status_.ok()) status_ = status;

981 return;

982 }

983 default: {

985 return;

986 }

987 }

988}

989

990void SCIPInterface::SetScalingMode(int) {

992}

993

994

995

996

997void SCIPInterface::SetLpAlgorithm(int lp_algorithm) {

998

999 switch (lp_algorithm) {

1001 const auto status =

1002 SCIP_TO_STATUS(SCIPsetCharParam(scip_, "lp/initalgorithm", 'd'));

1003 if (status_.ok()) status_ = status;

1004 return;

1005 }

1007 const auto status =

1008 SCIP_TO_STATUS(SCIPsetCharParam(scip_, "lp/initalgorithm", 'p'));

1009 if (status_.ok()) status_ = status;

1010 return;

1011 }

1013

1014 const auto status =

1015 SCIP_TO_STATUS(SCIPsetCharParam(scip_, "lp/initalgorithm", 'p'));

1016 if (status_.ok()) status_ = status;

1017 return;

1018 }

1019 default: {

1021 lp_algorithm);

1022 return;

1023 }

1024 }

1025}

1026

1027void SCIPInterface::SetUnsupportedIntegerParam(

1030 if (status_.ok()) {

1031 status_ = absl::InvalidArgumentError(absl::StrFormat(

1032 "Tried to set unsupported integer parameter %d", param));

1033 }

1034}

1035

1036void SCIPInterface::SetIntegerParamToUnsupportedValue(

1039 if (status_.ok()) {

1040 status_ = absl::InvalidArgumentError(absl::StrFormat(

1041 "Tried to set integer parameter %d to unsupported value %d", param,

1042 value));

1043 }

1044}

1045

1046absl::Status SCIPInterface::SetNumThreads(int num_threads) {

1047 if (SetSolverSpecificParametersAsString(

1048 absl::StrFormat("parallel/maxnthreads = %d\n", num_threads))) {

1049 return absl::OkStatus();

1050 }

1051 return absl::InternalError(

1052 "Could not set parallel/maxnthreads, which may "

1053 "indicate that SCIP API has changed.");

1054}

1055

1056bool SCIPInterface::SetSolverSpecificParametersAsString(

1057 const std::string& parameters) {

1058 const absl::Status s =

1060 if (!s.ok()) {

1061 LOG(WARNING) << "Failed to set SCIP parameter string: " << parameters

1062 << ", error is: " << s;

1063 }

1064 return s.ok();

1065}

1066

1068 public:

1070 bool at_integer_solution)

1071 : scip_context_(scip_context),

1072 at_integer_solution_(at_integer_solution) {}

1073

1075 if (at_integer_solution_) {

1077 }

1079 }

1080

1082 return !scip_context_->is_pseudo_solution();

1083 }

1084

1087 return scip_context_->VariableValue(variable);

1088 }

1089

1092 constraint.is_cut = true;

1093 constraint.range = cutting_plane;

1094 constraint.local = false;

1095 constraints_added_.push_back(std::move(constraint));

1096 }

1097

1100 constraint.is_cut = false;

1101 constraint.range = lazy_constraint;

1102 constraint.local = false;

1103 constraints_added_.push_back(std::move(constraint));

1104 }

1105

1107 const absl::flat_hash_map<const MPVariable*, double>& solution) override {

1108 LOG(FATAL) << "SuggestSolution() not currently supported for SCIP.";

1109 }

1110

1112

1113

1114

1115

1116

1117

1118

1119 return std::max(int64_t{0}, scip_context_->NumNodesProcessed() - 1);

1120 }

1121

1123 return constraints_added_;

1124 }

1125

1126 private:

1128 bool at_integer_solution_;

1129

1130 std::vector<CallbackRangeConstraint> constraints_added_;

1131};

1132

1137

1138std::vector<CallbackRangeConstraint>

1141 return SeparateSolution(context, false);

1142}

1143

1144std::vector<CallbackRangeConstraint>

1147 return SeparateSolution(context, true);

1148}

1149

1150std::vector<CallbackRangeConstraint>

1151ScipConstraintHandlerForMPCallback::SeparateSolution(

1153 const bool at_integer_solution) {

1156 return mp_context.constraints_added();

1157}

1158

1160 if (callback_ != nullptr) {

1161 callback_reset_ = true;

1162 }

1163 callback_ = mp_callback;

1164}

1165

1166namespace {

1167

1168

1169const void* const kRegisterSCIP ABSL_ATTRIBUTE_UNUSED = [] {

1173 return nullptr;

1174}();

1175

1176}

1177

1178}

1179

1180#undef RETURN_AND_STORE_IF_SCIP_ERROR

1181#undef RETURN_IF_ALREADY_IN_ERROR_STATE

1182#undef RETURN_ABNORMAL_IF_BAD_STATUS

1183#undef RETURN_ABNORMAL_IF_SCIP_ERROR

absl::Duration GetDuration() const

virtual void RunCallback(MPCallbackContext *callback_context)=0

bool is_lazy() const

Advanced usage: returns true if the constraint is "lazy" (see below).

double lb() const

Returns the lower bound.

double ub() const

Returns the upper bound.

const MPVariable * indicator_variable() const

const std::string & name() const

Returns the name of the constraint.

int index() const

Returns the index of the constraint in the MPSolver::constraints_.

bool indicator_value() const

static MPSolverInterfaceFactoryRepository * GetInstance()

void Register(MPSolverInterfaceFactory factory, MPSolver::OptimizationProblemType problem_type, std::function< bool()> is_runtime_ready={})

void set_variable_as_extracted(int var_index, bool extracted)

bool CheckSolutionIsSynchronized() const

static constexpr int64_t kUnknownNumberOfIterations

friend class MPConstraint

void InvalidateSolutionSynchronization()

void set_constraint_as_extracted(int ct_index, bool extracted)

void ResetExtractionInformation()

virtual void SetIntegerParamToUnsupportedValue(MPSolverParameters::IntegerParam param, int value)

int last_constraint_index_

virtual void SetUnsupportedIntegerParam(MPSolverParameters::IntegerParam param)

bool variable_is_extracted(int var_index) const

bool constraint_is_extracted(int ct_index) const

static constexpr int64_t kUnknownNumberOfNodes

double best_objective_bound_

void SetMIPParameters(const MPSolverParameters &param)

MPSolverInterface(MPSolver *solver)

void SetCommonParameters(const MPSolverParameters &param)

bool CheckSolutionIsSynchronizedAndExists() const

MPSolver::ResultStatus result_status_

SynchronizationStatus sync_status_

@ PRESOLVE_OFF

Presolve is off.

@ PRESOLVE_ON

Presolve is on.

@ BARRIER

Barrier algorithm.

IntegerParam

Enumeration of parameters that take integer or categorical values.

@ INCREMENTALITY

Advanced usage: incrementality from one solve to the next.

@ PRESOLVE

Advanced usage: presolve mode.

@ LP_ALGORITHM

Algorithm to solve linear programs.

@ SCALING

Advanced usage: enable or disable matrix scaling.

@ INCREMENTALITY_OFF

Start solve from scratch.

int GetIntegerParam(MPSolverParameters::IntegerParam param) const

Returns the value of an integer parameter.

@ FEASIBLE

feasible, or stopped by limit.

@ NOT_SOLVED

not been solved yet.

@ INFEASIBLE

proven infeasible.

@ UNBOUNDED

proven unbounded.

@ ABNORMAL

abnormal, i.e., error of some kind.

@ SCIP_MIXED_INTEGER_PROGRAMMING

The class for variables of a Mathematical Programming (MP) model.

bool integer() const

Returns the integrality requirement of the variable.

double lb() const

Returns the lower bound.

double ub() const

Returns the upper bound.

const std::string & name() const

Returns the name of the variable.

int branching_priority() const

void set_solution_value(double value)

int index() const

Returns the index of the variable in the MPSolver::variables_.

void ExtractObjective() override

Definition scip_interface.cc:662

bool InterruptSolve() override

Definition scip_interface.cc:138

void ExtractNewConstraints() override

Definition scip_interface.cc:562

void AddVariable(MPVariable *var) override

Definition scip_interface.cc:515

int64_t nodes() const override

Definition scip_interface.cc:925

double infinity() override

Definition scip_interface.cc:331

void SetObjectiveCoefficient(const MPVariable *variable, double coefficient) override

Definition scip_interface.cc:462

void SetObjectiveOffset(double value) override

Definition scip_interface.cc:467

void ExtractNewVariables() override

Definition scip_interface.cc:517

void * underlying_solver() override

Definition scip_interface.cc:148

bool IsContinuous() const override

Definition scip_interface.cc:124

~SCIPInterface() override

Definition scip_interface.cc:277

int64_t iterations() const override

Definition scip_interface.cc:918

void SetVariableInteger(int var_index, bool integer) override

Definition scip_interface.cc:381

SCIPInterface(MPSolver *solver)

Definition scip_interface.cc:272

void ClearConstraint(MPConstraint *constraint) override

Definition scip_interface.cc:443

void SetCallback(MPCallback *mp_callback) override

Definition scip_interface.cc:1159

void ClearObjective() override

Definition scip_interface.cc:470

void Reset() override

Definition scip_interface.cc:279

MPSolver::ResultStatus Solve(const MPSolverParameters &param) override

Definition scip_interface.cc:695

void BranchingPriorityChangedForVariable(int var_index) override

Definition scip_interface.cc:494

void SetVariableBounds(int var_index, double lb, double ub) override

Definition scip_interface.cc:365

bool IsMIP() const override

Definition scip_interface.cc:126

void SetCoefficient(MPConstraint *constraint, const MPVariable *variable, double new_value, double old_value) override

Definition scip_interface.cc:418

void SetConstraintBounds(int row_index, double lb, double ub) override

Definition scip_interface.cc:402

bool SupportsCallbacks() const override

Definition scip_interface.cc:174

void AddRowConstraint(MPConstraint *ct) override

Definition scip_interface.cc:506

std::string SolverVersion() const override

Definition scip_interface.cc:132

MPSolver::BasisStatus row_status(int) const override

Definition scip_interface.cc:115

bool IsLP() const override

Definition scip_interface.cc:125

bool SupportsDirectlySolveProto(std::atomic< bool > *interrupt) const override

Definition scip_interface.cc:884

bool NextSolution() override

Definition scip_interface.cc:904

MPSolutionResponse DirectlySolveProto(LazyMutableCopy< MPModelRequest > request, std::atomic< bool > *interrupt) override

Definition scip_interface.cc:895

void SetOptimizationDirection(bool maximize) override

Definition scip_interface.cc:357

bool AddIndicatorConstraint(MPConstraint *ct) override

Definition scip_interface.cc:510

MPSolver::BasisStatus column_status(int) const override

Definition scip_interface.cc:119

std::vector< CallbackRangeConstraint > SeparateIntegerSolution(const ScipConstraintHandlerContext &context, const EmptyStruct &) override

Definition scip_interface.cc:1145

MPCallback * mp_callback() const

Definition scip_interface.cc:249

std::vector< CallbackRangeConstraint > SeparateFractionalSolution(const ScipConstraintHandlerContext &context, const EmptyStruct &) override

Definition scip_interface.cc:1139

ScipConstraintHandlerForMPCallback(MPCallback *mp_callback)

Definition scip_interface.cc:1133

ScipConstraintHandler(const ScipConstraintHandlerDescription &description)

void AddLazyConstraint(const LinearRange &lazy_constraint) override

Definition scip_interface.cc:1098

void AddCut(const LinearRange &cutting_plane) override

Definition scip_interface.cc:1090

int64_t NumExploredNodes() override

Definition scip_interface.cc:1111

MPCallbackEvent Event() override

Definition scip_interface.cc:1074

bool CanQueryVariableValues() override

Definition scip_interface.cc:1081

double VariableValue(const MPVariable *variable) override

Definition scip_interface.cc:1085

ScipMPCallbackContext(const ScipConstraintHandlerContext *scip_context, bool at_integer_solution)

Definition scip_interface.cc:1069

double SuggestSolution(const absl::flat_hash_map< const MPVariable *, double > &solution) override

Definition scip_interface.cc:1106

const std::vector< CallbackRangeConstraint > & constraints_added()

Definition scip_interface.cc:1122

void AddCallbackConstraint(SCIP *scip, ScipConstraintHandler< ConstraintData > *handler, const std::string &constraint_name, const ConstraintData *constraint_data, const ScipCallbackConstraintOptions &options)

Select next search node to expand Select next item_i to add this new search node to the search Generate a new search node where item_i is not in the knapsack Check validity of this new partial solution(using propagators) - If valid

absl::StatusOr< MPSolutionResponse > ScipSolveProto(LazyMutableCopy< MPModelRequest > request)

void RegisterConstraintHandler(ScipConstraintHandler< Constraint > *handler, SCIP *scip)

MPSolutionResponse ConvertStatusOrMPSolutionResponse(bool log_error, absl::StatusOr< MPSolutionResponse > response)

absl::Status LegacyScipSetSolverSpecificParameters(absl::string_view parameters, SCIP *scip)

#define SCIP_TO_STATUS(x)

#define RETURN_IF_SCIP_ERROR(x)

ABSL_FLAG(bool, scip_feasibility_emphasis, false, "When true, emphasize search towards feasibility. This may or " "may not result in speedups in some problems.")

#define RETURN_IF_ALREADY_IN_ERROR_STATE

Definition scip_interface.cc:258

#define RETURN_ABNORMAL_IF_SCIP_ERROR(x)

Definition scip_interface.cc:688

#define RETURN_AND_STORE_IF_SCIP_ERROR(x)

Definition scip_interface.cc:266

#define RETURN_ABNORMAL_IF_BAD_STATUS

Definition scip_interface.cc:679