14#ifndef OR_TOOLS_SAT_CONSTRAINT_VIOLATION_H_ 
   15#define OR_TOOLS_SAT_CONSTRAINT_VIOLATION_H_ 
   24#include "absl/container/flat_hash_map.h" 
   25#include "absl/log/check.h" 
   26#include "absl/types/span.h" 
   55  void AddLiteral(
int ct_index, 
int lit, int64_t coeff = 1);
 
   56  void AddTerm(
int ct_index, 
int var, int64_t coeff, int64_t offset = 0);
 
   57  void AddOffset(
int ct_index, int64_t offset);
 
   73      int var, int64_t delta, absl::Span<const double> weights,
 
   74      absl::Span<const int64_t> jump_deltas, absl::Span<double> jump_scores,
 
   75      std::vector<int>* constraints_with_changed_violations);
 
   79                                 absl::Span<double> var_to_score_change);
 
   87    return last_affected_variables_.PositionsSetAtLeastOnce();
 
 
  113                                int64_t delta) 
const;
 
  122                                        const Domain& var_domain) 
const;
 
  128    return 5e-9 * 
static_cast<double>(num_ops_);
 
 
  132    if (var >= columns_.size()) 
return 0.0;
 
  133    const SpanData& data = columns_[var];
 
  134    if (data.num_linear_entries == 0) 
return 0.0;
 
  135    const int i = data.start + data.num_neg_literal + data.num_pos_literal;
 
  136    const int c = ct_buffer_[
i];
 
  137    if (c != 0) 
return 0.0;
 
  138    return coeff_buffer_[data.linear_start];
 
 
  142    const SpanData& data = rows_[c];
 
  144        data.num_pos_literal + data.num_neg_literal + data.num_linear_entries;
 
  145    if (size == 0) 
return {};
 
  146    return absl::MakeSpan(&row_var_buffer_[data.start], size);
 
 
  157  struct LiteralEntry {
 
  164    int num_pos_literal = 0;
 
  165    int num_neg_literal = 0;
 
  166    int linear_start = 0;
 
  167    int num_linear_entries = 0;
 
  170  absl::Span<const int> VarToConstraints(
int var)
 const {
 
  171    if (var >= columns_.size()) 
return {};
 
  172    const SpanData& data = columns_[var];
 
  174        data.num_pos_literal + data.num_neg_literal + data.num_linear_entries;
 
  175    if (size == 0) 
return {};
 
  176    return absl::MakeSpan(&ct_buffer_[data.start], size);
 
  179  void ComputeAndCacheDistance(
int ct_index);
 
  182  void UpdateScoreOnNewlyEnforced(
int c, 
double weight,
 
  183                                  absl::Span<const int64_t> jump_deltas,
 
  184                                  absl::Span<double> jump_scores);
 
  185  void UpdateScoreOnNewlyUnenforced(
int c, 
double weight,
 
  186                                    absl::Span<const int64_t> jump_deltas,
 
  187                                    absl::Span<double> jump_scores);
 
  188  void UpdateScoreOfEnforcementIncrease(
int c, 
double score_change,
 
  189                                        absl::Span<const int64_t> jump_deltas,
 
  190                                        absl::Span<double> jump_scores);
 
  191  void UpdateScoreOnActivityChange(
int c, 
double weight, int64_t activity_delta,
 
  192                                   absl::Span<const int64_t> jump_deltas,
 
  193                                   absl::Span<double> jump_scores);
 
  196  int num_constraints_ = 0;
 
  197  std::vector<Domain> domains_;
 
  198  std::vector<int64_t> offsets_;
 
  203  bool creation_phase_ = 
true;
 
  204  std::vector<std::vector<Entry>> var_entries_;
 
  205  std::vector<std::vector<LiteralEntry>> literal_entries_;
 
  208  std::vector<SpanData> columns_;
 
  209  std::vector<int> ct_buffer_;
 
  210  std::vector<int64_t> coeff_buffer_;
 
  213  std::vector<SpanData> rows_;
 
  214  std::vector<int> row_var_buffer_;
 
  215  std::vector<int64_t> row_coeff_buffer_;
 
  221  std::vector<int64_t> row_max_variations_;
 
  224  std::vector<int> tmp_row_sizes_;
 
  225  std::vector<int> tmp_row_num_positive_literals_;
 
  226  std::vector<int> tmp_row_num_negative_literals_;
 
  227  std::vector<int> tmp_row_num_linear_entries_;
 
  230  std::vector<bool> is_violated_;
 
  231  std::vector<int64_t> activities_;
 
  232  std::vector<int64_t> distances_;
 
  233  std::vector<int> num_false_enforcement_;
 
  236  std::vector<int64_t> old_distances_;
 
  237  std::vector<int> old_num_false_enforcement_;
 
  238  std::vector<int64_t> cached_deltas_;
 
  239  std::vector<double> cached_scores_;
 
  241  SparseBitset<int> last_affected_variables_;
 
  243  mutable size_t num_ops_ = 0;
 
 
  256  virtual void PerformMove(
int var, int64_t old_value,
 
  257                           absl::Span<const int64_t> solution_with_new_value);
 
  261      int var, int64_t old_value,
 
  262      absl::Span<const int64_t> solution_with_new_value);
 
 
  315              const std::vector<bool>& ignored_constraints,
 
  316              const std::vector<ConstraintProto>& additional_constraints,
 
  329                                 absl::Span<const int64_t> new_solution);
 
  333                          absl::Span<const double> weights,
 
  334                          absl::Span<const int64_t> jump_deltas,
 
  335                          absl::Span<double> jump_scores);
 
  342    return linear_evaluator_.VariablesAffectedByLastUpdate();
 
 
  352    return cp_model_.has_objective() && c == 0;
 
 
  356    return cp_model_.has_objective()
 
  357               ? linear_evaluator_.ObjectiveCoefficient(var)
 
 
  379                                absl::Span<const double> weights, 
int var,
 
  381                                absl::Span<int64_t> mutable_solution) 
const;
 
  384    return linear_evaluator_;
 
 
  388    return &linear_evaluator_;
 
 
  398    return violated_constraints_.values();
 
 
  403    return num_violated_constraint_per_var_ignoring_objective_[var];
 
 
  410    return last_update_violation_changes_;
 
 
  415      return linear_evaluator_.ConstraintToVars(c);
 
 
  423    return var_to_constraints_[var];
 
 
  426    return constraint_to_vars_[general_c];
 
 
  431    return linear_evaluator_.DeterministicTime() + dtime_;
 
 
  435  void CompileConstraintsAndObjective(
 
  436      const std::vector<bool>& ignored_constraints,
 
  437      const std::vector<ConstraintProto>& additional_constraints);
 
  440  void BuildVarConstraintGraph();
 
  447  std::vector<std::unique_ptr<CompiledConstraint>> constraints_;
 
  448  std::vector<std::vector<int>> var_to_constraints_;
 
  449  std::vector<double> var_to_dtime_estimate_;
 
  450  std::vector<std::vector<int>> constraint_to_vars_;
 
  451  std::vector<bool> jump_value_optimal_;
 
  455  std::vector<int> num_violated_constraint_per_var_ignoring_objective_;
 
  458  std::vector<int> last_update_violation_changes_;
 
  460  mutable double dtime_ = 0;
 
 
  468class CompiledBoolXorConstraint : 
public CompiledConstraintWithProto {
 
  476      absl::Span<const int64_t> solution_with_new_value) 
override;
 
 
  541  std::vector<int64_t> values_;
 
 
  550      DCHECK_EQ(proto.
vars().size(), 1);
 
 
  558    if (
coeff != 0) result.push_back(
var);
 
 
  569template <
bool has_enforcement = true>
 
  581      : interval1_(x1), interval2_(x2) {
 
  582    if (has_enforcement) {
 
  585      enforcements_.insert(enforcements_.end(),
 
 
  605      absl::Span<const int64_t> solution_with_new_value) 
final;
 
  610  std::vector<int> enforcements_;
 
  611  const Interval interval1_;
 
  612  const Interval interval2_;
 
  615class CompiledNoOverlap2dConstraint : 
public CompiledConstraintWithProto {
 
 
  627template <
bool has_enforcement = true>
 
 
  634          y_min(y.interval().start()),
 
 
 
  646      : box1_(x1, y1), box2_(x2, y2) {
 
  647    if (has_enforcement) {
 
  650      enforcements_.insert(enforcements_.end(),
 
  653      enforcements_.insert(enforcements_.end(),
 
  656      enforcements_.insert(enforcements_.end(),
 
 
  678      absl::Span<const int64_t> solution_with_new_value) 
final;
 
  683  std::vector<int> enforcements_;
 
 
  696class CompiledReservoirConstraint : 
public CompiledConstraint {
 
  699                              std::vector<std::optional<int>> is_active,
 
  700                              std::vector<LinearExpressionProto> times,
 
  701                              std::vector<LinearExpressionProto> demands)
 
  702      : capacity_(
std::move(capacity)),
 
  703        is_active_(
std::move(is_active)),
 
  704        times_(
std::move(times)),
 
  705        demands_(
std::move(demands)) {
 
  706    const int num_events = times_.size();
 
  707    time_values_.resize(num_events, 0);
 
  708    demand_values_.resize(num_events, 0);
 
  709    InitializeDenseIndexToEvents();
 
 
  721                   absl::Span<const int64_t> solution_with_new_value) 
final {
 
  730      absl::Span<const int64_t> solution_with_new_value) 
final {
 
  731    return IncrementalViolation(var, solution_with_new_value) - 
violation_;
 
 
  738  int64_t BuildProfileAndReturnViolation(absl::Span<const int64_t> 
solution);
 
  742  int64_t IncrementalViolation(
int var, absl::Span<const int64_t> 
solution);
 
  745  void InitializeDenseIndexToEvents();
 
  746  void AppendVariablesForEvent(
int i, std::vector<int>* result) 
const;
 
  751  const std::vector<std::optional<int>> is_active_;
 
  752  const std::vector<LinearExpressionProto> times_;
 
  753  const std::vector<LinearExpressionProto> demands_;
 
  756  absl::flat_hash_map<int, int> var_to_dense_index_;
 
  762    bool operator<(
const Event& o)
 const { 
return time < o.time; }
 
  764  std::vector<Event> profile_;
 
  765  std::vector<Event> profile_delta_;
 
  769  int64_t capacity_value_;
 
  770  std::vector<int64_t> time_values_;
 
  771  std::vector<int64_t> demand_values_;
 
 
int64_t ComputeViolation(absl::Span< const int64_t > solution) override
CompiledAllDiffConstraint(const ConstraintProto &ct_proto)
--— CompiledAllDiffConstraint --—
~CompiledAllDiffConstraint() override=default
~CompiledBoolXorConstraint() override=default
CompiledBoolXorConstraint(const ConstraintProto &ct_proto)
--— CompiledBoolXorConstraint --—
int64_t ViolationDelta(int, int64_t, absl::Span< const int64_t > solution_with_new_value) override
Returns the delta if var changes from old_value to solution[var].
int64_t ComputeViolation(absl::Span< const int64_t > solution) override
CompiledConstraintWithProto(const ConstraintProto &ct_proto)
--— CompiledConstraintWithProto --—
std::vector< int > UsedVariables(const CpModelProto &model_proto) const final
This just returns the variables used by the stored ct_proto_.
~CompiledConstraintWithProto() override=default
const ConstraintProto & ct_proto() const
View of a generic (non linear) constraint for the LsEvaluator.
int64_t violation() const
The cached violation of this constraint.
virtual std::vector< int > UsedVariables(const CpModelProto &model_proto) const =0
virtual void PerformMove(int var, int64_t old_value, absl::Span< const int64_t > solution_with_new_value)
Updates the violation with the new value.
virtual int64_t ComputeViolation(absl::Span< const int64_t > solution)=0
void InitializeViolation(absl::Span< const int64_t > solution)
Recomputes the violation of the constraint from scratch.
CompiledConstraint()=default
virtual int64_t ViolationDelta(int var, int64_t old_value, absl::Span< const int64_t > solution_with_new_value)
Returns the delta if var changes from old_value to solution[var].
virtual ~CompiledConstraint()=default
~CompiledIntDivConstraint() override=default
CompiledIntDivConstraint(const ConstraintProto &ct_proto)
--— CompiledIntDivConstraint --—
int64_t ComputeViolation(absl::Span< const int64_t > solution) override
int64_t ComputeViolation(absl::Span< const int64_t > solution) override
~CompiledIntModConstraint() override=default
CompiledIntModConstraint(const ConstraintProto &ct_proto)
--— CompiledIntModConstraint --—
CompiledIntProdConstraint(const ConstraintProto &ct_proto)
--— CompiledIntProdConstraint --—
~CompiledIntProdConstraint() override=default
int64_t ComputeViolation(absl::Span< const int64_t > solution) override
int64_t ComputeViolation(absl::Span< const int64_t > solution) override
CompiledLinMaxConstraint(const ConstraintProto &ct_proto)
--— CompiledLinMaxConstraint --—
~CompiledLinMaxConstraint() override=default
int64_t ComputeViolation(absl::Span< const int64_t > solution) override
CompiledNoOverlap2dConstraint(const ConstraintProto &ct_proto, const CpModelProto &cp_model)
~CompiledNoOverlap2dConstraint() override=default
int64_t ViolationDelta(int, int64_t, absl::Span< const int64_t > solution_with_new_value) final
int64_t ComputeViolation(absl::Span< const int64_t > solution) final
~CompiledNoOverlap2dWithTwoBoxes() final=default
CompiledNoOverlap2dWithTwoBoxes(const ConstraintProto &x1, const ConstraintProto &y1, const ConstraintProto &x2, const ConstraintProto &y2)
std::vector< int > UsedVariables(const CpModelProto &model_proto) const final
int64_t ViolationDelta(int, int64_t, absl::Span< const int64_t > solution_with_new_value) final
--— CompiledNoOverlapWithTwoIntervals --—
int64_t ComputeViolation(absl::Span< const int64_t > solution) final
~CompiledNoOverlapWithTwoIntervals() final=default
CompiledNoOverlapWithTwoIntervals(const ConstraintProto &x1, const ConstraintProto &x2)
std::vector< int > UsedVariables(const CpModelProto &model_proto) const final
CompiledReservoirConstraint(LinearExpressionProto capacity, std::vector< std::optional< int > > is_active, std::vector< LinearExpressionProto > times, std::vector< LinearExpressionProto > demands)
void PerformMove(int, int64_t, absl::Span< const int64_t > solution_with_new_value) final
Updates the violation with the new value.
int64_t ComputeViolation(absl::Span< const int64_t > solution) final
int64_t ViolationDelta(int var, int64_t, absl::Span< const int64_t > solution_with_new_value) final
Returns the delta if var changes from old_value to solution[var].
std::vector< int > UsedVariables(const CpModelProto &model_proto) const final
::int32_t enforcement_literal(int index) const
::int64_t coeffs(int index) const
::int32_t vars(int index) const
void UpdateScoreOnWeightUpdate(int c, absl::Span< const int64_t > jump_deltas, absl::Span< double > var_to_score_change)
Also for feasibility jump.
void AddOffset(int ct_index, int64_t offset)
double WeightedViolationDelta(absl::Span< const double > weights, int var, int64_t delta) const
bool IsViolated(int c) const
void ComputeInitialActivities(absl::Span< const int64_t > solution)
Compute activities.
void AddLiteral(int ct_index, int lit, int64_t coeff=1)
int NewConstraint(Domain domain)
Returns the index of the new constraint.
double WeightedViolation(absl::Span< const double > weights) const
bool ReduceBounds(int c, int64_t lb, int64_t ub)
bool VarIsConsistent(int var) const
Used to DCHECK the state of the evaluator.
int64_t ObjectiveCoefficient(int var) const
int num_constraints() const
Model getters.
void ClearAffectedVariables()
int64_t Activity(int c) const
Query violation.
void UpdateVariableAndScores(int var, int64_t delta, absl::Span< const double > weights, absl::Span< const int64_t > jump_deltas, absl::Span< double > jump_scores, std::vector< int > *constraints_with_changed_violations)
double DeterministicTime() const
bool AppearsInViolatedConstraints(int var) const
absl::Span< const int > VariablesAffectedByLastUpdate() const
void AddLinearExpression(int ct_index, const LinearExpressionProto &expr, int64_t multiplier)
void PrecomputeCompactView(absl::Span< const int64_t > var_max_variation)
int64_t Violation(int c) const
absl::Span< const int > ConstraintToVars(int c) const
void AddEnforcementLiteral(int ct_index, int lit)
bool ViolationChangeIsConvex(int var) const
Checks if the jump value of a variable is always optimal.
LinearIncrementalEvaluator()=default
std::vector< int64_t > SlopeBreakpoints(int var, int64_t current_value, const Domain &var_domain) const
void AddTerm(int ct_index, int var, int64_t coeff, int64_t offset=0)
int NumViolatedConstraintsForVarIgnoringObjective(int var) const
Returns the number of constraints in ViolatedConstraints containing var.
double WeightedViolation(absl::Span< const double > weights) const
void ComputeAllNonLinearViolations(absl::Span< const int64_t > solution)
const LinearIncrementalEvaluator & LinearEvaluator()
void UpdateLinearScores(int var, int64_t old_value, int64_t new_value, absl::Span< const double > weights, absl::Span< const int64_t > jump_deltas, absl::Span< double > jump_scores)
Function specific to the linear only feasibility jump.
bool VariableOnlyInLinearConstraintWithConvexViolationChange(int var) const
Indicates if the computed jump value is always the best choice.
void ComputeAllViolations(absl::Span< const int64_t > solution)
Recomputes the violations of all constraints (resp only non-linear one).
void UpdateNonLinearViolations(int var, int64_t old_value, absl::Span< const int64_t > new_solution)
Recomputes the violations of all impacted non linear constraints.
double DeterministicTime() const
bool ReduceObjectiveBounds(int64_t lb, int64_t ub)
int64_t SumOfViolations()
Simple summation metric for the constraint and objective violations.
int64_t ObjectiveActivity() const
Returns the objective activity in the current state.
int64_t ObjectiveCoefficient(int var) const
bool IsViolated(int c) const
int64_t Violation(int c) const
absl::Span< const int > ViolatedConstraints() const
absl::Span< const int > VariablesAffectedByLastLinearUpdate() const
LsEvaluator(const CpModelProto &cp_model, const SatParameters ¶ms, TimeLimit *time_limit)
The cp_model must outlive this class.
void UpdateViolatedList()
absl::Span< const int > ConstraintToVars(int c) const
int NumNonLinearConstraints() const
LinearIncrementalEvaluator * MutableLinearEvaluator()
absl::Span< const int > VarToGeneralConstraints(int var) const
int NumInfeasibleConstraints() const
double WeightedViolationDelta(bool linear_only, absl::Span< const double > weights, int var, int64_t delta, absl::Span< int64_t > mutable_solution) const
absl::Span< const int > GeneralConstraintToVars(int general_c) const
void RecomputeViolatedList(bool linear_only)
bool IsObjectiveConstraint(int c) const
const std::vector< int > & last_update_violation_changes() const
int NumLinearConstraints() const
int NumEvaluatorConstraints() const
void STLSortAndRemoveDuplicates(T *v, const LessFunc &less_func)
In SWIG mode, we don't want anything besides these top-level includes.
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
DenseSet< T, false > UnsafeDenseSet
ClosedInterval::Iterator end(ClosedInterval interval)
ViewOfAffineLinearExpressionProto y_min
Box(const ConstraintProto &x, const ConstraintProto &y)
ViewOfAffineLinearExpressionProto y_max
ViewOfAffineLinearExpressionProto x_min
ViewOfAffineLinearExpressionProto x_max
ViewOfAffineLinearExpressionProto end
Interval(const ConstraintProto &x)
ViewOfAffineLinearExpressionProto start
ViewOfAffineLinearExpressionProto(const LinearExpressionProto &proto)
void AppendVarTo(std::vector< int > &result) const