27 VLOG(1) << num_deductions_ <<
" enqueued deductions.";
28 VLOG(1) << bounds_.size() <<
" implied bounds stored.";
29 VLOG(1) << num_enqueued_in_var_to_bounds_
30 <<
" implied bounds with view stored.";
35 const IntegerVariable
var = integer_literal.
var;
38 if (
var >= level_zero_lower_bounds_.
size()) {
47 if (integer_literal.
bound <= level_zero_lower_bounds_[
var]) {
61 const auto key = std::make_pair(
literal.Index(),
var);
62 auto insert_result = bounds_.insert({key, integer_literal.
bound});
63 if (!insert_result.second) {
64 if (insert_result.first->second < integer_literal.
bound) {
65 insert_result.first->second = integer_literal.
bound;
78 if (it != bounds_.end() && it->second == -integer_literal.
bound) {
90 const auto it = bounds_.find(std::make_pair(
literal.NegatedIndex(),
var));
91 if (it != bounds_.end()) {
92 if (it->second <= level_zero_lower_bounds_[
var]) {
97 const IntegerValue deduction =
107 level_zero_lower_bounds_[
var] = deduction;
108 new_level_zero_bounds_.
Set(
var);
110 VLOG(1) <<
"Deduction old: "
117 if (it->second == deduction) {
120 if (integer_literal.
bound == deduction) {
121 bounds_.erase(std::make_pair(
literal.Index(),
var));
143 if (var_to_bounds_.size() <=
var) {
144 var_to_bounds_.resize(
var.value() + 1);
147 ++num_enqueued_in_var_to_bounds_;
148 has_implied_bounds_.
Set(
var);
150 integer_literal.
bound,
true});
153 if (var_to_bounds_.size() <=
var) {
154 var_to_bounds_.resize(
var.value() + 1);
157 ++num_enqueued_in_var_to_bounds_;
158 has_implied_bounds_.
Set(
var);
159 var_to_bounds_[
var].push_back(
161 integer_literal.
bound,
false});
166 IntegerVariable
var) {
167 if (
var >= var_to_bounds_.size())
return empty_implied_bounds_;
174 std::vector<ImpliedBoundEntry>& ref = var_to_bounds_[
var];
175 const IntegerValue level_zero_lb =
std::max(
177 level_zero_lower_bounds_[
var] = level_zero_lb;
179 if (entry.lower_bound <= level_zero_lb)
continue;
180 ref[new_size++] = entry;
189 IntegerValue
value) {
201 tmp_integer_literals_.clear();
204 Add(first_decision, lit);
209 IntegerVariable
var,
const std::vector<ValueLiteralPair>& encoding,
210 int exactly_one_index) {
211 var_to_index_to_element_encodings_[
var][exactly_one_index] = encoding;
214const absl::flat_hash_map<int, std::vector<ValueLiteralPair>>&
216 const auto& it = var_to_index_to_element_encodings_.find(
var);
217 if (it == var_to_index_to_element_encodings_.end()) {
218 return empty_element_encoding_;
226 return element_encoded_variables_;
231 for (
const IntegerVariable
var :
243std::string
EncodingStr(
const std::vector<ValueLiteralPair>& enc) {
246 absl::StrAppend(&result, term.literal.DebugString(),
":",
247 term.value.value(),
" ");
269 const std::vector<ValueLiteralPair>& affine_var_encoding,
Model*
model,
272 IntegerVariable binary = size2_affine.
var;
274 const std::vector<ValueLiteralPair>& size2_enc =
277 Literal lit0 = size2_enc[0].literal;
278 IntegerValue value0 =
279 size2_enc[0].value * size2_affine.
coeff + size2_affine.
constant;
280 Literal lit1 = size2_enc[1].literal;
281 IntegerValue value1 =
282 size2_enc[1].value * size2_affine.
coeff + size2_affine.
constant;
283 for (
const auto& [unused, candidate_literal] : affine_var_encoding) {
284 if (candidate_literal == lit1) {
288 if (candidate_literal != lit0)
continue;
292 for (
const auto& [
value,
literal] : affine_var_encoding) {
302 for (
const auto& [
value,
literal] : affine_var_encoding) {
306 if (
energy > min_energy) {
323 CHECK(builder !=
nullptr);
329 if (integer_trail->
IsFixed(left)) {
335 if (integer_trail->
IsFixed(right)) {
346 const IntegerValue left_coeff =
348 const IntegerValue right_coeff =
351 left_coeff * right_coeff + left.
constant * right_coeff +
358 const absl::flat_hash_map<int, std::vector<ValueLiteralPair>>&
359 left_encodings = implied_bounds->GetElementEncodings(left.
var);
362 const absl::flat_hash_map<int, std::vector<ValueLiteralPair>>&
363 right_encodings = implied_bounds->GetElementEncodings(right.
var);
365 std::vector<int> compatible_keys;
366 for (
const auto& [
index, encoding] : left_encodings) {
367 if (right_encodings.contains(
index)) {
368 compatible_keys.push_back(
index);
372 if (compatible_keys.empty()) {
374 for (
const auto& [
index, right_encoding] : right_encodings) {
382 for (
const auto& [
index, left_encoding] : left_encodings) {
392 if (compatible_keys.size() > 1) {
393 VLOG(1) <<
"More than one exactly_one involved in the encoding of the two "
398 const int min_index =
399 *std::min_element(compatible_keys.begin(), compatible_keys.end());
402 const std::vector<ValueLiteralPair>& left_encoding =
403 left_encodings.at(min_index);
404 const std::vector<ValueLiteralPair>& right_encoding =
405 right_encodings.at(min_index);
406 DCHECK_EQ(left_encoding.size(), right_encoding.size());
410 for (
int i = 0; i < left_encoding.size(); ++i) {
417 for (
int i = 0; i < left_encoding.size(); ++i) {
420 if (
energy == min_energy)
continue;
422 const Literal lit = left_encoding[i].literal;
440 return !expr.
vars.empty() ||
445 const std::vector<AffineExpression>& right,
447 std::vector<LinearExpression>* energies) {
449 for (
int i = 0; i < left.size(); ++i) {
452 VLOG(3) <<
"linearized energy: "
456 VLOG(2) <<
"Product is not linearizable: demands "
457 << left[i].DebugString() <<
" with var domain "
458 << integer_trail->InitialVariableDomain(left[i].
var)
459 <<
", size = " << right[i].DebugString() <<
" with var domain "
460 << integer_trail->InitialVariableDomain(right[i].
var);
#define CHECK_EQ(val1, val2)
#define DCHECK_GT(val1, val2)
#define DCHECK_EQ(val1, val2)
#define VLOG(verboselevel)
void resize(size_type new_size)
int64_t Size() const
Returns the number of elements in the domain.
void Set(IntegerType index)
const std::vector< IntegerType > & PositionsSetAtLeastOnce() const
void Resize(IntegerType size)
bool EnqueueNewDeductions()
const std::vector< ImpliedBoundEntry > & GetImpliedBounds(IntegerVariable var)
void AddLiteralImpliesVarEqValue(Literal literal, IntegerVariable var, IntegerValue value)
const absl::flat_hash_map< int, std::vector< ValueLiteralPair > > & GetElementEncodings(IntegerVariable var)
void Add(Literal literal, IntegerLiteral integer_literal)
void AddElementEncoding(IntegerVariable var, const std::vector< ValueLiteralPair > &encoding, int exactly_one_index)
const std::vector< IntegerVariable > & GetElementEncodedVariables() const
void ProcessIntegerTrail(Literal first_decision)
const IntegerVariable GetLiteralView(Literal lit) const
std::vector< ValueLiteralPair > FullDomainEncoding(IntegerVariable var) const
bool VariableIsFullyEncoded(IntegerVariable var) const
ABSL_MUST_USE_RESULT bool Enqueue(IntegerLiteral i_lit, absl::Span< const Literal > literal_reason, absl::Span< const IntegerLiteral > integer_reason)
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
void AppendNewBounds(std::vector< IntegerLiteral > *output) const
IntegerValue LowerBound(IntegerVariable i) const
bool IsOptional(IntegerVariable i) const
const Domain & InitialVariableDomain(IntegerVariable var) const
ABSL_MUST_USE_RESULT bool AddLiteralTerm(Literal lit, IntegerValue coeff)
void AddConstant(IntegerValue value)
LinearExpression BuildExpression()
void AddTerm(IntegerVariable var, IntegerValue coeff)
Class that owns everything related to a particular optimization model.
bool use_implied_bounds() const
int CurrentDecisionLevel() const
void swap(IdMap< K, V > &a, IdMap< K, V > &b)
constexpr IntegerValue kMaxIntegerValue(std::numeric_limits< IntegerValue::ValueType >::max() - 1)
constexpr IntegerValue kMinIntegerValue(-kMaxIntegerValue)
void LinearizeInnerProduct(const std::vector< AffineExpression > &left, const std::vector< AffineExpression > &right, Model *model, std::vector< LinearExpression > *energies)
std::string EncodingStr(const std::vector< ValueLiteralPair > &enc)
const IntegerVariable kNoIntegerVariable(-1)
LinearExpression NotLinearizedEnergy()
IntegerVariable PositiveVariable(IntegerVariable i)
bool ProductIsLinearized(const LinearExpression &expr)
bool DetectLinearEncodingOfProducts(const AffineExpression &left, const AffineExpression &right, Model *model, LinearConstraintBuilder *builder)
std::vector< IntegerVariable > NegationOf(const std::vector< IntegerVariable > &vars)
bool TryToReconcileEncodings(const AffineExpression &size2_affine, const AffineExpression &affine, const std::vector< ValueLiteralPair > &affine_var_encoding, Model *model, LinearConstraintBuilder *builder)
bool VariableIsPositive(IntegerVariable i)
Collection of objects used to extend the Constraint Solver library.
IntegerValue ValueAt(IntegerValue var_value) const
static IntegerLiteral GreaterOrEqual(IntegerVariable i, IntegerValue bound)
std::vector< IntegerVariable > vars
std::string DebugString() const