14 #ifndef OR_TOOLS_SAT_CUTS_H_
15 #define OR_TOOLS_SAT_CUTS_H_
24 #include "absl/container/flat_hash_map.h"
25 #include "absl/container/flat_hash_set.h"
26 #include "absl/strings/str_cat.h"
27 #include "absl/types/span.h"
50 std::vector<IntegerVariable>
vars;
77 IntegerValue
coeff = IntegerValue(0);
98 const std::vector<double>& lp_values,
102 bool AppendOneTerm(IntegerVariable
var, IntegerValue coeff,
double lp_value,
103 IntegerValue lb, IntegerValue ub);
129 void RegisterAllBooleansTerms(
const CutData& cut);
132 bool constraint_is_indexed_ =
false;
133 absl::flat_hash_map<IntegerVariable, int> direct_index_;
134 absl::flat_hash_map<IntegerVariable, int> complemented_index_;
135 absl::btree_map<IntegerVariable, IntegerValue> tmp_map_;
151 : lp_vars_(lp_vars_.begin(), lp_vars_.
end()),
152 integer_trail_(integer_trail),
153 implied_bounds_(implied_bounds) {}
200 BestImpliedBoundInfo ComputeBestImpliedBound(
204 absl::flat_hash_set<IntegerVariable> lp_vars_;
205 mutable absl::flat_hash_map<IntegerVariable, BestImpliedBoundInfo> cache_;
290 return absl::StrCat(
" slack=", slack_.value(),
" #in=", num_in_ignored_,
291 "|", num_in_flow_,
"|", num_in_bin_,
292 " #out:", num_out_capa_,
"|", num_out_flow_,
"|",
299 bool ComputeFlowCoverRelaxation(
306 bool TryXminusLB(IntegerVariable
var,
double lp_value, IntegerValue lb,
307 IntegerValue ub, IntegerValue coeff,
310 bool TryUBminusX(IntegerVariable
var,
double lp_value, IntegerValue lb,
311 IntegerValue ub, IntegerValue coeff,
360 IntegerValue
GetFactorT(IntegerValue rhs_remainder, IntegerValue divisor,
361 IntegerValue max_magnitude);
363 IntegerValue rhs_remainder, IntegerValue divisor, IntegerValue t,
364 IntegerValue max_scaling);
414 std::string
Info()
const {
return absl::StrCat(
"ib_lift=", num_ib_used_); }
417 bool HasComplementedImpliedBound(
const CutTerm& entry,
420 double GetScaledViolation(IntegerValue divisor, IntegerValue max_scaling,
421 IntegerValue remainder_threshold,
425 std::vector<IntegerValue> divisors_;
426 std::vector<IntegerValue> remainders_;
427 std::vector<IntegerValue> rs_;
428 std::vector<IntegerValue> best_rs_;
430 int64_t num_ib_used_ = 0;
435 std::vector<std::pair<int, IntegerValue>> adjusted_coeffs_;
436 std::vector<std::pair<int, IntegerValue>> best_adjusted_coeffs_;
440 int64_t total_num_dominating_f_ = 0;
441 int64_t total_num_pos_lifts_ = 0;
442 int64_t total_num_neg_lifts_ = 0;
443 int64_t total_num_post_complements_ = 0;
444 int64_t total_num_overflow_abort_ = 0;
445 int64_t total_num_coeff_adjust_ = 0;
446 int64_t total_num_merges_ = 0;
447 int64_t total_num_bumps_ = 0;
448 int64_t total_num_final_complements_ = 0;
450 int64_t total_num_initial_ibs_ = 0;
451 int64_t total_num_initial_merges_ = 0;
504 std::string
Info()
const {
return absl::StrCat(
"lift=", num_lifting_); }
511 int GetCoverSize(
int relevant_size, IntegerValue* rhs);
520 int64_t num_lifting_ = 0;
522 int64_t total_num_lifting_ = 0;
523 int64_t total_num_ibs_ = 0;
524 int64_t total_num_overflow_abort_ = 0;
534 int linearization_level,
543 AffineExpression square,
545 IntegerValue x_ub, Model*
model);
553 AffineExpression square,
554 IntegerValue x_value,
560 int linearization_level, Model*
model);
569 const std::vector<AffineExpression>& exprs, Model*
model);
609 IntegerVariable target,
const std::vector<LinearExpression>& exprs,
610 const std::vector<IntegerVariable>& z_vars, Model*
model);
616 const LinearExpression& target, IntegerVariable
var,
617 const std::vector<std::pair<IntegerValue, IntegerValue>>& affines,
618 Model*
model, LinearConstraintBuilder* builder);
625 LinearExpression target, IntegerVariable
var,
626 std::vector<std::pair<IntegerValue, IntegerValue>> affines,
627 std::string cut_name, Model*
model);
633 const std::vector<IntegerVariable>& base_variables, Model*
model);
646 int size()
const {
return expr_mins_.size(); }
649 absl::btree_set<IntegerValue> min_values_;
650 std::vector<IntegerValue> expr_mins_;
const LinearConstraint & cut() const
bool TrySimpleKnapsack(const CutData &input, ImpliedBoundsProcessor *ib_processor=nullptr)
bool TryWithLetchfordSouliLifting(const CutData &input, ImpliedBoundsProcessor *ib_processor=nullptr)
void SetSharedStatistics(SharedStatistics *stats)
bool MakeAllTermsPositive(CutData *cut)
bool ConvertToLinearConstraint(const CutData &cut, LinearConstraint *output)
void AddOrMergeTerm(const CutTerm &term, IntegerValue t, CutData *cut)
int NumMergesSinceLastClear() const
const LinearConstraint & cut() const
bool ComputeFlowCoverRelaxationAndGenerateCut(const LinearConstraint &base_ct, const absl::StrongVector< IntegerVariable, double > &lp_values, IntegerTrail *integer_trail, ImpliedBoundsProcessor *ib_helper)
bool GenerateCut(const SingleNodeFlow &data)
void AddLpVariable(IntegerVariable var)
BestImpliedBoundInfo GetCachedImpliedBoundInfo(IntegerVariable var) const
bool TryToExpandWithLowerImpliedbound(IntegerValue factor_t, int i, bool complement, CutData *cut, CutDataBuilder *builder)
void RecomputeCacheAndSeparateSomeImpliedBoundCuts(const absl::StrongVector< IntegerVariable, double > &lp_values)
ImpliedBoundsProcessor(absl::Span< const IntegerVariable > lp_vars_, IntegerTrail *integer_trail, ImpliedBounds *implied_bounds)
const LinearConstraint & cut() const
void SetSharedStatistics(SharedStatistics *stats)
bool ComputeCut(RoundingOptions options, const CutData &base_ct, ImpliedBoundsProcessor *ib_processor=nullptr)
~IntegerRoundingCutHelper()
IntegerValue SumOfMinDomainValues()
IntegerValue GetBestLowerBound(std::string &suffix)
IntegerValue SumOfDifferentMins()
void Add(const AffineExpression &expr, int num_expr, const IntegerTrail &integer_trail)
LinearConstraint ComputeHyperplanBelowSquare(AffineExpression x, AffineExpression square, IntegerValue x_value, Model *model)
CutGenerator CreateAllDifferentCutGenerator(const std::vector< AffineExpression > &exprs, Model *model)
const IntegerVariable kNoIntegerVariable(-1)
CutGenerator CreateMaxAffineCutGenerator(LinearExpression target, IntegerVariable var, std::vector< std::pair< IntegerValue, IntegerValue >> affines, const std::string cut_name, Model *model)
CutGenerator CreateLinMaxCutGenerator(const IntegerVariable target, const std::vector< LinearExpression > &exprs, const std::vector< IntegerVariable > &z_vars, Model *model)
CutGenerator CreatePositiveMultiplicationCutGenerator(AffineExpression z, AffineExpression x, AffineExpression y, int linearization_level, Model *model)
bool BuildMaxAffineUpConstraint(const LinearExpression &target, IntegerVariable var, const std::vector< std::pair< IntegerValue, IntegerValue >> &affines, Model *model, LinearConstraintBuilder *builder)
IntegerValue GetFactorT(IntegerValue rhs_remainder, IntegerValue divisor, IntegerValue max_magnitude)
std::function< IntegerValue(IntegerValue)> GetSuperAdditiveRoundingFunction(IntegerValue rhs_remainder, IntegerValue divisor, IntegerValue t, IntegerValue max_scaling)
CutGenerator CreateSquareCutGenerator(AffineExpression y, AffineExpression x, int linearization_level, Model *model)
LinearConstraint ComputeHyperplanAboveSquare(AffineExpression x, AffineExpression square, IntegerValue x_lb, IntegerValue x_ub, Model *model)
CutGenerator CreateCliqueCutGenerator(const std::vector< IntegerVariable > &base_variables, Model *model)
double ToDouble(IntegerValue value)
Collection of objects used to extend the Constraint Solver library.
static int input(yyscan_t yyscanner)
std::vector< double > lower_bounds
std::vector< double > upper_bounds
std::optional< int64_t > end
std::vector< CutTerm > terms
IntegerValue max_magnitude
bool FillFromLinearConstraint(const LinearConstraint &base_ct, const absl::StrongVector< IntegerVariable, double > &lp_values, IntegerTrail *integer_trail)
bool FillFromParallelVectors(const LinearConstraint &base_ct, const std::vector< double > &lp_values, const std::vector< IntegerValue > &lower_bounds, const std::vector< IntegerValue > &upper_bounds)
bool AppendOneTerm(IntegerVariable var, IntegerValue coeff, double lp_value, IntegerValue lb, IntegerValue ub)
bool only_run_at_level_zero
std::vector< IntegerVariable > vars
std::function< bool(const absl::StrongVector< IntegerVariable, double > &lp_values, LinearConstraintManager *manager)> generate_cuts
double LpDistToMaxValue() const
bool HasRelevantLpValue() const
std::string DebugString() const
std::array< IntegerVariable, 2 > expr_vars
bool Complement(IntegerValue *rhs)
std::array< IntegerValue, 2 > expr_coeffs
AffineExpression flow_expr
AffineExpression bool_expr
IntegerValue implied_bound
std::string DebugString() const
double SlackLpValue(IntegerValue lb) const
bool use_ib_before_heuristic
std::vector< FlowInfo > out_flow
std::vector< FlowInfo > in_flow
std::string DebugString() const