22#include "absl/log/check.h"
23#include "absl/status/status.h"
24#include "absl/status/statusor.h"
25#include "absl/types/span.h"
40absl::Status ValidateFullFiniteSolution(
const Model& model,
42 for (
const auto& [v, value] :
solution) {
44 if (!std::isfinite(value)) {
46 <<
"the solution contains non-finite value " << value
47 <<
" for variable " << v;
50 for (
const Variable v : model.SortedVariables()) {
53 <<
"the solution does not contain a value for variable " << v;
56 return absl::OkStatus();
66 CHECK_EQ(c_bexpr.expression.offset(), 0.0);
68 return c_bexpr.expression.Evaluate(
solution);
71absl::Status ValidateOptions(
73 if (!std::isfinite(options.integrality_tolerance) ||
74 options.integrality_tolerance < 0.0 ||
77 <<
"integrality_tolerance = "
78 << RoundTripDoubleFormat(options.integrality_tolerance)
82 return absl::OkStatus();
89 absl::Span<const Variable> variables,
102 "MoveVariablesToTheirBestFeasibleValue"));
104 for (
const Variable v : variables) {
106 <<
"invalid `variables`";
107 if (v.lower_bound() > v.upper_bound()) {
109 <<
"variable " << v <<
" bounds ["
112 <<
"] integer: " << std::boolalpha << v.is_integer()
118 <<
"integer variable " << v <<
" has bounds ["
121 <<
"] that contain no integer value";
125 <<
"invalid `input_solution`";
139 constraint_values.try_emplace(
c, ConstraintValue(
c, new_solution));
141 for (
const Variable v : variables) {
145 if (obj_coeff == 0.0)
continue;
147 const double v_current_value = new_solution.at(v);
154 const bool positive_v_change = model.
is_maximize() == (obj_coeff > 0.0);
158 double best_v_bound =
168 bool some_constraints_are_limiting =
false;
170 const double c_coeff =
c.coefficient(v);
172 CHECK(std::isfinite(c_coeff)) << v <<
": " << c_coeff;
175 if (c_coeff == 0.0)
continue;
179 const bool use_constraint_upper_bound =
180 (c_coeff >= 0.0) == positive_v_change;
183 const double used_bound =
184 use_constraint_upper_bound ?
c.upper_bound() :
c.lower_bound();
185 if (!std::isfinite(used_bound))
continue;
188 some_constraints_are_limiting =
true;
191 const double c_v_bound = [&]() {
192 const double c_value = constraint_values.at(
c);
200 if (!std::isfinite(c_value))
return v_current_value;
208 if ((c_value >= used_bound) == use_constraint_upper_bound) {
209 return v_current_value;
212 return v_current_value + ((used_bound - c_value) / c_coeff);
216 if (positive_v_change) {
217 best_v_bound = std::fmin(best_v_bound, c_v_bound);
219 best_v_bound = std::fmax(best_v_bound, c_v_bound);
223 if (!std::isfinite(best_v_bound)) {
224 if (some_constraints_are_limiting) {
236 <<
"the model is unbounded regarding variable " << v;
239 const double v_improved_value = [&]() {
240 if (!v.is_integer()) {
247 return positive_v_change ? std::floor(best_v_bound)
248 : std::ceil(best_v_bound);
252 if (positive_v_change ? v_improved_value <= v_current_value
253 : v_improved_value >= v_current_value)
259 new_solution.at(v) = v_improved_value;
267 constraint_values.at(
c) = ConstraintValue(
c, new_solution);
#define RETURN_IF_ERROR(expr)
ModelProto ExportModel(bool remove_names=false) const
std::vector< LinearConstraint > ColumnNonzeros(Variable variable) const
std::vector< LinearConstraint > LinearConstraints() const
double objective_coefficient(Variable variable) const
Returns 0.0 if this variable has no linear objective coefficient.
absl::Status ValidateExistingVariableOfThisModel(Variable variable) const
-----------------------— Linear constraints ----------------------------—
An object oriented wrapper for quadratic constraints in ModelStorage.
absl::Status ModelIsSupported(const ModelProto &model, const SupportedProblemStructures &support_menu, const absl::string_view solver_name)
absl::flat_hash_map< Variable, V > VariableMap
absl::flat_hash_map< LinearConstraint, V > LinearConstraintMap
double RoundedLowerBound(const Variable v, const double tolerance)
double RoundedUpperBound(const Variable v, const double tolerance)
Same as RoundedLowerBound() but for upper-bound.
constexpr double kMaxIntegralityTolerance
absl::StatusOr< ModelSummary > ValidateModel(const ModelProto &model, const bool check_names)
absl::StatusOr< VariableMap< double > > MoveVariablesToTheirBestFeasibleValue(const Model &model, const VariableMap< double > &input_solution, absl::Span< const Variable > variables, const MoveVariablesToTheirBestFeasibleValueOptions &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
StatusBuilder InvalidArgumentErrorBuilder()
StatusBuilder FailedPreconditionErrorBuilder()
A LinearExpression with upper and lower bounds.
Options for MoveVariablesToTheirBestFeasibleValue.
double integrality_tolerance