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);
75 for (MPConstraintProto& mp_constraint : *mp_model->mutable_constraint()) {
76 ScaleConstraint(var_scaling, &mp_constraint);
78 for (MPGeneralConstraintProto& general_constraint :
79 *mp_model->mutable_general_constraint()) {
80 switch (general_constraint.general_constraint_case()) {
82 ScaleConstraint(var_scaling,
83 general_constraint.mutable_indicator_constraint()
84 ->mutable_constraint());
92 LOG(
FATAL) <<
"Scaling unsupported for general constraint of type "
93 << general_constraint.general_constraint_case();
103 std::vector<double> var_scaling(num_variables, 1.0);
104 for (
int i = 0; i < num_variables; ++i) {
108 const double magnitude =
std::max(std::abs(lb), std::abs(ub));
109 if (magnitude == 0 || magnitude > max_bound)
continue;
110 var_scaling[i] =
std::min(scaling, max_bound / magnitude);
112 ApplyVarScaling(var_scaling, mp_model);
120 const double initial_x = x;
126 if (std::abs(q * initial_x - std::round(q * initial_x)) < q * tolerance) {
130 const int new_q = prev_q +
static_cast<int>(std::floor(x)) * q;
144double GetIntegralityMultiplier(
const MPModelProto& mp_model,
145 const std::vector<double>& var_scaling,
int var,
146 int ct_index,
double tolerance) {
149 double multiplier = 1.0;
150 double var_coeff = 0.0;
151 const double max_multiplier = 1e4;
152 for (
int i = 0; i <
ct.var_index().size(); ++i) {
153 if (
var ==
ct.var_index(i)) {
154 var_coeff =
ct.coefficient(i);
162 multiplier *
ct.coefficient(i) / var_scaling[
ct.var_index(i)];
165 if (multiplier == 0 || multiplier > max_multiplier)
return 0.0;
170 for (
const double bound : {
ct.lower_bound(),
ct.upper_bound()}) {
171 if (!std::isfinite(
bound))
continue;
172 if (std::abs(std::round(
bound * multiplier) -
bound * multiplier) >
173 tolerance * multiplier) {
177 return std::abs(multiplier * var_coeff);
189 std::vector<double> max_bounds(num_variables);
190 for (
int i = 0; i < num_variables; ++i) {
194 max_bounds[i] =
value;
202 int64_t num_removed = 0;
203 double largest_removed = 0.0;
205 for (
int c = 0; c < num_constraints; ++c) {
208 const int size =
ct->var_index().size();
209 if (size == 0)
continue;
210 const double threshold =
212 for (
int i = 0; i < size; ++i) {
213 const int var =
ct->var_index(i);
214 const double coeff =
ct->coefficient(i);
215 if (std::abs(coeff) * max_bounds[
var] < threshold) {
216 largest_removed =
std::max(largest_removed, std::abs(coeff));
219 ct->set_var_index(new_size,
var);
220 ct->set_coefficient(new_size, coeff);
223 num_removed += size - new_size;
224 ct->mutable_var_index()->Truncate(new_size);
225 ct->mutable_coefficient()->Truncate(new_size);
228 if (num_removed > 0) {
230 " near zero terms with largest magnitude of ", largest_removed,
238 std::vector<double> var_scaling(num_variables, 1.0);
240 int initial_num_integers = 0;
241 for (
int i = 0; i < num_variables; ++i) {
244 VLOG(1) <<
"Initial num integers: " << initial_num_integers;
247 const double tolerance = 1e-6;
248 std::vector<int> constraint_queue;
251 std::vector<int> constraint_to_num_non_integer(num_constraints, 0);
252 std::vector<std::vector<int>> var_to_constraints(num_variables);
253 for (
int i = 0; i < num_constraints; ++i) {
258 var_to_constraints[
var].push_back(i);
259 constraint_to_num_non_integer[i]++;
262 if (constraint_to_num_non_integer[i] == 1) {
263 constraint_queue.push_back(i);
266 VLOG(1) <<
"Initial constraint queue: " << constraint_queue.size() <<
" / "
269 int num_detected = 0;
270 double max_scaling = 0.0;
271 auto scale_and_mark_as_integer = [&](
int var,
double scaling)
mutable {
275 if (scaling != 1.0) {
276 VLOG(2) <<
"Scaled " <<
var <<
" by " << scaling;
280 max_scaling =
std::max(max_scaling, scaling);
284 var_scaling[
var] = scaling;
288 for (
const int ct_index : var_to_constraints[
var]) {
289 constraint_to_num_non_integer[ct_index]--;
290 if (constraint_to_num_non_integer[ct_index] == 1) {
291 constraint_queue.push_back(ct_index);
296 int num_fail_due_to_rhs = 0;
297 int num_fail_due_to_large_multiplier = 0;
298 int num_processed_constraints = 0;
299 while (!constraint_queue.empty()) {
300 const int top_ct_index = constraint_queue.back();
301 constraint_queue.pop_back();
305 if (constraint_to_num_non_integer[top_ct_index] == 0)
continue;
309 if (
ct.lower_bound() + tolerance <
ct.upper_bound())
continue;
311 ++num_processed_constraints;
323 double multiplier = 1.0;
324 const double max_multiplier = 1e4;
326 for (
int i = 0; i <
ct.var_index().size(); ++i) {
329 var =
ct.var_index(i);
330 var_coeff =
ct.coefficient(i);
335 multiplier *
ct.coefficient(i) / var_scaling[
ct.var_index(i)];
338 if (multiplier == 0 || multiplier > max_multiplier) {
344 if (multiplier == 0 || multiplier > max_multiplier) {
345 ++num_fail_due_to_large_multiplier;
350 const double rhs =
ct.lower_bound();
351 if (std::abs(std::round(rhs * multiplier) - rhs * multiplier) >
352 tolerance * multiplier) {
353 ++num_fail_due_to_rhs;
363 double best_scaling = std::abs(var_coeff * multiplier);
364 for (
const int ct_index : var_to_constraints[
var]) {
365 if (ct_index == top_ct_index)
continue;
366 if (constraint_to_num_non_integer[ct_index] != 1)
continue;
370 if (
ct.lower_bound() + tolerance <
ct.upper_bound())
continue;
372 const double multiplier = GetIntegralityMultiplier(
373 *mp_model, var_scaling,
var, ct_index, tolerance);
374 if (multiplier != 0.0 && multiplier < best_scaling) {
375 best_scaling = multiplier;
379 scale_and_mark_as_integer(
var, best_scaling);
387 int num_in_inequalities = 0;
388 int num_to_be_handled = 0;
389 for (
int var = 0;
var < num_variables; ++
var) {
393 if (var_to_constraints[
var].empty())
continue;
396 for (
const int ct_index : var_to_constraints[
var]) {
397 if (constraint_to_num_non_integer[ct_index] != 1) {
404 std::vector<double> scaled_coeffs;
405 for (
const int ct_index : var_to_constraints[
var]) {
406 const double multiplier = GetIntegralityMultiplier(
407 *mp_model, var_scaling,
var, ct_index, tolerance);
408 if (multiplier == 0.0) {
412 scaled_coeffs.push_back(multiplier);
421 double scaling = scaled_coeffs[0];
422 for (
const double c : scaled_coeffs) {
426 for (
const double c : scaled_coeffs) {
427 const double fraction = c / scaling;
428 if (std::abs(std::round(fraction) - fraction) > tolerance) {
442 if (!std::isfinite(
bound))
continue;
443 if (std::abs(std::round(
bound * scaling) -
bound * scaling) >
444 tolerance * scaling) {
456 ++num_in_inequalities;
457 scale_and_mark_as_integer(
var, scaling);
459 VLOG(1) <<
"num_new_integer: " << num_detected
460 <<
" num_processed_constraints: " << num_processed_constraints
461 <<
" num_rhs_fail: " << num_fail_due_to_rhs
462 <<
" num_multiplier_fail: " << num_fail_due_to_large_multiplier;
464 if (num_to_be_handled > 0) {
465 SOLVER_LOG(logger,
"Missed ", num_to_be_handled,
466 " potential implied integer.");
469 const int num_integers = initial_num_integers + num_detected;
470 SOLVER_LOG(logger,
"Num integers: ", num_integers,
"/", num_variables,
471 " (implied: ", num_detected,
472 " in_inequalities: ", num_in_inequalities,
473 " max_scaling: ", max_scaling,
")",
474 (num_integers == num_variables ?
" [IP] " :
" [MIP] "));
476 ApplyVarScaling(var_scaling, mp_model);
483struct ConstraintScaler {
485 ConstraintProto* AddConstraint(
const MPModelProto& mp_model,
487 CpModelProto* cp_model);
503double FindFractionalScaling(
const std::vector<double>&
coefficients,
505 double multiplier = 1.0;
509 if (multiplier == 0.0)
break;
516ConstraintProto* ConstraintScaler::AddConstraint(
517 const MPModelProto& mp_model,
const MPConstraintProto& mp_constraint,
518 CpModelProto* cp_model) {
519 if (mp_constraint.lower_bound() == -
kInfinity &&
520 mp_constraint.upper_bound() ==
kInfinity) {
524 auto* constraint = cp_model->add_constraints();
525 constraint->set_name(mp_constraint.name());
526 auto* arg = constraint->mutable_linear();
534 const int num_coeffs = mp_constraint.coefficient_size();
535 for (
int i = 0; i < num_coeffs; ++i) {
536 const auto& var_proto = cp_model->variables(mp_constraint.var_index(i));
537 const int64_t lb = var_proto.domain(0);
538 const int64_t ub = var_proto.domain(var_proto.domain_size() - 1);
539 if (lb == 0 && ub == 0)
continue;
541 const double coeff = mp_constraint.coefficient(i);
542 if (coeff == 0.0)
continue;
557 if (scaling_factor == 0.0) {
561 LOG(DFATAL) <<
"Scaling factor of zero while scaling constraint: "
562 << mp_constraint.ShortDebugString();
571 double x =
std::min(scaling_factor, 1.0);
572 double relative_coeff_error;
573 double scaled_sum_error;
574 for (; x <= scaling_factor; x *= 2) {
576 &relative_coeff_error, &scaled_sum_error);
586 const double integer_factor = FindFractionalScaling(
coefficients, 1e-8);
587 if (integer_factor != 0 && integer_factor < scaling_factor) {
589 &relative_coeff_error, &scaled_sum_error);
591 scaling_factor = integer_factor;
602 bool relax_bound = scaled_sum_error > 0;
605 const double scaled_value =
coefficients[i] * scaling_factor;
606 const int64_t
value =
static_cast<int64_t
>(std::round(scaled_value)) / gcd;
608 if (!mp_model.variable(
var_indices[i]).is_integer()) {
612 arg->add_coeffs(
value);
624 const Fractional scaled_lb = std::ceil(lb * scaling_factor);
632 arg->add_domain(
CeilRatio(IntegerValue(
static_cast<int64_t
>(scaled_lb)),
640 const Fractional scaled_ub = std::floor(ub * scaling_factor);
648 arg->add_domain(
FloorRatio(IntegerValue(
static_cast<int64_t
>(scaled_ub)),
662 CHECK(cp_model !=
nullptr);
678 const int64_t kMaxVariableBound =
681 int num_truncated_bounds = 0;
682 int num_small_domains = 0;
683 const int64_t kSmallDomainSize = 1000;
688 for (
int i = 0; i < num_variables; ++i) {
700 ++num_truncated_bounds;
701 const int64_t
value =
702 static_cast<int64_t
>(std::round(mp_var.
lower_bound()));
706 }
else if (mp_var.
upper_bound() < -kMaxVariableBound) {
708 ++num_truncated_bounds;
709 const int64_t
value =
710 static_cast<int64_t
>(std::round(mp_var.
upper_bound()));
717 for (
const bool lower : {
true,
false}) {
719 if (std::abs(
bound) >= kMaxVariableBound) {
720 ++num_truncated_bounds;
721 cp_var->
add_domain(
bound < 0 ? -kMaxVariableBound : kMaxVariableBound);
727 static_cast<int64_t
>(lower ? std::ceil(
bound - kWantedPrecision)
728 : std::floor(
bound + kWantedPrecision)));
732 LOG(
WARNING) <<
"Variable #" << i <<
" cannot take integer value. "
733 << mp_var.ShortDebugString();
740 cp_var->
domain(1) - cp_var->
domain(0) < kSmallDomainSize) {
746 << num_truncated_bounds <<
" bounds were truncated to "
747 << kMaxVariableBound <<
".";
749 << num_small_domains <<
" continuous variable domain with fewer than "
750 << kSmallDomainSize <<
" values.";
752 ConstraintScaler scaler;
753 const int64_t kScalingTarget = int64_t{1}
755 scaler.wanted_precision = kWantedPrecision;
756 scaler.scaling_target = kScalingTarget;
760 scaler.AddConstraint(mp_model, mp_constraint, cp_model);
764 switch (general_constraint.general_constraint_case()) {
766 const auto& indicator_constraint =
767 general_constraint.indicator_constraint();
769 indicator_constraint.constraint();
771 scaler.AddConstraint(mp_model, mp_constraint, cp_model);
772 if (
ct ==
nullptr)
continue;
775 const int var = indicator_constraint.var_index();
776 const int value = indicator_constraint.var_value();
781 const auto& and_constraint = general_constraint.and_constraint();
782 const std::string&
name = general_constraint.name();
788 and_constraint.var_index();
793 NegatedRef(and_constraint.resultant_var_index()));
794 for (
const int var_index : and_constraint.var_index()) {
800 const auto& or_constraint = general_constraint.or_constraint();
801 const std::string&
name = general_constraint.name();
807 or_constraint.var_index();
812 NegatedRef(or_constraint.resultant_var_index()));
813 for (
const int var_index : or_constraint.var_index()) {
819 LOG(
ERROR) <<
"Can't convert general constraints of type "
820 << general_constraint.general_constraint_case()
821 <<
" to CpModelProto.";
827 SOLVER_LOG(logger,
"Maximum constraint coefficient relative error: ",
828 scaler.max_relative_coeff_error);
829 SOLVER_LOG(logger,
"Maximum constraint worst-case activity relative error: ",
830 scaler.max_relative_rhs_error,
832 ?
" [Potentially IMPRECISE]"
835 "Maximum constraint scaling factor: ", scaler.max_scaling_factor);
842 double min_magnitude = std::numeric_limits<double>::infinity();
843 double max_magnitude = 0.0;
844 double l1_norm = 0.0;
845 for (
int i = 0; i < num_variables; ++i) {
849 const auto& var_proto = cp_model->
variables(i);
850 const int64_t lb = var_proto.
domain(0);
851 const int64_t ub = var_proto.domain(var_proto.domain_size() - 1);
852 if (lb == 0 && ub == 0)
continue;
863 const double average_magnitude =
865 SOLVER_LOG(logger,
"Objective magnitude in [", min_magnitude,
", ",
866 max_magnitude,
"] average = ", average_magnitude);
871 if (scaling_factor == 0.0) {
872 LOG(
ERROR) <<
"Scaling factor of zero while scaling objective! This "
873 "likely indicate an infinite coefficient in the objective.";
882 double x =
std::min(scaling_factor, 1.0);
883 double relative_coeff_error;
884 double scaled_sum_error;
885 for (; x <= scaling_factor; x *= 2) {
887 &relative_coeff_error, &scaled_sum_error);
888 if (scaled_sum_error < kWantedPrecision * x)
break;
894 const double integer_factor = FindFractionalScaling(
coefficients, 1e-8);
895 if (integer_factor != 0 && integer_factor < scaling_factor) {
897 &relative_coeff_error, &scaled_sum_error);
898 if (scaled_sum_error < kWantedPrecision * integer_factor) {
899 scaling_factor = integer_factor;
908 logger,
"Objective coefficient relative error: ", relative_coeff_error,
911 SOLVER_LOG(logger,
"Objective worst-case absolute error: ",
912 scaled_sum_error / scaling_factor);
913 SOLVER_LOG(logger,
"Objective scaling factor: ", scaling_factor / gcd);
919 const int mult = mp_model.
maximize() ? -1 : 1;
922 objective->set_scaling_factor(1.0 / scaling_factor * gcd * mult);
924 const int64_t
value =
925 static_cast<int64_t
>(std::round(
coefficients[i] * scaling_factor)) /
929 objective->add_coeffs(
value * mult);
939 CHECK(problem !=
nullptr);
947 for (
int var_id(0); var_id < num_variables; ++var_id) {
958 if (lb <= -1.0) is_binary =
false;
959 if (ub >= 2.0) is_binary =
false;
962 if (lb <= 0.0 && ub >= 1.0) {
964 }
else if (lb <= 1.0 && ub >= 1.0) {
971 }
else if (lb <= 0.0 && ub >= 0.0) {
986 LOG(
WARNING) <<
"The variable #" << var_id <<
" with name "
987 << mp_var.
name() <<
" is not binary. "
988 <<
"lb: " << lb <<
" ub: " << ub;
995 double max_relative_error = 0.0;
996 double max_bound_error = 0.0;
998 double relative_error = 0.0;
999 double scaling_factor = 0.0;
1005 constraint->
set_name(mp_constraint.name());
1009 const int num_coeffs = mp_constraint.coefficient_size();
1010 for (
int i = 0; i < num_coeffs; ++i) {
1017 max_relative_error =
std::max(relative_error, max_relative_error);
1020 double bound_error = 0.0;
1021 for (
int i = 0; i < num_coeffs; ++i) {
1022 const double scaled_value = mp_constraint.coefficient(i) * scaling_factor;
1023 bound_error += std::abs(round(scaled_value) - scaled_value);
1024 const int64_t
value =
static_cast<int64_t
>(round(scaled_value)) / gcd;
1026 constraint->
add_literals(mp_constraint.var_index(i) + 1);
1030 max_bound_error =
std::max(max_bound_error, bound_error);
1037 const Fractional lb = mp_constraint.lower_bound();
1039 if (lb * scaling_factor >
static_cast<double>(kInt64Max)) {
1040 LOG(
WARNING) <<
"A constraint is trivially unsatisfiable.";
1043 if (lb * scaling_factor > -
static_cast<double>(kInt64Max)) {
1046 static_cast<int64_t
>(round(lb * scaling_factor - bound_error)) /
1050 const Fractional ub = mp_constraint.upper_bound();
1052 if (ub * scaling_factor < -
static_cast<double>(kInt64Max)) {
1053 LOG(
WARNING) <<
"A constraint is trivially unsatisfiable.";
1056 if (ub * scaling_factor <
static_cast<double>(kInt64Max)) {
1059 static_cast<int64_t
>(round(ub * scaling_factor + bound_error)) /
1066 LOG(
INFO) <<
"Maximum constraint relative error: " << max_relative_error;
1067 LOG(
INFO) <<
"Maximum constraint bound error: " << max_bound_error;
1072 for (
int var_id = 0; var_id < num_variables; ++var_id) {
1079 max_relative_error =
std::max(relative_error, max_relative_error);
1082 LOG(
INFO) <<
"objective relative error: " << relative_error;
1083 LOG(
INFO) <<
"objective scaling factor: " << scaling_factor / gcd;
1091 for (
int var_id = 0; var_id < num_variables; ++var_id) {
1093 const int64_t
value =
1094 static_cast<int64_t
>(
1107 const double kRelativeTolerance = 1e-8;
1108 if (max_relative_error > kRelativeTolerance) {
1109 LOG(
WARNING) <<
"The relative error during double -> int64_t conversion "
1137 for (
int i = 0; i < constraint.literals_size(); ++i) {
1138 const int literal = constraint.literals(i);
1139 const double coeff = constraint.coefficients(i);
1140 const ColIndex variable_index = ColIndex(abs(
literal) - 1);
1150 constraint.has_lower_bound() ? constraint.lower_bound() - sum
1152 constraint.has_upper_bound() ? constraint.upper_bound() - sum
1163 const double coeff =
1164 static_cast<double>(objective.
coefficients(i)) * scaling_factor;
1165 const ColIndex variable_index = ColIndex(abs(
literal) - 1);
1181 int num_fixed_variables = 0;
1183 for (
int i = 0; i < trail.
Index(); ++i) {
1184 const BooleanVariable
var = trail[i].Variable();
1185 const int value = trail[i].IsPositive() ? 1.0 : 0.0;
1187 ++num_fixed_variables;
1191 return num_fixed_variables;
1196 double max_time_in_seconds) {
1223 int num_variable_fixed = 0;
1227 if (
value > 1 - tolerance) {
1228 ++num_variable_fixed;
1234 }
else if (
value < tolerance) {
1235 ++num_variable_fixed;
1243 LOG(
INFO) <<
"LNS with " << num_variable_fixed <<
" fixed variables.";
#define LOG_IF(severity, condition)
#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)
::PROTOBUF_NAMESPACE_ID::int32 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
double lower_bound() const
void set_max_time_in_seconds(double value)
const DenseRow & variable_values() 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)
void SetObjectiveCoefficient(ColIndex col, Fractional value)
ColIndex num_variables() const
RowIndex CreateNewConstraint()
void SetMaximizationProblem(bool maximize)
::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int32 > * mutable_literals()
void add_literals(::PROTOBUF_NAMESPACE_ID::int32 value)
void set_name(ArgT0 &&arg0, ArgT... args)
::operations_research::sat::BoolArgumentProto * mutable_bool_and()
void add_enforcement_literal(::PROTOBUF_NAMESPACE_ID::int32 value)
::operations_research::sat::BoolArgumentProto * mutable_bool_or()
const ::operations_research::sat::IntegerVariableProto & variables(int index) const
void set_name(ArgT0 &&arg0, ArgT... args)
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final
::operations_research::sat::ConstraintProto * add_constraints()
::operations_research::sat::IntegerVariableProto * add_variables()
::operations_research::sat::CpObjectiveProto * mutable_objective()
void add_domain(::PROTOBUF_NAMESPACE_ID::int64 value)
void set_name(ArgT0 &&arg0, ArgT... args)
::PROTOBUF_NAMESPACE_ID::int64 domain(int index) const
void add_coefficients(::PROTOBUF_NAMESPACE_ID::int64 value)
void set_upper_bound(::PROTOBUF_NAMESPACE_ID::int64 value)
void set_name(ArgT0 &&arg0, ArgT... args)
void set_lower_bound(::PROTOBUF_NAMESPACE_ID::int64 value)
void add_literals(::PROTOBUF_NAMESPACE_ID::int32 value)
::operations_research::sat::LinearBooleanConstraint * add_constraints()
void set_name(ArgT0 &&arg0, ArgT... args)
int var_names_size() const
void set_num_variables(::PROTOBUF_NAMESPACE_ID::int32 value)
const ::operations_research::sat::LinearObjective & objective() const
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final
std::string * add_var_names()
::PROTOBUF_NAMESPACE_ID::int32 num_variables() const
const ::operations_research::sat::LinearBooleanConstraint & constraints(int index) const
const std::string & var_names(int index) const
::operations_research::sat::LinearObjective * mutable_objective()
void add_coefficients(::PROTOBUF_NAMESPACE_ID::int64 value)
::PROTOBUF_NAMESPACE_ID::int64 coefficients(int index) const
int literals_size() const
void add_literals(::PROTOBUF_NAMESPACE_ID::int32 value)
double scaling_factor() const
void set_offset(double value)
::PROTOBUF_NAMESPACE_ID::int32 literals(int index) const
void set_scaling_factor(double value)
double mip_check_precision() const
double mip_wanted_precision() const
::PROTOBUF_NAMESPACE_ID::int32 mip_max_activity_exponent() const
double mip_max_bound() const
const Trail & LiteralTrail() const
void SetAssignmentPreference(Literal literal, double weight)
const AssignmentInfo & Info(BooleanVariable var) const
IntegerValue FloorRatio(IntegerValue dividend, IntegerValue positive_divisor)
bool SolveLpAndUseSolutionForSatAssignmentPreference(const glop::LinearProgram &lp, SatSolver *sat_solver, double max_time_in_seconds)
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 SolveLpAndUseIntegerVariableToStartLNS(const glop::LinearProgram &lp, LinearBooleanProblem *problem)
void ChangeOptimizationDirection(LinearBooleanProblem *problem)
int FixVariablesFromSat(const SatSolver &solver, glop::LinearProgram *lp)
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,...)