25#include "absl/strings/str_cat.h"
52void ScaleConstraint(
const std::vector<double>& var_scaling,
53 MPConstraintProto* mp_constraint) {
54 const int num_terms = mp_constraint->coefficient_size();
55 for (
int i = 0; i < num_terms; ++i) {
56 const int var_index = mp_constraint->var_index(i);
57 mp_constraint->set_coefficient(
58 i, mp_constraint->coefficient(i) / var_scaling[var_index]);
62void ApplyVarScaling(
const std::vector<double>& var_scaling,
63 MPModelProto* mp_model) {
64 const int num_variables = mp_model->variable_size();
65 for (
int i = 0; i < num_variables; ++i) {
66 const double scaling = var_scaling[i];
67 const MPVariableProto& mp_var = mp_model->variable(i);
69 const double old_ub = mp_var.upper_bound();
70 const double old_obj = mp_var.objective_coefficient();
71 mp_model->mutable_variable(i)->set_lower_bound(old_lb * scaling);
72 mp_model->mutable_variable(i)->set_upper_bound(old_ub * scaling);
73 mp_model->mutable_variable(i)->set_objective_coefficient(old_obj / scaling);
77 for (MPConstraintProto& mp_constraint : *mp_model->mutable_constraint()) {
78 ScaleConstraint(var_scaling, &mp_constraint);
80 for (MPGeneralConstraintProto& general_constraint :
81 *mp_model->mutable_general_constraint()) {
82 switch (general_constraint.general_constraint_case()) {
84 ScaleConstraint(var_scaling,
85 general_constraint.mutable_indicator_constraint()
86 ->mutable_constraint());
94 LOG(
FATAL) <<
"Scaling unsupported for general constraint of type "
95 << general_constraint.general_constraint_case();
105 std::vector<double> var_scaling(num_variables, 1.0);
106 for (
int i = 0; i < num_variables; ++i) {
110 const double magnitude =
std::max(std::abs(lb), std::abs(ub));
111 if (magnitude == 0 || magnitude > max_bound)
continue;
112 var_scaling[i] =
std::min(scaling, max_bound / magnitude);
114 ApplyVarScaling(var_scaling, mp_model);
122 const double initial_x = x;
128 if (std::abs(q * initial_x - std::round(q * initial_x)) < q * tolerance) {
132 const int new_q = prev_q +
static_cast<int>(std::floor(x)) * q;
146double GetIntegralityMultiplier(
const MPModelProto& mp_model,
147 const std::vector<double>& var_scaling,
int var,
148 int ct_index,
double tolerance) {
151 double multiplier = 1.0;
152 double var_coeff = 0.0;
153 const double max_multiplier = 1e4;
154 for (
int i = 0; i <
ct.var_index().size(); ++i) {
155 if (
var ==
ct.var_index(i)) {
156 var_coeff =
ct.coefficient(i);
164 multiplier *
ct.coefficient(i) / var_scaling[
ct.var_index(i)];
167 if (multiplier == 0 || multiplier > max_multiplier)
return 0.0;
172 for (
const double bound : {
ct.lower_bound(),
ct.upper_bound()}) {
173 if (!std::isfinite(
bound))
continue;
174 if (std::abs(std::round(
bound * multiplier) -
bound * multiplier) >
175 tolerance * multiplier) {
179 return std::abs(multiplier * var_coeff);
189 int64_t num_changes = 0;
190 for (
int i = 0; i < num_variables; ++i) {
195 const double new_lb = std::isfinite(lb) ? std::ceil(lb - tolerance) : lb;
202 const double new_ub = std::isfinite(ub) ? std::floor(ub + tolerance) : ub;
208 if (new_ub < new_lb) {
209 SOLVER_LOG(logger,
"Empty domain for integer variable #", i,
": [", lb,
215 if (num_changes > 0) {
217 " bounds of integer variables to integer values");
229 std::vector<double> max_bounds(num_variables);
230 for (
int i = 0; i < num_variables; ++i) {
234 max_bounds[i] =
value;
242 int64_t num_removed = 0;
243 double largest_removed = 0.0;
245 for (
int c = 0; c < num_constraints; ++c) {
248 const int size =
ct->var_index().size();
249 if (size == 0)
continue;
250 const double threshold =
252 for (
int i = 0; i < size; ++i) {
253 const int var =
ct->var_index(i);
254 const double coeff =
ct->coefficient(i);
255 if (std::abs(
coeff) * max_bounds[
var] < threshold) {
256 largest_removed =
std::max(largest_removed, std::abs(
coeff));
259 ct->set_var_index(new_size,
var);
260 ct->set_coefficient(new_size,
coeff);
263 num_removed += size - new_size;
264 ct->mutable_var_index()->Truncate(new_size);
265 ct->mutable_coefficient()->Truncate(new_size);
268 if (num_removed > 0) {
270 " near zero terms with largest magnitude of ", largest_removed,
281 switch (general_constraint.general_constraint_case()) {
289 SOLVER_LOG(logger,
"General constraints of type ",
290 general_constraint.general_constraint_case(),
291 " are not supported.");
299 for (
int i = 0; i < num_variables; ++i) {
301 if ((std::isfinite(
var.lower_bound()) &&
302 std::abs(
var.lower_bound()) > threshold) ||
303 (std::isfinite(
var.upper_bound()) &&
304 std::abs(
var.upper_bound()) > threshold)) {
305 SOLVER_LOG(logger,
"Variable bounds are too large [",
var.lower_bound(),
306 ",",
var.upper_bound(),
"]");
309 if (std::abs(
var.objective_coefficient()) > threshold) {
310 SOLVER_LOG(logger,
"Objective coefficient is too large: ",
311 var.objective_coefficient());
318 for (
int c = 0; c < num_constraints; ++c) {
320 if ((std::isfinite(
ct.lower_bound()) &&
321 std::abs(
ct.lower_bound()) > threshold) ||
322 (std::isfinite(
ct.upper_bound()) &&
323 std::abs(
ct.upper_bound()) > threshold)) {
324 SOLVER_LOG(logger,
"Constraint bounds are too large [",
ct.lower_bound(),
325 ",",
ct.upper_bound(),
"]");
328 for (
const double coeff :
ct.coefficient()) {
329 if (std::abs(
coeff) > threshold) {
342 std::vector<double> var_scaling(num_variables, 1.0);
344 int initial_num_integers = 0;
345 for (
int i = 0; i < num_variables; ++i) {
348 VLOG(1) <<
"Initial num integers: " << initial_num_integers;
351 const double tolerance = 1e-6;
352 std::vector<int> constraint_queue;
355 std::vector<int> constraint_to_num_non_integer(num_constraints, 0);
356 std::vector<std::vector<int>> var_to_constraints(num_variables);
357 for (
int i = 0; i < num_constraints; ++i) {
362 var_to_constraints[
var].push_back(i);
363 constraint_to_num_non_integer[i]++;
366 if (constraint_to_num_non_integer[i] == 1) {
367 constraint_queue.push_back(i);
370 VLOG(1) <<
"Initial constraint queue: " << constraint_queue.size() <<
" / "
373 int num_detected = 0;
374 double max_scaling = 0.0;
375 auto scale_and_mark_as_integer = [&](
int var,
double scaling)
mutable {
379 if (scaling != 1.0) {
380 VLOG(2) <<
"Scaled " <<
var <<
" by " << scaling;
384 max_scaling =
std::max(max_scaling, scaling);
388 var_scaling[
var] = scaling;
392 for (
const int ct_index : var_to_constraints[
var]) {
393 constraint_to_num_non_integer[ct_index]--;
394 if (constraint_to_num_non_integer[ct_index] == 1) {
395 constraint_queue.push_back(ct_index);
400 int num_fail_due_to_rhs = 0;
401 int num_fail_due_to_large_multiplier = 0;
402 int num_processed_constraints = 0;
403 while (!constraint_queue.empty()) {
404 const int top_ct_index = constraint_queue.back();
405 constraint_queue.pop_back();
409 if (constraint_to_num_non_integer[top_ct_index] == 0)
continue;
413 if (
ct.lower_bound() + tolerance <
ct.upper_bound())
continue;
415 ++num_processed_constraints;
427 double multiplier = 1.0;
428 const double max_multiplier = 1e4;
430 for (
int i = 0; i <
ct.var_index().size(); ++i) {
433 var =
ct.var_index(i);
434 var_coeff =
ct.coefficient(i);
439 multiplier *
ct.coefficient(i) / var_scaling[
ct.var_index(i)];
442 if (multiplier == 0 || multiplier > max_multiplier) {
448 if (multiplier == 0 || multiplier > max_multiplier) {
449 ++num_fail_due_to_large_multiplier;
454 const double rhs =
ct.lower_bound();
455 if (std::abs(std::round(rhs * multiplier) - rhs * multiplier) >
456 tolerance * multiplier) {
457 ++num_fail_due_to_rhs;
467 double best_scaling = std::abs(var_coeff * multiplier);
468 for (
const int ct_index : var_to_constraints[
var]) {
469 if (ct_index == top_ct_index)
continue;
470 if (constraint_to_num_non_integer[ct_index] != 1)
continue;
474 if (
ct.lower_bound() + tolerance <
ct.upper_bound())
continue;
476 const double multiplier = GetIntegralityMultiplier(
477 *mp_model, var_scaling,
var, ct_index, tolerance);
478 if (multiplier != 0.0 && multiplier < best_scaling) {
479 best_scaling = multiplier;
483 scale_and_mark_as_integer(
var, best_scaling);
491 int num_in_inequalities = 0;
492 int num_to_be_handled = 0;
493 for (
int var = 0;
var < num_variables; ++
var) {
497 if (var_to_constraints[
var].empty())
continue;
500 for (
const int ct_index : var_to_constraints[
var]) {
501 if (constraint_to_num_non_integer[ct_index] != 1) {
508 std::vector<double> scaled_coeffs;
509 for (
const int ct_index : var_to_constraints[
var]) {
510 const double multiplier = GetIntegralityMultiplier(
511 *mp_model, var_scaling,
var, ct_index, tolerance);
512 if (multiplier == 0.0) {
516 scaled_coeffs.push_back(multiplier);
525 double scaling = scaled_coeffs[0];
526 for (
const double c : scaled_coeffs) {
530 for (
const double c : scaled_coeffs) {
531 const double fraction = c / scaling;
532 if (std::abs(std::round(fraction) - fraction) > tolerance) {
546 if (!std::isfinite(
bound))
continue;
547 if (std::abs(std::round(
bound * scaling) -
bound * scaling) >
548 tolerance * scaling) {
560 ++num_in_inequalities;
561 scale_and_mark_as_integer(
var, scaling);
563 VLOG(1) <<
"num_new_integer: " << num_detected
564 <<
" num_processed_constraints: " << num_processed_constraints
565 <<
" num_rhs_fail: " << num_fail_due_to_rhs
566 <<
" num_multiplier_fail: " << num_fail_due_to_large_multiplier;
568 if (num_to_be_handled > 0) {
569 SOLVER_LOG(logger,
"Missed ", num_to_be_handled,
570 " potential implied integer.");
573 const int num_integers = initial_num_integers + num_detected;
574 SOLVER_LOG(logger,
"Num integers: ", num_integers,
"/", num_variables,
575 " (implied: ", num_detected,
576 " in_inequalities: ", num_in_inequalities,
577 " max_scaling: ", max_scaling,
")",
578 (num_integers == num_variables ?
" [IP] " :
" [MIP] "));
580 ApplyVarScaling(var_scaling, mp_model);
587struct ConstraintScaler {
589 ConstraintProto* AddConstraint(
const MPModelProto& mp_model,
591 CpModelProto* cp_model);
607double FindFractionalScaling(
const std::vector<double>&
coefficients,
609 double multiplier = 1.0;
613 if (multiplier == 0.0)
break;
620ConstraintProto* ConstraintScaler::AddConstraint(
621 const MPModelProto& mp_model,
const MPConstraintProto& mp_constraint,
622 CpModelProto* cp_model) {
623 if (mp_constraint.lower_bound() == -
kInfinity &&
624 mp_constraint.upper_bound() ==
kInfinity) {
628 auto* constraint = cp_model->add_constraints();
629 constraint->set_name(mp_constraint.name());
630 auto* arg = constraint->mutable_linear();
638 const int num_coeffs = mp_constraint.coefficient_size();
639 for (
int i = 0; i < num_coeffs; ++i) {
640 const auto& var_proto = cp_model->variables(mp_constraint.var_index(i));
641 const int64_t lb = var_proto.domain(0);
642 const int64_t ub = var_proto.domain(var_proto.domain_size() - 1);
643 if (lb == 0 && ub == 0)
continue;
645 const double coeff = mp_constraint.coefficient(i);
646 if (
coeff == 0.0)
continue;
661 if (scaling_factor == 0.0) {
665 LOG(DFATAL) <<
"Scaling factor of zero while scaling constraint: "
666 << mp_constraint.ShortDebugString();
675 double x =
std::min(scaling_factor, 1.0);
676 double relative_coeff_error;
677 double scaled_sum_error;
678 for (; x <= scaling_factor; x *= 2) {
680 &relative_coeff_error, &scaled_sum_error);
690 const double integer_factor = FindFractionalScaling(
coefficients, 1e-8);
691 if (integer_factor != 0 && integer_factor < scaling_factor) {
693 &relative_coeff_error, &scaled_sum_error);
695 scaling_factor = integer_factor;
706 bool relax_bound = scaled_sum_error > 0;
709 const double scaled_value =
coefficients[i] * scaling_factor;
710 const int64_t
value =
static_cast<int64_t
>(std::round(scaled_value)) / gcd;
712 if (!mp_model.variable(
var_indices[i]).is_integer()) {
716 arg->add_coeffs(
value);
728 const Fractional scaled_lb = std::ceil(lb * scaling_factor);
736 arg->add_domain(
CeilRatio(IntegerValue(
static_cast<int64_t
>(scaled_lb)),
744 const Fractional scaled_ub = std::floor(ub * scaling_factor);
752 arg->add_domain(
FloorRatio(IntegerValue(
static_cast<int64_t
>(scaled_ub)),
766 CHECK(cp_model !=
nullptr);
782 const int64_t kMaxVariableBound =
785 int num_truncated_bounds = 0;
786 int num_small_domains = 0;
787 const int64_t kSmallDomainSize = 1000;
792 for (
int i = 0; i < num_variables; ++i) {
803 if (mp_var.
lower_bound() >
static_cast<double>(kMaxVariableBound) ||
804 mp_var.
upper_bound() <
static_cast<double>(-kMaxVariableBound)) {
805 SOLVER_LOG(logger,
"Error: variable ", mp_var.DebugString(),
806 " is outside [-mip_max_bound..mip_max_bound]");
811 for (
const bool lower : {
true,
false}) {
813 if (std::abs(
bound) >=
static_cast<double>(kMaxVariableBound)) {
814 ++num_truncated_bounds;
815 cp_var->
add_domain(
bound < 0 ? -kMaxVariableBound : kMaxVariableBound);
821 static_cast<int64_t
>(lower ? std::ceil(
bound - kWantedPrecision)
822 : std::floor(
bound + kWantedPrecision)));
826 LOG(
WARNING) <<
"Variable #" << i <<
" cannot take integer value. "
827 << mp_var.ShortDebugString();
834 cp_var->
domain(1) - cp_var->
domain(0) < kSmallDomainSize) {
839 if (num_truncated_bounds > 0) {
840 SOLVER_LOG(logger,
"Warning: ", num_truncated_bounds,
841 " bounds were truncated to ", kMaxVariableBound,
".");
843 if (num_small_domains > 0) {
844 SOLVER_LOG(logger,
"Warning: ", num_small_domains,
845 " continuous variable domain with fewer than ", kSmallDomainSize,
849 ConstraintScaler scaler;
850 const int64_t kScalingTarget = int64_t{1}
852 scaler.wanted_precision = kWantedPrecision;
853 scaler.scaling_target = kScalingTarget;
857 scaler.AddConstraint(mp_model, mp_constraint, cp_model);
861 switch (general_constraint.general_constraint_case()) {
863 const auto& indicator_constraint =
864 general_constraint.indicator_constraint();
866 indicator_constraint.constraint();
868 scaler.AddConstraint(mp_model, mp_constraint, cp_model);
869 if (
ct ==
nullptr)
continue;
872 const int var = indicator_constraint.var_index();
873 const int value = indicator_constraint.var_value();
878 const auto& and_constraint = general_constraint.and_constraint();
879 const std::string&
name = general_constraint.name();
885 and_constraint.var_index();
890 NegatedRef(and_constraint.resultant_var_index()));
891 for (
const int var_index : and_constraint.var_index()) {
897 const auto& or_constraint = general_constraint.or_constraint();
898 const std::string&
name = general_constraint.name();
904 or_constraint.var_index();
909 NegatedRef(or_constraint.resultant_var_index()));
910 for (
const int var_index : or_constraint.var_index()) {
916 LOG(
ERROR) <<
"Can't convert general constraints of type "
917 << general_constraint.general_constraint_case()
918 <<
" to CpModelProto.";
924 SOLVER_LOG(logger,
"Maximum constraint coefficient relative error: ",
925 scaler.max_relative_coeff_error);
926 SOLVER_LOG(logger,
"Maximum constraint worst-case activity relative error: ",
927 scaler.max_relative_rhs_error,
929 ?
" [Potentially IMPRECISE]"
932 "Maximum constraint scaling factor: ", scaler.max_scaling_factor);
940 for (
int i = 0; i < num_variables; ++i) {
943 float_objective->add_vars(i);
949 if (float_objective->offset() == 0 && float_objective->vars().empty()) {
956 const std::vector<std::pair<int, double>>& objective,
957 double objective_offset,
bool maximize,
967 double min_magnitude = std::numeric_limits<double>::infinity();
968 double max_magnitude = 0.0;
969 double l1_norm = 0.0;
970 for (
const auto [
var,
coeff] : objective) {
972 const int64_t lb = var_proto.
domain(0);
973 const int64_t ub = var_proto.domain(var_proto.domain_size() - 1);
975 if (lb != 0) objective_offset += lb *
coeff;
985 l1_norm += std::abs(
coeff);
988 if (
coefficients.empty() && objective_offset == 0.0)
return true;
991 const double average_magnitude =
993 SOLVER_LOG(logger,
"[Scaling] Floating point objective has ",
994 coefficients.size(),
" terms with magnitude in [", min_magnitude,
995 ", ", max_magnitude,
"] average = ", average_magnitude);
1000 const int64_t kScalingTarget = int64_t{1}
1004 if (scaling_factor == 0.0) {
1005 LOG(
ERROR) <<
"Scaling factor of zero while scaling objective! This "
1006 "likely indicate an infinite coefficient in the objective.";
1015 double x =
std::min(scaling_factor, 1.0);
1016 double relative_coeff_error;
1017 double scaled_sum_error;
1018 const double kWantedPrecision =
1020 for (; x <= scaling_factor; x *= 2) {
1022 &relative_coeff_error, &scaled_sum_error);
1023 if (scaled_sum_error < kWantedPrecision * x)
break;
1029 const double integer_factor = FindFractionalScaling(
coefficients, 1e-8);
1030 if (integer_factor != 0 && integer_factor < scaling_factor) {
1032 &relative_coeff_error, &scaled_sum_error);
1033 if (scaled_sum_error < kWantedPrecision * integer_factor) {
1034 scaling_factor = integer_factor;
1041 SOLVER_LOG(logger,
"[Scaling] Objective coefficient relative error: ",
1042 relative_coeff_error);
1043 SOLVER_LOG(logger,
"[Scaling] Objective worst-case absolute error: ",
1044 scaled_sum_error / scaling_factor);
1046 "[Scaling] Objective scaling factor: ", scaling_factor / gcd);
1052 const int64_t mult = maximize ? -1 : 1;
1053 objective_proto->
set_offset(objective_offset * scaling_factor / gcd * mult);
1054 objective_proto->set_scaling_factor(1.0 / scaling_factor * gcd * mult);
1056 const int64_t
value =
1057 static_cast<int64_t
>(std::round(
coefficients[i] * scaling_factor)) /
1061 objective_proto->add_coeffs(
value * mult);
1065 if (scaled_sum_error == 0.0) {
1066 objective_proto->set_scaling_was_exact(
true);
1074 CHECK(problem !=
nullptr);
1082 for (
int var_id(0); var_id < num_variables; ++var_id) {
1093 if (lb <= -1.0) is_binary =
false;
1094 if (ub >= 2.0) is_binary =
false;
1097 if (lb <= 0.0 && ub >= 1.0) {
1099 }
else if (lb <= 1.0 && ub >= 1.0) {
1106 }
else if (lb <= 0.0 && ub >= 0.0) {
1121 LOG(
WARNING) <<
"The variable #" << var_id <<
" with name "
1122 << mp_var.
name() <<
" is not binary. "
1123 <<
"lb: " << lb <<
" ub: " << ub;
1130 double max_relative_error = 0.0;
1131 double max_bound_error = 0.0;
1133 double relative_error = 0.0;
1134 double scaling_factor = 0.0;
1140 constraint->
set_name(mp_constraint.name());
1144 const int num_coeffs = mp_constraint.coefficient_size();
1145 for (
int i = 0; i < num_coeffs; ++i) {
1152 max_relative_error =
std::max(relative_error, max_relative_error);
1155 double bound_error = 0.0;
1156 for (
int i = 0; i < num_coeffs; ++i) {
1157 const double scaled_value = mp_constraint.coefficient(i) * scaling_factor;
1158 bound_error += std::abs(round(scaled_value) - scaled_value);
1159 const int64_t
value =
static_cast<int64_t
>(round(scaled_value)) / gcd;
1161 constraint->
add_literals(mp_constraint.var_index(i) + 1);
1165 max_bound_error =
std::max(max_bound_error, bound_error);
1172 const Fractional lb = mp_constraint.lower_bound();
1174 if (lb * scaling_factor >
static_cast<double>(kInt64Max)) {
1175 LOG(
WARNING) <<
"A constraint is trivially unsatisfiable.";
1178 if (lb * scaling_factor > -
static_cast<double>(kInt64Max)) {
1181 static_cast<int64_t
>(round(lb * scaling_factor - bound_error)) /
1185 const Fractional ub = mp_constraint.upper_bound();
1187 if (ub * scaling_factor < -
static_cast<double>(kInt64Max)) {
1188 LOG(
WARNING) <<
"A constraint is trivially unsatisfiable.";
1191 if (ub * scaling_factor <
static_cast<double>(kInt64Max)) {
1194 static_cast<int64_t
>(round(ub * scaling_factor + bound_error)) /
1201 LOG(
INFO) <<
"Maximum constraint relative error: " << max_relative_error;
1202 LOG(
INFO) <<
"Maximum constraint bound error: " << max_bound_error;
1207 for (
int var_id = 0; var_id < num_variables; ++var_id) {
1214 max_relative_error =
std::max(relative_error, max_relative_error);
1217 LOG(
INFO) <<
"objective relative error: " << relative_error;
1218 LOG(
INFO) <<
"objective scaling factor: " << scaling_factor / gcd;
1226 for (
int var_id = 0; var_id < num_variables; ++var_id) {
1228 const int64_t
value =
1229 static_cast<int64_t
>(
1242 const double kRelativeTolerance = 1e-8;
1243 if (max_relative_error > kRelativeTolerance) {
1244 LOG(
WARNING) <<
"The relative error during double -> int64_t conversion "
1272 for (
int i = 0; i < constraint.literals_size(); ++i) {
1273 const int literal = constraint.literals(i);
1274 const double coeff = constraint.coefficients(i);
1275 const ColIndex variable_index = ColIndex(abs(
literal) - 1);
1285 constraint.has_lower_bound() ? constraint.lower_bound() - sum
1287 constraint.has_upper_bound() ? constraint.upper_bound() - sum
1298 const double coeff =
1299 static_cast<double>(objective.
coefficients(i)) * scaling_factor;
1300 const ColIndex variable_index = ColIndex(abs(
literal) - 1);
1316 const CpModelProto& model_proto_with_floating_point_objective,
1318 const int64_t inner_integer_objective_lower_bound) {
1325 static_cast<double>(domain[domain.size() - 1]));
1333 for (
int i = 0; i < float_obj.
vars().size(); ++i) {
1334 const glop::ColIndex
col(float_obj.
vars(i));
1342 ct,
static_cast<double>(inner_integer_objective_lower_bound),
1343 std::numeric_limits<double>::infinity());
1344 for (
int i = 0; i < integer_objective.
vars().size(); ++i) {
1346 static_cast<double>(integer_objective.
coeffs(i)));
1363 return float_obj.
maximize() ? std::numeric_limits<double>::infinity()
1364 : -std::numeric_limits<double>::infinity();
#define DCHECK_NE(val1, val2)
#define CHECK_EQ(val1, val2)
#define CHECK_GT(val1, val2)
#define CHECK_NE(val1, val2)
#define DCHECK(condition)
#define VLOG(verboselevel)
int32_t var_index(int index) const
::operations_research::MPConstraintProto * mutable_constraint(int index)
const ::operations_research::MPConstraintProto & constraint(int index) const
int variable_size() const
const std::string & name() const
const ::operations_research::MPVariableProto & variable(int index) const
::operations_research::MPVariableProto * mutable_variable(int index)
double objective_offset() const
const ::operations_research::MPGeneralConstraintProto & general_constraint(int index) const
int constraint_size() const
void set_is_integer(bool value)
const std::string & name() const
double objective_coefficient() const
double upper_bound() const
void set_lower_bound(double value)
double lower_bound() const
void set_upper_bound(double value)
void set_max_deterministic_time(double value)
void set_change_status_to_imprecise(bool value)
Fractional GetObjectiveValue() const
ABSL_MUST_USE_RESULT ProblemStatus Solve(const LinearProgram &lp)
void SetParameters(const GlopParameters ¶meters)
void SetVariableBounds(ColIndex col, Fractional lower_bound, Fractional upper_bound)
void SetConstraintName(RowIndex row, absl::string_view name)
void SetObjectiveOffset(Fractional objective_offset)
void SetCoefficient(RowIndex row, ColIndex col, Fractional value)
void SetVariableName(ColIndex col, absl::string_view name)
void SetConstraintBounds(RowIndex row, Fractional lower_bound, Fractional upper_bound)
ColIndex CreateNewVariable()
void SetVariableType(ColIndex col, VariableType type)
const DenseRow & objective_coefficients() const
void SetObjectiveCoefficient(ColIndex col, Fractional value)
RowIndex CreateNewConstraint()
void SetMaximizationProblem(bool maximize)
::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t > * mutable_literals()
void add_literals(int32_t value)
void set_name(ArgT0 &&arg0, ArgT... args)
::operations_research::sat::BoolArgumentProto * mutable_bool_and()
void add_enforcement_literal(int32_t value)
::operations_research::sat::BoolArgumentProto * mutable_bool_or()
::operations_research::sat::FloatObjectiveProto * mutable_floating_point_objective()
const ::operations_research::sat::IntegerVariableProto & variables(int index) const
void set_name(ArgT0 &&arg0, ArgT... args)
void clear_floating_point_objective()
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final
::operations_research::sat::ConstraintProto * add_constraints()
const ::operations_research::sat::FloatObjectiveProto & floating_point_objective() const
::operations_research::sat::IntegerVariableProto * add_variables()
::operations_research::sat::CpObjectiveProto * mutable_objective()
int32_t vars(int index) const
int64_t coeffs(int index) const
void set_offset(double value)
double coeffs(int index) const
int32_t vars(int index) const
void set_maximize(bool value)
void set_name(ArgT0 &&arg0, ArgT... args)
int64_t domain(int index) const
void add_domain(int64_t value)
void set_lower_bound(int64_t value)
void add_literals(int32_t value)
void set_upper_bound(int64_t value)
void set_name(ArgT0 &&arg0, ArgT... args)
void add_coefficients(int64_t value)
::operations_research::sat::LinearBooleanConstraint * add_constraints()
void set_name(ArgT0 &&arg0, ArgT... args)
int var_names_size() const
void set_num_variables(int32_t value)
const ::operations_research::sat::LinearObjective & objective() const
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final
std::string * add_var_names()
const ::operations_research::sat::LinearBooleanConstraint & constraints(int index) const
const std::string & var_names(int index) const
int32_t num_variables() const
::operations_research::sat::LinearObjective * mutable_objective()
void add_literals(int32_t value)
int literals_size() const
int32_t literals(int index) const
void add_coefficients(int64_t value)
double scaling_factor() const
int64_t coefficients(int index) const
void set_offset(double value)
void set_scaling_factor(double value)
double mip_check_precision() const
double mip_wanted_precision() const
int32_t mip_max_activity_exponent() const
double absolute_gap_limit() const
double mip_max_bound() const
double mip_max_valid_magnitude() const
IntegerValue FloorRatio(IntegerValue dividend, IntegerValue positive_divisor)
bool ScaleAndSetObjective(const SatParameters ¶ms, const std::vector< std::pair< int, double > > &objective, double objective_offset, bool maximize, CpModelProto *cp_model, SolverLogger *logger)
IntegerValue CeilRatio(IntegerValue dividend, IntegerValue positive_divisor)
void ConvertBooleanProblemToLinearProgram(const LinearBooleanProblem &problem, glop::LinearProgram *lp)
bool ConvertBinaryMPModelProtoToBooleanProblem(const MPModelProto &mp_model, LinearBooleanProblem *problem)
void RemoveNearZeroTerms(const SatParameters ¶ms, MPModelProto *mp_model, SolverLogger *logger)
bool ConvertMPModelProtoToCpModelProto(const SatParameters ¶ms, const MPModelProto &mp_model, CpModelProto *cp_model, SolverLogger *logger)
bool MPModelProtoValidationBeforeConversion(const SatParameters ¶ms, const MPModelProto &mp_model, SolverLogger *logger)
void ChangeOptimizationDirection(LinearBooleanProblem *problem)
bool MakeBoundsOfIntegerVariablesInteger(const SatParameters ¶ms, MPModelProto *mp_model, SolverLogger *logger)
double ComputeTrueObjectiveLowerBound(const CpModelProto &model_proto_with_floating_point_objective, const CpObjectiveProto &integer_objective, const int64_t inner_integer_objective_lower_bound)
std::vector< double > ScaleContinuousVariables(double scaling, double max_bound, MPModelProto *mp_model)
std::vector< double > DetectImpliedIntegers(MPModelProto *mp_model, SolverLogger *logger)
int FindRationalFactor(double x, int limit, double tolerance)
Collection of objects used to extend the Constraint Solver library.
void ComputeScalingErrors(const std::vector< double > &input, const std::vector< double > &lb, const std::vector< double > &ub, double scaling_factor, double *max_relative_coeff_error, double *max_scaled_sum_error)
int64_t ComputeGcdOfRoundedDoubles(const std::vector< double > &x, double scaling_factor)
double GetBestScalingOfDoublesToInt64(const std::vector< double > &input, const std::vector< double > &lb, const std::vector< double > &ub, int64_t max_absolute_sum)
double max_scaling_factor
double max_relative_coeff_error
std::vector< double > lower_bounds
std::vector< int > var_indices
std::vector< double > upper_bounds
std::vector< double > coefficients
double max_relative_rhs_error
#define SOLVER_LOG(logger,...)