Google OR-Tools v9.15
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
integer_base.h
Go to the documentation of this file.
1// Copyright 2010-2025 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14#ifndef ORTOOLS_SAT_INTEGER_BASE_H_
15#define ORTOOLS_SAT_INTEGER_BASE_H_
16
17#include <stdlib.h>
18
19#include <algorithm>
20#include <cstdint>
21#include <limits>
22#include <numeric>
23#include <ostream>
24#include <string>
25#include <utility>
26#include <vector>
27
28#include "absl/container/flat_hash_map.h"
29#include "absl/log/check.h"
30#include "absl/strings/str_cat.h"
31#include "absl/types/span.h"
38
39namespace operations_research {
40namespace sat {
41
42// Callbacks that will be called when the search goes back to level 0.
43// Callbacks should return false if the propagation fails.
44//
45// We will call this after propagation has reached a fixed point. Note however
46// that if any callbacks "propagate" something, the callbacks following it might
47// not see a state where the propagation have been called again.
48// TODO(user): maybe we should re-propagate before calling the next callback.
50 std::vector<std::function<bool()>> callbacks;
51};
52
53// Value type of an integer variable. An integer variable is always bounded
54// on both sides, and this type is also used to store the bounds [lb, ub] of the
55// range of each integer variable.
56//
57// Note that both bounds are inclusive, which allows to write many propagation
58// algorithms for just one of the bound and apply it to the negated variables to
59// get the symmetric algorithm for the other bound.
61
62// The max range of an integer variable is [kMinIntegerValue, kMaxIntegerValue].
63//
64// It is symmetric so the set of possible ranges stays the same when we take the
65// negation of a variable. Moreover, we need some IntegerValue that fall outside
66// this range on both side so that we can usually take care of integer overflow
67// by simply doing "saturated arithmetic" and if one of the bound overflow, the
68// two bounds will "cross" each others and we will get an empty range.
69constexpr IntegerValue kMaxIntegerValue(
70 std::numeric_limits<IntegerValue::ValueType>::max() - 1);
71constexpr IntegerValue kMinIntegerValue(-kMaxIntegerValue.value());
72
73inline double ToDouble(IntegerValue value) {
74 const double kInfinity = std::numeric_limits<double>::infinity();
75 if (value >= kMaxIntegerValue) return kInfinity;
76 if (value <= kMinIntegerValue) return -kInfinity;
77 return static_cast<double>(value.value());
78}
79
80template <class IntType>
81inline IntType IntTypeAbs(IntType t) {
82 return IntType(std::abs(t.value()));
83}
84
85inline IntegerValue CeilRatio(IntegerValue dividend,
86 IntegerValue positive_divisor) {
87 DCHECK_GT(positive_divisor, 0);
88 const IntegerValue result = dividend / positive_divisor;
89 const IntegerValue adjust =
90 static_cast<IntegerValue>(result * positive_divisor < dividend);
91 return result + adjust;
92}
93
94inline IntegerValue FloorRatio(IntegerValue dividend,
95 IntegerValue positive_divisor) {
96 DCHECK_GT(positive_divisor, 0);
97 const IntegerValue result = dividend / positive_divisor;
98 const IntegerValue adjust =
99 static_cast<IntegerValue>(result * positive_divisor > dividend);
100 return result - adjust;
101}
102
103// When the case positive_divisor == 1 is frequent, this is faster.
104inline IntegerValue FloorRatioWithTest(IntegerValue dividend,
105 IntegerValue positive_divisor) {
106 if (positive_divisor == 1) return dividend;
107 return FloorRatio(dividend, positive_divisor);
108}
109
110// Overflows and saturated arithmetic.
111
112inline IntegerValue CapProdI(IntegerValue a, IntegerValue b) {
113 return IntegerValue(CapProd(a.value(), b.value()));
114}
115
116inline IntegerValue CapSubI(IntegerValue a, IntegerValue b) {
117 return IntegerValue(CapSub(a.value(), b.value()));
118}
119
120inline IntegerValue CapAddI(IntegerValue a, IntegerValue b) {
121 return IntegerValue(CapAdd(a.value(), b.value()));
122}
123
124inline bool ProdOverflow(IntegerValue t, IntegerValue value) {
125 return AtMinOrMaxInt64(CapProd(t.value(), value.value()));
126}
127
128inline bool AtMinOrMaxInt64I(IntegerValue t) {
129 return AtMinOrMaxInt64(t.value());
130}
131
132// Returns dividend - FloorRatio(dividend, divisor) * divisor;
133//
134// This function is around the same speed than the computation above, but it
135// never causes integer overflow. Note also that when calling FloorRatio() then
136// PositiveRemainder(), the compiler should optimize the modulo away and just
137// reuse the one from the first integer division.
138inline IntegerValue PositiveRemainder(IntegerValue dividend,
139 IntegerValue positive_divisor) {
140 DCHECK_GT(positive_divisor, 0);
141 const IntegerValue m = dividend % positive_divisor;
142 return m < 0 ? m + positive_divisor : m;
143}
144
145inline bool AddTo(IntegerValue a, IntegerValue* result) {
146 if (AtMinOrMaxInt64I(a)) return false;
147 const IntegerValue add = CapAddI(a, *result);
148 if (AtMinOrMaxInt64I(add)) return false;
149 *result = add;
150 return true;
151}
152
153// Computes result += a * b, and return false iff there is an overflow.
154inline bool AddProductTo(IntegerValue a, IntegerValue b, IntegerValue* result) {
155 const IntegerValue prod = CapProdI(a, b);
156 if (AtMinOrMaxInt64I(prod)) return false;
157 const IntegerValue add = CapAddI(prod, *result);
158 if (AtMinOrMaxInt64I(add)) return false;
159 *result = add;
160 return true;
161}
162
163// Computes result += a * a, and return false iff there is an overflow.
164inline bool AddSquareTo(IntegerValue a, IntegerValue* result) {
165 return AddProductTo(a, a, result);
166}
167
168// Index of an IntegerVariable.
169//
170// Each time we create an IntegerVariable we also create its negation. This is
171// done like that so internally we only stores and deal with lower bound. The
172// upper bound being the lower bound of the negated variable.
174const IntegerVariable kNoIntegerVariable(-1);
175inline IntegerVariable NegationOf(IntegerVariable i) {
176 return IntegerVariable(i.value() ^ 1);
177}
178
179inline bool VariableIsPositive(IntegerVariable i) {
180 return (i.value() & 1) == 0;
181}
182
183inline IntegerVariable PositiveVariable(IntegerVariable i) {
184 return IntegerVariable(i.value() & (~1));
185}
186
187// Special type for storing only one thing for var and NegationOf(var).
188DEFINE_STRONG_INDEX_TYPE(PositiveOnlyIndex);
189inline PositiveOnlyIndex GetPositiveOnlyIndex(IntegerVariable var) {
190 return PositiveOnlyIndex(var.value() / 2);
191}
192
193inline std::string IntegerTermDebugString(IntegerVariable var,
194 IntegerValue coeff) {
195 coeff = VariableIsPositive(var) ? coeff : -coeff;
196 return absl::StrCat(coeff.value(), "*I", GetPositiveOnlyIndex(var));
197}
198
199// Returns the vector of the negated variables.
200std::vector<IntegerVariable> NegationOf(absl::Span<const IntegerVariable> vars);
201
202// The integer equivalent of a literal.
203// It represents an IntegerVariable and an upper/lower bound on it.
204//
205// Overflow: all the bounds below kMinIntegerValue and kMaxIntegerValue are
206// treated as kMinIntegerValue - 1 and kMaxIntegerValue + 1.
208 // Because IntegerLiteral should never be created at a bound less constrained
209 // than an existing IntegerVariable bound, we don't allow GreaterOrEqual() to
210 // have a bound lower than kMinIntegerValue, and LowerOrEqual() to have a
211 // bound greater than kMaxIntegerValue. The other side is not constrained
212 // to allow for a computed bound to overflow. Note that both the full initial
213 // domain and the empty domain can always be represented.
214 static IntegerLiteral GreaterOrEqual(IntegerVariable i, IntegerValue bound);
215 static IntegerLiteral LowerOrEqual(IntegerVariable i, IntegerValue bound);
216
217 // These two static integer literals represent an always true and an always
218 // false condition.
221
222 // Clients should prefer the static construction methods above.
224 IntegerLiteral(IntegerVariable v, IntegerValue b) : var(v), bound(b) {
225 DCHECK_GE(bound, kMinIntegerValue);
226 DCHECK_LE(bound, kMaxIntegerValue + 1);
227 }
228
229 bool IsValid() const { return var != kNoIntegerVariable; }
230 bool IsAlwaysTrue() const { return var == kNoIntegerVariable && bound <= 0; }
231 bool IsAlwaysFalse() const { return var == kNoIntegerVariable && bound > 0; }
232
233 // The negation of x >= bound is x <= bound - 1.
234 IntegerLiteral Negated() const;
235
237 return var == o.var && bound == o.bound;
238 }
240 return var != o.var || bound != o.bound;
241 }
242
243 std::string DebugString() const {
244 return VariableIsPositive(var)
245 ? absl::StrCat("I", var.value() / 2, ">=", bound.value())
246 : absl::StrCat("I", var.value() / 2, "<=", -bound.value());
247 }
248
249 // Note that bound should be in [kMinIntegerValue, kMaxIntegerValue + 1].
250 IntegerVariable var = kNoIntegerVariable;
251 IntegerValue bound = IntegerValue(0);
252};
253
254inline std::ostream& operator<<(std::ostream& os, IntegerLiteral i_lit) {
255 os << i_lit.DebugString();
256 return os;
257}
258
259inline std::ostream& operator<<(std::ostream& os,
260 absl::Span<const IntegerLiteral> literals) {
261 os << "[";
262 bool first = true;
263 for (const IntegerLiteral literal : literals) {
264 if (first) {
265 first = false;
266 } else {
267 os << ",";
268 }
269 os << literal.DebugString();
270 }
271 os << "]";
272 return os;
273}
274
275// Represents [coeff * variable + constant] or just a [constant].
276//
277// In some places it is useful to manipulate such expression instead of having
278// to create an extra integer variable. This is mainly used for scheduling
279// related constraints.
281 // Helper to construct an AffineExpression.
282 AffineExpression() = default;
283 AffineExpression(IntegerValue cst) // NOLINT(runtime/explicit)
284 : constant(cst) {}
285 AffineExpression(IntegerVariable v) // NOLINT(runtime/explicit)
286 : var(v), coeff(1) {}
287 AffineExpression(IntegerVariable v, IntegerValue c)
288 : var(c >= 0 ? v : NegationOf(v)), coeff(IntTypeAbs(c)) {}
289 AffineExpression(IntegerVariable v, IntegerValue c, IntegerValue cst)
290 : var(c >= 0 ? v : NegationOf(v)), coeff(IntTypeAbs(c)), constant(cst) {}
291
292 // Returns the integer literal corresponding to expression >= value or
293 // expression <= value.
294 //
295 // On constant expressions, they will return IntegerLiteral::TrueLiteral()
296 // or IntegerLiteral::FalseLiteral().
297 IntegerLiteral GreaterOrEqual(IntegerValue bound) const;
298 IntegerLiteral LowerOrEqual(IntegerValue bound) const;
299
304
305 AffineExpression MultipliedBy(IntegerValue multiplier) const {
306 // Note that this also works if multiplier is negative.
307 return AffineExpression(var, coeff * multiplier, constant * multiplier);
308 }
309
311 return var == o.var && coeff == o.coeff && constant == o.constant;
312 }
313
314 // Returns the value of this affine expression given its variable value.
315 IntegerValue ValueAt(IntegerValue var_value) const {
316 return coeff * var_value + constant;
317 }
318
319 // Returns the affine expression value under a given LP solution.
321 lp_values) const {
322 if (var == kNoIntegerVariable) return ToDouble(constant);
323 return ToDouble(coeff) * lp_values[var] + ToDouble(constant);
324 }
325
326 bool IsConstant() const { return var == kNoIntegerVariable; }
327
328 template <typename Sink>
329 friend void AbslStringify(Sink& sink, const AffineExpression& expr) {
330 if (expr.constant == 0) {
331 absl::Format(&sink, "(%v)", IntegerTermDebugString(expr.var, expr.coeff));
332 } else {
333 absl::Format(&sink, "(%v + %d)",
334 IntegerTermDebugString(expr.var, expr.coeff),
335 expr.constant.value());
336 }
337 }
338
339 // The coefficient MUST be positive. Use NegationOf(var) if needed.
340 //
341 // TODO(user): Make this private to enforce the invariant that coeff cannot be
342 // negative.
343 IntegerVariable var = kNoIntegerVariable; // kNoIntegerVariable for constant.
344 IntegerValue coeff = IntegerValue(0); // Zero for constant.
345 IntegerValue constant = IntegerValue(0);
346};
347
348template <typename H>
350 if (e.var != kNoIntegerVariable) {
351 h = H::combine(std::move(h), e.var);
352 h = H::combine(std::move(h), e.coeff);
353 }
354 h = H::combine(std::move(h), e.constant);
355
356 return h;
357}
358
359// A linear expression with at most two variables (coeffs can be zero).
360// And some utility to canonicalize them.
362 // Construct a zero expression.
363 LinearExpression2() = default;
364
365 LinearExpression2(IntegerVariable v1, IntegerVariable v2, IntegerValue c1,
366 IntegerValue c2) {
367 vars[0] = v1;
368 vars[1] = v2;
369 coeffs[0] = c1;
370 coeffs[1] = c2;
371 }
372
373 // Build (v1 - v2)
374 static LinearExpression2 Difference(IntegerVariable v1, IntegerVariable v2) {
375 return LinearExpression2(v1, v2, 1, -1);
376 }
377
378 // Take the negation of this expression.
379 void Negate() {
380 if (vars[0] != kNoIntegerVariable) {
381 vars[0] = NegationOf(vars[0]);
382 }
383 if (vars[1] != kNoIntegerVariable) {
384 vars[1] = NegationOf(vars[1]);
385 }
386 }
387
388 // This will not change any bounds on the LinearExpression2.
389 // That is we will not potentially Negate() the expression like
390 // CanonicalizeAndUpdateBounds() might do.
391 // Note that since kNoIntegerVariable=-1 and we sort the variables, if we have
392 // one zero and one non-zero we will always have the zero first.
394
395 // Fully canonicalizes the expression and updates the given bounds
396 // accordingly. This is the same as SimpleCanonicalization(), DivideByGcd()
397 // and the NegateForCanonicalization() with a proper updates of the bounds.
398 // Returns whether the expression was negated.
399 bool CanonicalizeAndUpdateBounds(IntegerValue& lb, IntegerValue& ub);
400
401 // Deduce an affine expression for the lower bound for the i-th (i=0 or 1)
402 // variable from a lower bound on the LinearExpression2. Returns `affine` so
403 // that (expr >= lb) => (expr.vars[var_index] >= affine) with the condition
404 // that expr.vars[1-var_index] >= other_var_lb.
405 AffineExpression GetAffineLowerBound(int var_index, IntegerValue expr_lb,
406 IntegerValue other_var_lb) const;
407
408 // Divides the expression by the gcd of both coefficients, and returns it.
409 // Note that we always return something >= 1 even if both coefficients are
410 // zero.
411 IntegerValue DivideByGcd();
412
413 bool IsCanonicalized() const;
414
415 // Makes sure expr and -expr have the same canonical representation by
416 // negating the expression of it is in the non-canonical form. Returns true if
417 // the expression was negated.
419
421
422 absl::Span<const IntegerVariable> non_zero_vars() const {
423 const int first = coeffs[0] == 0 ? 1 : 0;
424 const int last = coeffs[1] == 0 ? 0 : 1;
425 return absl::MakeSpan(&vars[first], last - first + 1);
426 }
427
428 absl::Span<const IntegerValue> non_zero_coeffs() const {
429 const int first = coeffs[0] == 0 ? 1 : 0;
430 const int last = coeffs[1] == 0 ? 0 : 1;
431 return absl::MakeSpan(&coeffs[first], last - first + 1);
432 }
433
434 bool operator==(const LinearExpression2& o) const {
435 return vars[0] == o.vars[0] && vars[1] == o.vars[1] &&
436 coeffs[0] == o.coeffs[0] && coeffs[1] == o.coeffs[1];
437 }
438
439 bool operator<(const LinearExpression2& o) const {
440 return std::tie(vars[0], vars[1], coeffs[0], coeffs[1]) <
441 std::tie(o.vars[0], o.vars[1], o.coeffs[0], o.coeffs[1]);
442 }
443
444 IntegerValue coeffs[2];
446
447 template <typename Sink>
448 friend void AbslStringify(Sink& sink, const LinearExpression2& expr) {
449 if (expr.coeffs[0] == 0) {
450 if (expr.coeffs[1] == 0) {
451 absl::Format(&sink, "0");
452 } else {
453 absl::Format(&sink, "%v",
454 IntegerTermDebugString(expr.vars[1], expr.coeffs[1]));
455 }
456 } else {
457 absl::Format(&sink, "%v + %v",
458 IntegerTermDebugString(expr.vars[0], expr.coeffs[0]),
459 IntegerTermDebugString(expr.vars[1], expr.coeffs[1]));
460 }
461 }
462};
463
464// Encodes (a - b <= ub) in (linear2 <= ub) format.
465// Note that the returned expression is canonicalized and divided by its GCD.
466inline std::pair<LinearExpression2, IntegerValue> EncodeDifferenceLowerThan(
467 AffineExpression a, AffineExpression b, IntegerValue ub) {
469 expr.vars[0] = a.var;
470 expr.coeffs[0] = a.coeff;
471 expr.vars[1] = b.var;
472 expr.coeffs[1] = -b.coeff;
473 IntegerValue rhs = ub + b.constant - a.constant;
474
475 // Canonicalize.
477 const IntegerValue gcd = expr.DivideByGcd();
478 rhs = FloorRatio(rhs, gcd);
479 return {std::move(expr), rhs};
480}
481
482template <typename H>
484 h = H::combine(std::move(h), e.vars[0]);
485 h = H::combine(std::move(h), e.vars[1]);
486 h = H::combine(std::move(h), e.coeffs[0]);
487 h = H::combine(std::move(h), e.coeffs[1]);
488 return h;
489}
490
491// Note that we only care about binary relation, not just simple variable bound.
494 public:
495 // Register the fact that expr \in [lb, ub] is true.
496 //
497 // If lb==kMinIntegerValue it only register that expr <= ub (and symmetrically
498 // for ub==kMaxIntegerValue).
499 //
500 // Returns for each of the bound if it was restricted (added/updated), if it
501 // was ignored because a better or equal bound was already present, or if it
502 // was rejected because it was invalid (e.g. the expression was a degenerate
503 // linear2 or the bound was a min/max value).
510 std::pair<AddResult, AddResult> Add(LinearExpression2 expr, IntegerValue lb,
511 IntegerValue ub);
512
513 // Returns the known status of expr <= bound.
514 RelationStatus GetStatus(LinearExpression2 expr, IntegerValue lb,
515 IntegerValue ub) const;
516
517 // Same as GetUpperBound() but assume the expression is already canonicalized.
518 // This is slightly faster.
519 IntegerValue UpperBoundWhenCanonicalized(LinearExpression2 expr) const;
520
521 int64_t num_bounds() const { return best_bounds_.size(); }
522
523 std::vector<std::pair<LinearExpression2, IntegerValue>>
525
526 std::vector<std::tuple<LinearExpression2, IntegerValue, IntegerValue>>
528
529 private:
530 // The best bound on the given "canonicalized" expression.
531 absl::flat_hash_map<LinearExpression2, std::pair<IntegerValue, IntegerValue>>
532 best_bounds_;
533};
534
535// A model singleton that holds the root level integer variable domains.
536// we just store a single domain for both var and its negation.
538 : public util_intops::StrongVector<PositiveOnlyIndex, Domain> {};
539
540// A model singleton used for debugging. If this is set in the model, then we
541// can check that various derived constraint do not exclude this solution (if it
542// is a known optimal solution for instance).
544 void Clear() {
545 proto_values.clear();
546 ivar_has_value.clear();
547 ivar_values.clear();
548 }
549
550 // This is the value of all proto variables.
551 // It should be of the same size of the PRESOLVED model and should correspond
552 // to a solution to the presolved model.
553 std::vector<int64_t> proto_values;
554
556
557 // This is filled from proto_values at load-time, and using the
558 // cp_model_mapping, we cache the solution of the integer variables that are
559 // mapped. Note that it is possible that not all integer variable are mapped.
560 //
561 // TODO(user): When this happen we should be able to infer the value of these
562 // derived variable in the solution. For now, we only do that for the
563 // objective variable.
566};
567
568// A value and a literal.
572 const ValueLiteralPair& b) const {
573 return a.literal < b.literal;
574 }
575 };
578 const ValueLiteralPair& b) const {
579 return (a.value < b.value) ||
580 (a.value == b.value && a.literal < b.literal);
581 }
582 };
583
584 bool operator==(const ValueLiteralPair& o) const {
585 return value == o.value && literal == o.literal;
586 }
587
588 std::string DebugString() const;
589
590 IntegerValue value = IntegerValue(0);
592};
593
594std::ostream& operator<<(std::ostream& os, const ValueLiteralPair& p);
595
596DEFINE_STRONG_INDEX_TYPE(IntervalVariable);
597const IntervalVariable kNoIntervalVariable(-1);
598
599// This functions appears in hot spot, and so it is important to inline it.
600//
601// TODO(user): Maybe introduce a CanonicalizedLinear2 class so we automatically
602// get the better function, and it documents when we have canonicalized
603// expression.
605 LinearExpression2 expr) const {
606 DCHECK_EQ(expr.DivideByGcd(), 1);
607 DCHECK(expr.IsCanonicalized());
608 const bool negated = expr.NegateForCanonicalization();
609 const auto it = best_bounds_.find(expr);
610 if (it != best_bounds_.end()) {
611 const auto [known_lb, known_ub] = it->second;
612 if (negated) {
613 return -known_lb;
614 } else {
615 return known_ub;
616 }
617 }
618 return kMaxIntegerValue;
619}
620
621// ============================================================================
622// Implementation.
623// ============================================================================
624
625inline IntegerLiteral IntegerLiteral::GreaterOrEqual(IntegerVariable i,
626 IntegerValue bound) {
629}
630
631inline IntegerLiteral IntegerLiteral::LowerOrEqual(IntegerVariable i,
632 IntegerValue bound) {
638 return IntegerLiteral(kNoIntegerVariable, IntegerValue(-1));
642 return IntegerLiteral(kNoIntegerVariable, IntegerValue(1));
644
646 // Note that bound >= kMinIntegerValue, so -bound + 1 will have the correct
647 // capped value.
648 return IntegerLiteral(
649 NegationOf(IntegerVariable(var)),
651}
652
653// var * coeff + constant >= bound.
655 IntegerValue bound) const {
657 return constant >= bound ? IntegerLiteral::TrueLiteral()
659 }
660 DCHECK_GT(coeff, 0);
662 var, coeff == 1 ? bound - constant : CeilRatio(bound - constant, coeff));
663}
664
665// var * coeff + constant <= bound.
666inline IntegerLiteral AffineExpression::LowerOrEqual(IntegerValue bound) const {
667 if (var == kNoIntegerVariable) {
669 : IntegerLiteral::FalseLiteral();
670 }
671 DCHECK_GT(coeff, 0);
673 var, coeff == 1 ? bound - constant : FloorRatio(bound - constant, coeff));
674}
675
676} // namespace sat
677} // namespace operations_research
678
679#endif // ORTOOLS_SAT_INTEGER_BASE_H_
std::pair< AddResult, AddResult > Add(LinearExpression2 expr, IntegerValue lb, IntegerValue ub)
IntegerValue UpperBoundWhenCanonicalized(LinearExpression2 expr) const
std::vector< std::tuple< LinearExpression2, IntegerValue, IntegerValue > > GetSortedNonTrivialBounds() const
std::vector< std::pair< LinearExpression2, IntegerValue > > GetSortedNonTrivialUpperBounds() const
RelationStatus GetStatus(LinearExpression2 expr, IntegerValue lb, IntegerValue ub) const
bool AddSquareTo(IntegerValue a, IntegerValue *result)
IntegerValue FloorRatio(IntegerValue dividend, IntegerValue positive_divisor)
bool AddProductTo(IntegerValue a, IntegerValue b, IntegerValue *result)
constexpr IntegerValue kMaxIntegerValue(std::numeric_limits< IntegerValue::ValueType >::max() - 1)
bool AddTo(IntegerValue a, IntegerValue *result)
IntType IntTypeAbs(IntType t)
IntegerValue CeilRatio(IntegerValue dividend, IntegerValue positive_divisor)
bool ProdOverflow(IntegerValue t, IntegerValue value)
const LiteralIndex kNoLiteralIndex(-1)
std::string IntegerTermDebugString(IntegerVariable var, IntegerValue coeff)
std::vector< IntegerVariable > NegationOf(absl::Span< const IntegerVariable > vars)
Definition integer.cc:52
constexpr IntegerValue kMinIntegerValue(-kMaxIntegerValue.value())
const IntegerVariable kNoIntegerVariable(-1)
const IntervalVariable kNoIntervalVariable(-1)
IntegerVariable PositiveVariable(IntegerVariable i)
std::ostream & operator<<(std::ostream &os, const BoolVar &var)
Definition cp_model.cc:89
IntegerValue PositiveRemainder(IntegerValue dividend, IntegerValue positive_divisor)
IntegerValue CapAddI(IntegerValue a, IntegerValue b)
H AbslHashValue(H h, const IntVar &i)
Definition cp_model.h:515
std::pair< LinearExpression2, IntegerValue > EncodeDifferenceLowerThan(AffineExpression a, AffineExpression b, IntegerValue ub)
IntegerValue FloorRatioWithTest(IntegerValue dividend, IntegerValue positive_divisor)
constexpr Fractional kInfinity
Definition lp_types.h:87
PositiveOnlyIndex GetPositiveOnlyIndex(IntegerVariable var)
bool VariableIsPositive(IntegerVariable i)
IntegerValue CapSubI(IntegerValue a, IntegerValue b)
bool AtMinOrMaxInt64I(IntegerValue t)
IntegerValue CapProdI(IntegerValue a, IntegerValue b)
double ToDouble(IntegerValue value)
OR-Tools root namespace.
bool AtMinOrMaxInt64(int64_t x)
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)
#define DEFINE_STRONG_INT64_TYPE(integer_type_name)
#define DEFINE_STRONG_INDEX_TYPE(index_type_name)
IntegerLiteral GreaterOrEqual(IntegerValue bound) const
bool operator==(AffineExpression o) const
AffineExpression MultipliedBy(IntegerValue multiplier) const
AffineExpression(IntegerVariable v, IntegerValue c, IntegerValue cst)
IntegerValue ValueAt(IntegerValue var_value) const
AffineExpression(IntegerVariable v, IntegerValue c)
double LpValue(const util_intops::StrongVector< IntegerVariable, double > &lp_values) const
friend void AbslStringify(Sink &sink, const AffineExpression &expr)
IntegerLiteral LowerOrEqual(IntegerValue bound) const
util_intops::StrongVector< IntegerVariable, bool > ivar_has_value
util_intops::StrongVector< IntegerVariable, IntegerValue > ivar_values
bool operator==(IntegerLiteral o) const
static IntegerLiteral GreaterOrEqual(IntegerVariable i, IntegerValue bound)
static IntegerLiteral LowerOrEqual(IntegerVariable i, IntegerValue bound)
IntegerLiteral(IntegerVariable v, IntegerValue b)
bool operator!=(IntegerLiteral o) const
std::vector< std::function< bool()> > callbacks
bool operator==(const LinearExpression2 &o) const
bool operator<(const LinearExpression2 &o) const
LinearExpression2(IntegerVariable v1, IntegerVariable v2, IntegerValue c1, IntegerValue c2)
absl::Span< const IntegerValue > non_zero_coeffs() const
absl::Span< const IntegerVariable > non_zero_vars() const
friend void AbslStringify(Sink &sink, const LinearExpression2 &expr)
static LinearExpression2 Difference(IntegerVariable v1, IntegerVariable v2)
AffineExpression GetAffineLowerBound(int var_index, IntegerValue expr_lb, IntegerValue other_var_lb) const
bool CanonicalizeAndUpdateBounds(IntegerValue &lb, IntegerValue &ub)
bool operator()(const ValueLiteralPair &a, const ValueLiteralPair &b) const
bool operator()(const ValueLiteralPair &a, const ValueLiteralPair &b) const
bool operator==(const ValueLiteralPair &o) const