118 absl::Span<SCIP_CONS*> constraints,
122 for (SCIP_CONS* constraint : constraints) {
123 SCIP_CONSDATA* consdata = SCIPconsGetData(constraint);
124 CHECK(consdata !=
nullptr);
125 std::vector<CallbackRangeConstraint> user_suggested_constraints;
127 user_suggested_constraints =
130 user_suggested_constraints =
133 int num_constraints_added = 0;
135 user_suggested_constraints) {
137 user_suggested_constraint.range)) {
140 num_constraints_added++;
142 if (user_suggested_constraint.is_cut) {
143 SCIP_ROW* row =
nullptr;
144 constexpr bool kModifiable =
false;
145 constexpr bool kRemovable =
true;
147 scip, &row, constraint, user_suggested_constraint.name.c_str(),
148 user_suggested_constraint.range.lower_bound(),
149 user_suggested_constraint.range.upper_bound(),
150 user_suggested_constraint.local, kModifiable, kRemovable)));
152 for (
const auto& coef_pair :
153 user_suggested_constraint.range.linear_expr().terms()) {
156 SCIP_VAR* var = ScipGetVar(scip, coef_pair.first->index());
157 const double coef = coef_pair.second;
161 SCIP_Bool infeasible;
162 constexpr bool kForceCut =
false;
163 CHECK_OK(
SCIP_TO_STATUS(SCIPaddRow(scip, row, kForceCut, &infeasible)));
177 std::vector<SCIP_VAR*> vars;
178 std::vector<double> coefs;
179 for (
const auto& coef_pair :
180 user_suggested_constraint.range.linear_expr().terms()) {
183 vars.push_back(ScipGetVar(scip, coef_pair.first->index()));
184 coefs.push_back(coef_pair.second);
187 const int num_vars = vars.size();
188 SCIP_CONS* scip_cons;
192 scip, &scip_cons, user_suggested_constraint.name.c_str(), num_vars,
193 vars.data(), coefs.data(),
194 user_suggested_constraint.range.lower_bound(),
195 user_suggested_constraint.range.upper_bound(),
true,
197 true, user_suggested_constraint.local,
200 if (user_suggested_constraint.local) {
201 CHECK_OK(
SCIP_TO_STATUS(SCIPaddConsLocal(scip, scip_cons,
nullptr)));
401 const int num_vars = operations_research::ScipNumVars(scip);
402 for (
int i = 0; i < num_vars; ++i) {
403 SCIP_VAR* var = operations_research::ScipGetVar(scip, i);
404 SCIP_CALL(SCIPaddVarLocksType(scip, var, locktype, nlockspos + nlocksneg,
405 nlockspos + nlocksneg));
416 std::unique_ptr<ScipCallbackRunner> runner,
SCIP* scip) {
417 SCIP_CONSHDLR* c_scip_handler;
418 SCIP_CONSHDLRDATA* scip_handler_data =
new SCIP_CONSHDLRDATA;
419 scip_handler_data->runner = std::move(runner);
422 scip, &c_scip_handler, description.
name.c_str(),
426 CheckFeasibilityC, VariableRoundingLockC, scip_handler_data)));
427 CHECK(c_scip_handler !=
nullptr);
429 scip, c_scip_handler, SeparateLpC, SeparatePrimalSolutionC,
433 SCIPsetConshdlrFree(scip, c_scip_handler, ConstraintHandlerFreeC)));
435 SCIPsetConshdlrDelete(scip, c_scip_handler, ConstraintHandlerDeleteC)));
439 const std::string& constraint_name,
440 void* constraint_data,
442 SCIP_CONSHDLR* conshdlr = SCIPfindConshdlr(scip, handler_name.c_str());
443 CHECK(conshdlr !=
nullptr)
444 <<
"Constraint handler " << handler_name <<
" not registered with scip.";
446 consdata->
data = constraint_data;
447 SCIP_CONS* constraint =
nullptr;
449 scip, &constraint, constraint_name.c_str(), conshdlr, consdata,
453 CHECK(constraint !=
nullptr);
double VariableValue(const MPVariable *variable) const
ScipConstraintHandlerContext(SCIP *scip, SCIP_SOL *solution, bool is_pseudo_solution)