Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
constraint_violation.h
Go to the documentation of this file.
1// Copyright 2010-2024 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 OR_TOOLS_SAT_CONSTRAINT_VIOLATION_H_
15#define OR_TOOLS_SAT_CONSTRAINT_VIOLATION_H_
16
17#include <cstddef>
18#include <cstdint>
19#include <memory>
20#include <optional>
21#include <utility>
22#include <vector>
23
24#include "absl/container/flat_hash_map.h"
25#include "absl/types/span.h"
26#include "ortools/sat/cp_model.pb.h"
27#include "ortools/sat/sat_parameters.pb.h"
28#include "ortools/sat/util.h"
31
32namespace operations_research {
33namespace sat {
34
36 public:
38
39 // Returns the index of the new constraint.
40 int NewConstraint(Domain domain);
41
42 // Incrementaly build the constraint.
43 //
44 // In case of duplicate variables on the same constraint, the code assumes
45 // constraints are built in-order as it checks for duplication.
46 //
47 // Note that the code assume that a Boolean variable DO NOT appear both in the
48 // enforcement list and in the constraint. Otherwise the update will just be
49 // wrong. This should be enforced by our presolve.
50 void AddEnforcementLiteral(int ct_index, int lit);
51 void AddLiteral(int ct_index, int lit, int64_t coeff = 1);
52 void AddTerm(int ct_index, int var, int64_t coeff, int64_t offset = 0);
53 void AddOffset(int ct_index, int64_t offset);
54 void AddLinearExpression(int ct_index, const LinearExpressionProto& expr,
55 int64_t multiplier);
56
57 // Important: this needs to be called after all constraint has been added
58 // and before the class starts to be used. This is DCHECKed.
59 void PrecomputeCompactView(absl::Span<const int64_t> var_max_variation);
60
61 // Compute activities.
62 void ComputeInitialActivities(absl::Span<const int64_t> solution);
63
64 // Update the activities of each constraints.
65 // Also update the current score for the given deltas.
66 //
67 // Note that the score of the changed variable will not be updated correctly!
69 int var, int64_t delta, absl::Span<const double> weights,
70 absl::Span<const int64_t> jump_deltas, absl::Span<double> jump_scores,
71 std::vector<int>* constraints_with_changed_violations);
72
73 // Also for feasibility jump.
74 void UpdateScoreOnWeightUpdate(int c, absl::Span<const int64_t> jump_deltas,
75 absl::Span<double> var_to_score_change);
76
77 // Variables whose score/jump might have changed since the last clear.
78 //
79 // Note that because we reason on a per-constraint basis, this is actually
80 // independent of the set of positive constraint weight used.
82 absl::Span<const int> VariablesAffectedByLastUpdate() const {
83 return last_affected_variables_;
84 }
85
86 // Query violation.
87 int64_t Activity(int c) const;
88 int64_t Violation(int c) const;
89 bool IsViolated(int c) const;
90 bool AppearsInViolatedConstraints(int var) const;
91
92 // Used to DCHECK the state of the evaluator.
93 bool VarIsConsistent(int var) const;
94
95 // Intersect constraint bounds with [lb..ub].
96 // It returns true if a reduction of the domain took place.
97 bool ReduceBounds(int c, int64_t lb, int64_t ub);
98
99 // Model getters.
100 int num_constraints() const { return num_constraints_; }
101
102 // Returns the weighted sum of the violation.
103 // Note that weights might have more entries than the number of constraints.
104 double WeightedViolation(absl::Span<const double> weights) const;
105
106 // Computes how much the weighted violation will change if var was changed
107 // from its old value by += delta.
108 double WeightedViolationDelta(absl::Span<const double> weights, int var,
109 int64_t delta) const;
110
111 // The violation for each constraint is a piecewise linear function. This
112 // computes and aggregates all the breakpoints for the given variable and its
113 // domain.
114 //
115 // Note that if the domain contains less than two values, we return an empty
116 // vector. This function is not meant to be used for such domains.
117 std::vector<int64_t> SlopeBreakpoints(int var, int64_t current_value,
118 const Domain& var_domain) const;
119
120 // Checks if the jump value of a variable is always optimal.
121 bool ViolationChangeIsConvex(int var) const;
122
123 double DeterministicTime() const {
124 return 5e-9 * static_cast<double>(num_ops_);
125 }
126
127 int64_t ObjectiveCoefficient(int var) const {
128 if (var >= columns_.size()) return 0.0;
129 const SpanData& data = columns_[var];
130 if (data.num_linear_entries == 0) return 0.0;
131 const int i = data.start + data.num_neg_literal + data.num_pos_literal;
132 const int c = ct_buffer_[i];
133 if (c != 0) return 0.0;
134 return coeff_buffer_[data.linear_start];
135 }
136
137 absl::Span<const int> ConstraintToVars(int c) const {
138 const SpanData& data = rows_[c];
139 const int size =
140 data.num_pos_literal + data.num_neg_literal + data.num_linear_entries;
141 if (size == 0) return {};
142 return absl::MakeSpan(&row_var_buffer_[data.start], size);
143 }
144
145 private:
146 // Cell in the sparse matrix.
147 struct Entry {
148 int ct_index;
149 int64_t coefficient;
150 };
151
152 // Column-view of the enforcement literals.
153 struct LiteralEntry {
154 int ct_index;
155 bool positive; // bool_var or its negation.
156 };
157
158 struct SpanData {
159 int start = 0;
160 int num_pos_literal = 0;
161 int num_neg_literal = 0;
162 int linear_start = 0;
163 int num_linear_entries = 0;
164 };
165
166 absl::Span<const int> VarToConstraints(int var) const {
167 if (var >= columns_.size()) return {};
168 const SpanData& data = columns_[var];
169 const int size =
170 data.num_pos_literal + data.num_neg_literal + data.num_linear_entries;
171 if (size == 0) return {};
172 return absl::MakeSpan(&ct_buffer_[data.start], size);
173 }
174
175 void ComputeAndCacheDistance(int ct_index);
176
177 // Incremental row-based update.
178 void UpdateScoreOnNewlyEnforced(int c, double weight,
179 absl::Span<const int64_t> jump_deltas,
180 absl::Span<double> jump_scores);
181 void UpdateScoreOnNewlyUnenforced(int c, double weight,
182 absl::Span<const int64_t> jump_deltas,
183 absl::Span<double> jump_scores);
184 void UpdateScoreOfEnforcementIncrease(int c, double score_change,
185 absl::Span<const int64_t> jump_deltas,
186 absl::Span<double> jump_scores);
187 void UpdateScoreOnActivityChange(int c, double weight, int64_t activity_delta,
188 absl::Span<const int64_t> jump_deltas,
189 absl::Span<double> jump_scores);
190
191 // Constraint indexed data (static).
192 int num_constraints_ = 0;
193 std::vector<Domain> domains_;
194 std::vector<int64_t> offsets_;
195
196 // Variable indexed data.
197 // Note that this is just used at construction and is replaced by a compact
198 // view when PrecomputeCompactView() is called.
199 bool creation_phase_ = true;
200 std::vector<std::vector<Entry>> var_entries_;
201 std::vector<std::vector<LiteralEntry>> literal_entries_;
202
203 // Memory efficient column based data (static).
204 std::vector<SpanData> columns_;
205 std::vector<int> ct_buffer_;
206 std::vector<int64_t> coeff_buffer_;
207
208 // Memory efficient row based data (static).
209 std::vector<SpanData> rows_;
210 std::vector<int> row_var_buffer_;
211 std::vector<int64_t> row_coeff_buffer_;
212
213 // In order to avoid scanning long constraint we compute for each of them
214 // the maximum activity variation of one variable (max-min) * abs(coeff).
215 // If the current activity plus this is still feasible, then the constraint
216 // do not need to be scanned.
217 std::vector<int64_t> row_max_variations_;
218
219 // Temporary data.
220 std::vector<int> tmp_row_sizes_;
221 std::vector<int> tmp_row_num_positive_literals_;
222 std::vector<int> tmp_row_num_negative_literals_;
223 std::vector<int> tmp_row_num_linear_entries_;
224
225 // Constraint indexed data (dynamic).
226 std::vector<bool> is_violated_;
227 std::vector<int64_t> activities_;
228 std::vector<int64_t> distances_;
229 std::vector<int> num_false_enforcement_;
230
231 // Code to update the scores on a variable change.
232 std::vector<int64_t> old_distances_;
233 std::vector<int> old_num_false_enforcement_;
234 std::vector<int64_t> cached_deltas_;
235 std::vector<double> cached_scores_;
236
237 std::vector<bool> in_last_affected_variables_;
238 FixedCapacityVector<int> last_affected_variables_;
239
240 mutable size_t num_ops_ = 0;
241};
242
243// View of a generic (non linear) constraint for the LsEvaluator.
245 public:
247 virtual ~CompiledConstraint() = default;
248
249 // Recomputes the violation of the constraint from scratch.
250 void InitializeViolation(absl::Span<const int64_t> solution);
251
252 // Updates the violation with the new value.
253 virtual void PerformMove(int var, int64_t old_value,
254 absl::Span<const int64_t> solution_with_new_value);
255
256 // Returns the delta if var changes from old_value to solution[var].
257 virtual int64_t ViolationDelta(
258 int var, int64_t old_value,
259 absl::Span<const int64_t> solution_with_new_value);
260
261 // Returns the sorted vector of variables used by this constraint. This is
262 // used to known when a violation might change, and is only called once during
263 // initialization, so speed is not to much of a concern here.
264 //
265 // The global proto is needed to resolve interval variables reference.
266 virtual std::vector<int> UsedVariables(
267 const CpModelProto& model_proto) const = 0;
268
269 // The cached violation of this constraint.
270 int64_t violation() const { return violation_; }
271
272 protected:
273 // Computes the violation of a constraint.
274 //
275 // This is called by InitializeViolation() and also the default implementation
276 // of ViolationDelta().
277 virtual int64_t ComputeViolation(absl::Span<const int64_t> solution) = 0;
278
279 int64_t violation_;
280};
281
282// Intermediate class for all constraints that store directly their proto as
283// part of their implementation.
285 public:
286 explicit CompiledConstraintWithProto(const ConstraintProto& ct_proto);
287 ~CompiledConstraintWithProto() override = default;
288
289 const ConstraintProto& ct_proto() const { return ct_proto_; }
290
291 // This just returns the variables used by the stored ct_proto_.
292 std::vector<int> UsedVariables(const CpModelProto& model_proto) const final;
293
294 private:
295 const ConstraintProto& ct_proto_;
296};
297
298// Evaluation container for the local search.
299//
300// TODO(user): Ideas for constraint generated moves or sequences of moves?
301
302// Note(user): This class do not handle ALL constraint yet. So it is not because
303// there is no violation here that the solution will be feasible. It is
304// important to check feasibility once this is used. Note that in practice, we
305// can be lucky, and feasible on a subset of hard constraint is enough.
307 public:
308 // The cp_model must outlive this class.
309 LsEvaluator(const CpModelProto& cp_model, const SatParameters& params);
310 LsEvaluator(const CpModelProto& cp_model, const SatParameters& params,
311 const std::vector<bool>& ignored_constraints,
312 const std::vector<ConstraintProto>& additional_constraints);
313
314 // Intersects the domain of the objective with [lb..ub].
315 // It returns true if a reduction of the domain took place.
316 bool ReduceObjectiveBounds(int64_t lb, int64_t ub);
317
318 // Recomputes the violations of all constraints (resp only non-linear one).
319 void ComputeAllViolations(absl::Span<const int64_t> solution);
320 void ComputeAllNonLinearViolations(absl::Span<const int64_t> solution);
321
322 // Recomputes the violations of all impacted non linear constraints.
323 void UpdateNonLinearViolations(int var, int64_t old_value,
324 absl::Span<const int64_t> new_solution);
325
326 // Function specific to the linear only feasibility jump.
327 void UpdateLinearScores(int var, int64_t old_value, int64_t new_value,
328 absl::Span<const double> weights,
329 absl::Span<const int64_t> jump_deltas,
330 absl::Span<double> jump_scores);
331
332 // Must be called after UpdateLinearScores() / UpdateNonLinearViolations()
333 // in order to update the ViolatedConstraints().
334 void UpdateViolatedList();
335
336 absl::Span<const int> VariablesAffectedByLastLinearUpdate() const {
337 return linear_evaluator_.VariablesAffectedByLastUpdate();
338 }
339
340 // Simple summation metric for the constraint and objective violations.
341 int64_t SumOfViolations();
342
343 // Returns the objective activity in the current state.
344 int64_t ObjectiveActivity() const;
345
346 bool IsObjectiveConstraint(int c) const {
347 return cp_model_.has_objective() && c == 0;
348 }
349
350 int64_t ObjectiveCoefficient(int var) const {
351 return cp_model_.has_objective()
352 ? linear_evaluator_.ObjectiveCoefficient(var)
353 : 0;
354 }
355
356 // The number of "internal" constraints in the evaluator. This might not
357 // be the same as the number of initial constraints of the model.
358 int NumLinearConstraints() const;
359 int NumNonLinearConstraints() const;
360 int NumEvaluatorConstraints() const;
361 int NumInfeasibleConstraints() const;
362
363 // Returns the weighted sum of violation. The weights must have the same
364 // size as NumEvaluatorConstraints().
365 int64_t Violation(int c) const;
366 bool IsViolated(int c) const;
367 double WeightedViolation(absl::Span<const double> weights) const;
368
369 // Computes the delta in weighted violation if solution[var] += delta.
370 // We need a temporary mutable solution to evaluate the violation of generic
371 // constraints. If linear_only is true, only the linear violation will be
372 // used.
373 double WeightedViolationDelta(bool linear_only,
374 absl::Span<const double> weights, int var,
375 int64_t delta,
376 absl::Span<int64_t> mutable_solution) const;
377
379 return linear_evaluator_;
380 }
381
383 return &linear_evaluator_;
384 }
385
386 // List of the currently violated constraints.
387 // - It is initialized by RecomputeViolatedList()
388 // - And incrementally maintained by UpdateVariableValue()
389 //
390 // The order depends on the algorithm used and shouldn't be relied on.
391 void RecomputeViolatedList(bool linear_only);
392 absl::Span<const int> ViolatedConstraints() const {
393 return violated_constraints_.values();
394 }
395
396 // Returns the number of constraints in ViolatedConstraints containing `var`.
398 return num_violated_constraint_per_var_ignoring_objective_[var];
399 }
400
401 // Indicates if the computed jump value is always the best choice.
403
404 const std::vector<int>& last_update_violation_changes() const {
405 return last_update_violation_changes_;
406 }
407
408 absl::Span<const int> ConstraintToVars(int c) const {
409 if (c < NumLinearConstraints()) {
410 return linear_evaluator_.ConstraintToVars(c);
411 }
412 return absl::MakeConstSpan(constraint_to_vars_[c - NumLinearConstraints()]);
413 }
414
415 // Note that the constraint indexing is different here than in the other
416 // functions.
417 absl::Span<const int> VarToGeneralConstraints(int var) const {
418 return var_to_constraints_[var];
419 }
420 absl::Span<const int> GeneralConstraintToVars(int general_c) const {
421 return constraint_to_vars_[general_c];
422 }
423
424 // TODO(user): Properly account all big time consumers.
425 double DeterministicTime() const {
426 return linear_evaluator_.DeterministicTime() + dtime_;
427 }
428
429 private:
430 void CompileConstraintsAndObjective(
431 const std::vector<bool>& ignored_constraints,
432 const std::vector<ConstraintProto>& additional_constraints);
433
434 void CompileOneConstraint(const ConstraintProto& ct_proto);
435 void BuildVarConstraintGraph();
436 void UpdateViolatedList(int c);
437
438 const CpModelProto& cp_model_;
439 const SatParameters& params_;
440 CpModelProto expanded_constraints_;
441 LinearIncrementalEvaluator linear_evaluator_;
442 std::vector<std::unique_ptr<CompiledConstraint>> constraints_;
443 std::vector<std::vector<int>> var_to_constraints_;
444 std::vector<std::vector<int>> constraint_to_vars_;
445 std::vector<bool> jump_value_optimal_;
446
447 UnsafeDenseSet<int> violated_constraints_;
448 std::vector<int> num_violated_constraint_per_var_ignoring_objective_;
449
450 // Constraint index with changed violations.
451 std::vector<int> last_update_violation_changes_;
452
453 mutable double dtime_ = 0;
454};
455
456// ================================
457// Individual compiled constraints.
458// ================================
459
460// The violation of a bool_xor constraint is 0 or 1.
461class CompiledBoolXorConstraint : public CompiledConstraintWithProto {
462 public:
463 explicit CompiledBoolXorConstraint(const ConstraintProto& ct_proto);
464 ~CompiledBoolXorConstraint() override = default;
465
466 int64_t ComputeViolation(absl::Span<const int64_t> solution) override;
467 int64_t ViolationDelta(
468 int /*var*/, int64_t /*old_value*/,
469 absl::Span<const int64_t> solution_with_new_value) override;
470};
471
472// The violation of a lin_max constraint is:
473// - the sum(max(0, expr_value - target_value) forall expr). This part will be
474// maintained by the linear part.
475// - target_value - max(expressions) if positive.
477 public:
478 explicit CompiledLinMaxConstraint(const ConstraintProto& ct_proto);
479 ~CompiledLinMaxConstraint() override = default;
480
481 int64_t ComputeViolation(absl::Span<const int64_t> solution) override;
482};
483
484// The violation of an int_prod constraint is
485// abs(value(target) - prod(value(expr)).
487 public:
488 explicit CompiledIntProdConstraint(const ConstraintProto& ct_proto);
489 ~CompiledIntProdConstraint() override = default;
490
491 int64_t ComputeViolation(absl::Span<const int64_t> solution) override;
492};
493
494// The violation of an int_div constraint is
495// abs(value(target) - value(expr0) / value(expr1)).
497 public:
498 explicit CompiledIntDivConstraint(const ConstraintProto& ct_proto);
499 ~CompiledIntDivConstraint() override = default;
500
501 int64_t ComputeViolation(absl::Span<const int64_t> solution) override;
502};
503
504// The violation of an int_mod constraint is defined as follow:
505//
506// if target and expr0 have the same sign:
507// min(
508// abs(value(target) - (value(expr0) % value(expr1))),
509// abs(value(target)) + abs((value(expr0) % value(expr1)) - value(expr1)),
510// abs(value(expr0) % value(expr1)) + abs(value(target) - value(expr1)),
511// )
512//
513// if target and expr0 have different sign:
514// abs(target) + abs(expr0)
515// Note: the modulo (expr1) is always fixed.
517 public:
518 explicit CompiledIntModConstraint(const ConstraintProto& ct_proto);
519 ~CompiledIntModConstraint() override = default;
520
521 int64_t ComputeViolation(absl::Span<const int64_t> solution) override;
522};
523
524// The violation of a all_diff is the number of unordered pairs of expressions
525// with the same value.
527 public:
528 explicit CompiledAllDiffConstraint(const ConstraintProto& ct_proto);
529 ~CompiledAllDiffConstraint() override = default;
530
531 int64_t ComputeViolation(absl::Span<const int64_t> solution) override;
532
533 private:
534 std::vector<int64_t> values_;
535};
536
537// Special constraint for no overlap between two intervals.
538// We usually expand small no-overlap in n^2 such constraint, so we want to
539// be compact and efficient here.
541 public:
542 NoOverlapBetweenTwoIntervals(int interval_0, int interval_1,
543 const CpModelProto& cp_model);
544 ~NoOverlapBetweenTwoIntervals() override = default;
545
546 int64_t ComputeViolation(absl::Span<const int64_t> solution) final {
547 return ComputeViolationInternal(solution);
549
550 // Note(user): this is the same implementation as the base one, but it
551 // avoid one virtual call !
552 int64_t ViolationDelta(
553 int /*var*/, int64_t /*old_value*/,
554 absl::Span<const int64_t> solution_with_new_value) final {
555 return ComputeViolationInternal(solution_with_new_value) - violation();
556 }
557
558 std::vector<int> UsedVariables(const CpModelProto& model_proto) const final;
559
560 private:
561 int64_t ComputeViolationInternal(absl::Span<const int64_t> solution);
562
563 int num_enforcements_;
564 std::unique_ptr<int[]> enforcements_;
565 LinearExpressionProto end_minus_start_1_;
566 LinearExpressionProto end_minus_start_2_;
567};
568
569class CompiledNoOverlap2dConstraint : public CompiledConstraintWithProto {
570 public:
571 explicit CompiledNoOverlap2dConstraint(const ConstraintProto& ct_proto,
572 const CpModelProto& cp_model);
573 ~CompiledNoOverlap2dConstraint() override = default;
574
575 int64_t ComputeViolation(absl::Span<const int64_t> solution) override;
576
577 private:
578 const CpModelProto& cp_model_;
579};
580
581// This can be used to encode reservoir or a cumulative constraints for LS. We
582// have a set of event time, and we use for overal violation the sum of overload
583// over time.
584//
585// This version support an incremental computation when just a few events
586// changes, which is roughly O(n) instead of O(n log n) which makes it
587// significantly faster than recomputing and sorting the profile on each
588// ViolationDelta().
590 public:
591 CompiledReservoirConstraint(LinearExpressionProto capacity,
592 std::vector<std::optional<int>> is_active,
593 std::vector<LinearExpressionProto> times,
594 std::vector<LinearExpressionProto> demands)
595 : capacity_(std::move(capacity)),
596 is_active_(std::move(is_active)),
597 times_(std::move(times)),
598 demands_(std::move(demands)) {
599 const int num_events = times_.size();
600 time_values_.resize(num_events, 0);
601 demand_values_.resize(num_events, 0);
602 InitializeDenseIndexToEvents();
603 }
604
605 // Note that since we have our own ViolationDelta() implementation this is
606 // only used for initialization and our PerformMove(). It is why we set
607 // violations_ here.
608 int64_t ComputeViolation(absl::Span<const int64_t> solution) final {
609 violation_ = BuildProfileAndReturnViolation(solution);
611 }
612
613 void PerformMove(int /*var*/, int64_t /*old_value*/,
614 absl::Span<const int64_t> solution_with_new_value) final {
615 // TODO(user): we could probably be more incremental here, but it is a bit
616 // tricky to get right and not too important since the time is dominated by
617 // evaluating moves, not taking them.
618 ComputeViolation(solution_with_new_value);
619 }
620
621 int64_t ViolationDelta(
622 int var, int64_t /*old_value*/,
623 absl::Span<const int64_t> solution_with_new_value) final {
624 return IncrementalViolation(var, solution_with_new_value) - violation_;
625 }
626
627 std::vector<int> UsedVariables(const CpModelProto& model_proto) const final;
628
629 private:
630 // This works in O(n log n).
631 int64_t BuildProfileAndReturnViolation(absl::Span<const int64_t> solution);
632
633 // This works in O(n) + O(d log d) where d is the number of modified events
634 // compare to the base solution. In most situation it should be O(1).
635 int64_t IncrementalViolation(int var, absl::Span<const int64_t> solution);
636
637 // This is used to speed up IncrementalViolation().
638 void InitializeDenseIndexToEvents();
639 void AppendVariablesForEvent(int i, std::vector<int>* result) const;
640
641 // The const data from the constructor.
642 // Note that is_active_ might be empty if all events are mandatory.
643 const LinearExpressionProto capacity_;
644 const std::vector<std::optional<int>> is_active_;
645 const std::vector<LinearExpressionProto> times_;
646 const std::vector<LinearExpressionProto> demands_;
647
648 // Remap all UsedVariables() to a dense index in [0, num_used_vars).
649 absl::flat_hash_map<int, int> var_to_dense_index_;
650 CompactVectorVector<int, int> dense_index_to_events_;
651
652 struct Event {
653 int64_t time;
654 int64_t demand;
655 bool operator<(const Event& o) const { return time < o.time; }
656 };
657 std::vector<Event> profile_;
658 std::vector<Event> profile_delta_;
659
660 // This is filled by BuildProfileAndReturnViolation() and correspond to the
661 // value in the current solutions.
662 int64_t capacity_value_;
663 std::vector<int64_t> time_values_;
664 std::vector<int64_t> demand_values_;
665};
666
667} // namespace sat
668} // namespace operations_research
669
670#endif // OR_TOOLS_SAT_CONSTRAINT_VIOLATION_H_
IntegerValue size
int64_t ComputeViolation(absl::Span< const int64_t > solution) override
CompiledAllDiffConstraint(const ConstraintProto &ct_proto)
--— CompiledAllDiffConstraint --—
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_.
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.
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].
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(const ConstraintProto &ct_proto)
--— CompiledIntModConstraint --—
CompiledIntProdConstraint(const ConstraintProto &ct_proto)
--— CompiledIntProdConstraint --—
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 --—
int64_t ComputeViolation(absl::Span< const int64_t > solution) override
CompiledNoOverlap2dConstraint(const ConstraintProto &ct_proto, const CpModelProto &cp_model)
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
void UpdateScoreOnWeightUpdate(int c, absl::Span< const int64_t > jump_deltas, absl::Span< double > var_to_score_change)
Also for feasibility jump.
double WeightedViolationDelta(absl::Span< const double > weights, int var, int64_t delta) 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 VarIsConsistent(int var) const
Used to DCHECK the state of the evaluator.
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)
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)
absl::Span< const int > ConstraintToVars(int c) const
bool ViolationChangeIsConvex(int var) const
Checks if the jump value of a variable is always optimal.
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.
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.
absl::Span< const int > ViolatedConstraints() const
absl::Span< const int > VariablesAffectedByLastLinearUpdate() const
absl::Span< const int > ConstraintToVars(int c) const
LinearIncrementalEvaluator * MutableLinearEvaluator()
absl::Span< const int > VarToGeneralConstraints(int var) const
LsEvaluator(const CpModelProto &cp_model, const SatParameters &params)
The cp_model must outlive this class.
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
const std::vector< int > & last_update_violation_changes() const
int64_t ComputeViolation(absl::Span< const int64_t > solution) final
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
NoOverlapBetweenTwoIntervals(int interval_0, int interval_1, const CpModelProto &cp_model)
--— NoOverlapBetweenTwoIntervals --—
IntVar * var
int lit
int ct_index
double solution
In SWIG mode, we don't want anything besides these top-level includes.
STL namespace.
int64_t weight
Definition pack.cc:510
int64_t time
Definition resource.cc:1708
int64_t delta
Definition resource.cc:1709