25 #include "absl/base/attributes.h"
26 #include "absl/container/flat_hash_set.h"
27 #include "absl/strings/str_cat.h"
40 if (coeff == 0)
return;
44 terms_.push_back({
var, coeff});
52 if (coeff == 0)
return;
57 terms_.push_back({expr.
var, coeff * expr.
coeff});
72 for (
int i = 0; i < expr.
vars.size(); ++i) {
75 terms_.push_back({expr.
vars[i], expr.
coeffs[i] * coeff});
80 offset_ += expr.
offset * coeff;
84 const std::vector<LiteralValueValue>& product) {
85 if (product.empty())
return true;
90 product_min =
std::min(product_min, term.left_value * term.right_value);
94 IntegerValue coeff = term.left_value * term.right_value - product_min;
95 if (coeff == 0)
continue;
106 bool* is_quadratic) {
107 if (integer_trail->
IsFixed(left)) {
109 }
else if (integer_trail->
IsFixed(right)) {
112 const IntegerValue left_min = integer_trail->
LowerBound(left);
113 const IntegerValue right_min = integer_trail->
LowerBound(right);
118 if (is_quadratic !=
nullptr) *is_quadratic =
true;
127 Literal lit, IntegerValue coeff) {
128 DCHECK(encoder_ !=
nullptr);
130 bool view_is_direct =
true;
135 if (view_is_direct) {
168 const int size =
static_cast<int>(constraint.
vars.size());
169 const int shifted_size = size - 3;
174 for (; i < shifted_size; i += 4) {
175 a0 +=
static_cast<double>(constraint.
coeffs[i].value()) *
176 values[constraint.
vars[i]];
177 a1 +=
static_cast<double>(constraint.
coeffs[i + 1].value()) *
178 values[constraint.
vars[i + 1]];
179 a2 +=
static_cast<double>(constraint.
coeffs[i + 2].value()) *
180 values[constraint.
vars[i + 2]];
181 a3 +=
static_cast<double>(constraint.
coeffs[i + 3].value()) *
182 values[constraint.
vars[i + 3]];
184 double activity = a0 + a1 + a2 + a3;
186 activity +=
static_cast<double>(constraint.
coeffs[i].value()) *
187 values[constraint.
vars[i]];
189 activity +=
static_cast<double>(constraint.
coeffs[i + 1].value()) *
190 values[constraint.
vars[i + 1]];
192 activity +=
static_cast<double>(constraint.
coeffs[i + 2].value()) *
193 values[constraint.
vars[i + 2]];
202 for (
const IntegerValue coeff : constraint.
coeffs) {
205 return std::sqrt(sum);
209 IntegerValue result(0);
210 for (
const IntegerValue coeff : constraint.
coeffs) {
218 DCHECK(std::is_sorted(constraint1.
vars.begin(), constraint1.
vars.end()));
219 DCHECK(std::is_sorted(constraint2.
vars.begin(), constraint2.
vars.end()));
220 double scalar_product = 0.0;
223 while (index_1 < constraint1.
vars.size() &&
224 index_2 < constraint2.
vars.size()) {
225 if (constraint1.
vars[index_1] == constraint2.
vars[index_2]) {
230 }
else if (constraint1.
vars[index_1] > constraint2.
vars[index_2]) {
236 return scalar_product;
242 IntegerValue ComputeGcd(
const std::vector<IntegerValue>& values) {
243 if (values.empty())
return IntegerValue(1);
245 for (
const IntegerValue
value : values) {
249 if (gcd < 0)
return IntegerValue(1);
250 return IntegerValue(gcd);
256 if (constraint->
coeffs.empty())
return;
257 const IntegerValue gcd = ComputeGcd(constraint->
coeffs);
258 if (gcd == 1)
return;
266 for (IntegerValue& coeff : constraint->
coeffs) coeff /= gcd;
271 const int size = constraint->
vars.size();
272 for (
int i = 0; i < size; ++i) {
273 if (constraint->
coeffs[i] == 0)
continue;
274 constraint->
vars[new_size] = constraint->
vars[i];
278 constraint->
vars.resize(new_size);
279 constraint->
coeffs.resize(new_size);
283 const int size = constraint->
vars.size();
284 for (
int i = 0; i < size; ++i) {
285 const IntegerValue coeff = constraint->
coeffs[i];
287 constraint->
coeffs[i] = -coeff;
294 const int size = constraint->
vars.size();
295 for (
int i = 0; i < size; ++i) {
296 const IntegerVariable
var = constraint->
vars[i];
307 for (
int i = 0; i <
vars.size(); ++i) {
314 IntegerValue result =
offset;
315 for (
int i = 0; i <
vars.size(); ++i) {
323 IntegerValue result =
offset;
324 for (
int i = 0; i <
vars.size(); ++i) {
335 IntegerValue result =
offset;
336 for (
int i = 0; i <
vars.size(); ++i) {
347 if (
vars.empty())
return absl::StrCat(
offset.value());
349 for (
int i = 0; i <
vars.size(); ++i) {
350 absl::StrAppend(&result, i > 0 ?
" " :
"",
354 absl::StrAppend(&result,
" + ",
offset.value());
366 std::vector<std::pair<IntegerVariable, IntegerValue>> terms;
368 const int size =
ct->vars.size();
369 for (
int i = 0; i < size; ++i) {
371 terms.push_back({
ct->vars[i],
ct->coeffs[i]});
376 std::sort(terms.begin(), terms.end());
380 for (
const auto& term : terms) {
381 ct->vars.push_back(term.first);
382 ct->coeffs.push_back(term.second);
387 absl::flat_hash_set<IntegerVariable> seen_variables;
388 const int size =
ct.vars.size();
389 for (
int i = 0; i < size; ++i) {
391 if (!seen_variables.insert(
ct.vars[i]).second)
return false;
393 if (!seen_variables.insert(
NegationOf(
ct.vars[i])).second)
return false;
402 for (
int i = 0; i < expr.
vars.size(); ++i) {
407 canonical_expr.
vars.push_back(expr.
vars[i]);
411 return canonical_expr;
418 int64_t positive_sum(0);
419 int64_t negative_sum(0);
420 for (
int i = 0; i < constraint.
vars.size(); ++i) {
421 const IntegerVariable
var = constraint.
vars[i];
422 const IntegerValue coeff = constraint.
coeffs[i];
426 int64_t min_prod =
CapProd(coeff.value(), lb.value());
427 int64_t max_prod =
CapProd(coeff.value(), ub.value());
428 if (min_prod > max_prod)
std::swap(min_prod, max_prod);
430 positive_sum =
CapAdd(positive_sum,
std::max(int64_t{0}, max_prod));
431 negative_sum =
CapAdd(negative_sum,
std::min(int64_t{0}, min_prod));
435 if (positive_sum >= limit)
return false;
436 if (negative_sum <= -limit)
return false;
437 if (
CapSub(positive_sum, negative_sum) >= limit)
return false;
453 for (
int i = 0; i < expr.
vars.size(); ++i) {
455 result.
vars.push_back(expr.
vars[i]);
467 for (
int i = 0; i < expr.
vars.size(); ++i) {
474 return IntegerValue(0);
480 for (
int i = 0; i < expr.
vars.size(); ++i) {
485 return IntegerValue(0);
static int64_t GCD64(int64_t x, int64_t y)
ABSL_MUST_USE_RESULT bool LiteralOrNegationHasView(Literal lit, IntegerVariable *view=nullptr, bool *view_is_direct=nullptr) const
bool IsFixed(IntegerVariable i) const
IntegerValue UpperBound(IntegerVariable i) const
IntegerValue LevelZeroUpperBound(IntegerVariable var) const
IntegerValue FixedValue(IntegerVariable i) const
IntegerValue LevelZeroLowerBound(IntegerVariable var) const
IntegerValue LowerBound(IntegerVariable i) const
ABSL_MUST_USE_RESULT bool AddLiteralTerm(Literal lit, IntegerValue coeff=IntegerValue(1))
ABSL_MUST_USE_RESULT bool AddDecomposedProduct(const std::vector< LiteralValueValue > &product)
void AddConstant(IntegerValue value)
void AddLinearExpression(const LinearExpression &expr)
LinearConstraint BuildConstraint(IntegerValue lb, IntegerValue ub)
LinearExpression BuildExpression()
void AddTerm(IntegerVariable var, IntegerValue coeff)
void AddQuadraticLowerBound(AffineExpression left, AffineExpression right, IntegerTrail *integer_trail, bool *is_quadratic=nullptr)
void swap(IdMap< K, V > &a, IdMap< K, V > &b)
IntegerValue FloorRatio(IntegerValue dividend, IntegerValue positive_divisor)
bool ValidateLinearConstraintForOverflow(const LinearConstraint &constraint, const IntegerTrail &integer_trail)
constexpr IntegerValue kMaxIntegerValue(std::numeric_limits< IntegerValue::ValueType >::max() - 1)
IntType IntTypeAbs(IntType t)
IntegerValue CeilRatio(IntegerValue dividend, IntegerValue positive_divisor)
std::string IntegerTermDebugString(IntegerVariable var, IntegerValue coeff)
void RemoveZeroTerms(LinearConstraint *constraint)
LinearExpression PositiveVarExpr(const LinearExpression &expr)
constexpr IntegerValue kMinIntegerValue(-kMaxIntegerValue.value())
double ScalarProduct(const LinearConstraint &constraint1, const LinearConstraint &constraint2)
const IntegerVariable kNoIntegerVariable(-1)
void MakeAllCoefficientsPositive(LinearConstraint *constraint)
LinearExpression CanonicalizeExpr(const LinearExpression &expr)
void CanonicalizeConstraint(LinearConstraint *ct)
bool NoDuplicateVariable(const LinearConstraint &ct)
double ComputeL2Norm(const LinearConstraint &constraint)
IntegerValue GetCoefficient(const IntegerVariable var, const LinearExpression &expr)
void MakeAllVariablesPositive(LinearConstraint *constraint)
std::vector< IntegerVariable > NegationOf(const std::vector< IntegerVariable > &vars)
IntegerValue GetCoefficientOfPositiveVar(const IntegerVariable var, const LinearExpression &expr)
IntegerValue ComputeInfinityNorm(const LinearConstraint &constraint)
void CleanTermsAndFillConstraint(std::vector< std::pair< IntegerVariable, IntegerValue >> *terms, ClassWithVarsAndCoeffs *output)
bool VariableIsPositive(IntegerVariable i)
void DivideByGCD(LinearConstraint *constraint)
double ComputeActivity(const LinearConstraint &constraint, const absl::StrongVector< IntegerVariable, double > &values)
double ToDouble(IntegerValue value)
Collection of objects used to extend the Constraint Solver library.
int64_t CapAdd(int64_t x, int64_t y)
int64_t CapSub(int64_t x, int64_t y)
int64_t CapProd(int64_t x, int64_t y)
std::vector< IntegerValue > coeffs
std::vector< IntegerVariable > vars
IntegerValue LevelZeroMin(IntegerTrail *integer_trail) const
std::vector< IntegerValue > coeffs
IntegerValue Max(const IntegerTrail &integer_trail) const
std::vector< IntegerVariable > vars
std::string DebugString() const
double LpValue(const absl::StrongVector< IntegerVariable, double > &lp_values) const
IntegerValue Min(const IntegerTrail &integer_trail) const