OR-Tools  9.6
diffn.h
Go to the documentation of this file.
1 // Copyright 2010-2022 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_DIFFN_H_
15 #define OR_TOOLS_SAT_DIFFN_H_
16 
17 #include <functional>
18 #include <vector>
19 
20 #include "absl/container/flat_hash_set.h"
21 #include "absl/types/span.h"
23 #include "ortools/base/logging.h"
24 #include "ortools/base/macros.h"
25 #include "ortools/sat/diffn_util.h"
27 #include "ortools/sat/integer.h"
28 #include "ortools/sat/intervals.h"
29 #include "ortools/sat/model.h"
30 #include "ortools/sat/sat_base.h"
31 #include "ortools/sat/util.h"
33 
34 namespace operations_research {
35 namespace sat {
36 
37 // Non overlapping rectangles.
39  : public PropagatorInterface {
40  public:
41  // The strict parameters indicates how to place zero width or zero height
42  // boxes. If strict is true, these boxes must not 'cross' another box, and are
43  // pushed by the other boxes.
44  // The slow_propagators select which disjunctive algorithms to propagate.
48  Model* model);
50 
51  bool Propagate() final;
52  void Register(int fast_priority, int slow_priority);
53 
54  private:
55  bool PropagateTwoBoxes();
56  bool FindBoxesThatMustOverlapAHorizontalLineAndPropagate(
57  bool fast_propagation, const SchedulingConstraintHelper& x,
59 
60  SchedulingConstraintHelper& global_x_;
61  SchedulingConstraintHelper& global_y_;
63  const bool strict_;
64 
65  GenericLiteralWatcher* watcher_;
66  int fast_id_; // Propagator id of the "fast" version.
67 
68  std::vector<IndexedInterval> indexed_intervals_;
69  std::vector<std::vector<int>> events_overlapping_boxes_;
70 
71  absl::flat_hash_set<absl::Span<int>> reduced_overlapping_boxes_;
72  std::vector<absl::Span<int>> boxes_to_propagate_;
73  std::vector<absl::Span<int>> disjoint_boxes_;
74 
75  DisjunctiveOverloadChecker overload_checker_;
76  DisjunctiveDetectablePrecedences forward_detectable_precedences_;
77  DisjunctiveDetectablePrecedences backward_detectable_precedences_;
78  DisjunctiveNotLast forward_not_last_;
79  DisjunctiveNotLast backward_not_last_;
80  DisjunctiveEdgeFinding forward_edge_finding_;
81  DisjunctiveEdgeFinding backward_edge_finding_;
82 
87 };
88 
89 // Add a cumulative relaxation. That is, on one dimension, it does not enforce
90 // the rectangle aspect, allowing vertical slices to move freely.
93 
94 // Enforces that the boxes with corners in (x, y), (x + dx, y), (x, y + dy)
95 // and (x + dx, y + dy) do not overlap.
96 // If strict is true, and if one box has a zero dimension, it still cannot
97 // intersect another box.
98 inline std::function<void(Model*)> NonOverlappingRectangles(
99  const std::vector<IntervalVariable>& x,
100  const std::vector<IntervalVariable>& y, bool is_strict) {
101  return [=](Model* model) {
102  SchedulingConstraintHelper* x_helper =
104  SchedulingConstraintHelper* y_helper =
106  model->TakeOwnership(x_helper);
107  model->TakeOwnership(y_helper);
108 
110  new NonOverlappingRectanglesDisjunctivePropagator(is_strict, x_helper,
111  y_helper, model);
112  constraint->Register(/*fast_priority=*/3, /*slow_priority=*/4);
113  model->TakeOwnership(constraint);
114 
115  const SatParameters* params = model->GetOrCreate<SatParameters>();
116  const bool add_cumulative_relaxation =
117  params->use_timetabling_in_no_overlap_2d() ||
118  params->use_energetic_reasoning_in_no_overlap_2d();
119 
120  if (add_cumulative_relaxation) {
121  // We must first check if the cumulative relaxation is possible.
122  bool some_boxes_are_only_optional_on_x = false;
123  bool some_boxes_are_only_optional_on_y = false;
124  for (int i = 0; i < x.size(); ++i) {
125  if (x_helper->IsOptional(i) && y_helper->IsOptional(i) &&
126  x_helper->PresenceLiteral(i) != y_helper->PresenceLiteral(i)) {
127  // Abort as the task would be conditioned by two literals.
128  return;
129  }
130  if (x_helper->IsOptional(i) && !y_helper->IsOptional(i)) {
131  // We cannot use x_size as the demand of the cumulative based on
132  // the y_intervals.
133  some_boxes_are_only_optional_on_x = true;
134  }
135  if (y_helper->IsOptional(i) && !x_helper->IsOptional(i)) {
136  // We cannot use y_size as the demand of the cumulative based on
137  // the y_intervals.
138  some_boxes_are_only_optional_on_y = true;
139  }
140  }
141  if (!some_boxes_are_only_optional_on_y) {
142  AddDiffnCumulativeRelationOnX(x_helper, y_helper, model);
143  }
144  if (!some_boxes_are_only_optional_on_x) {
145  AddDiffnCumulativeRelationOnX(y_helper, x_helper, model);
146  }
147  }
148  };
149 }
150 
151 } // namespace sat
152 } // namespace operations_research
153 
154 #endif // OR_TOOLS_SAT_DIFFN_H_
Class that owns everything related to a particular optimization model.
Definition: sat/model.h:42
NonOverlappingRectanglesDisjunctivePropagator(bool strict, SchedulingConstraintHelper *x, SchedulingConstraintHelper *y, Model *model)
Definition: sat/diffn.cc:213
GRBmodel * model
std::function< void(Model *)> NonOverlappingRectangles(const std::vector< IntervalVariable > &x, const std::vector< IntervalVariable > &y, bool is_strict)
Definition: diffn.h:98
void AddDiffnCumulativeRelationOnX(SchedulingConstraintHelper *x, SchedulingConstraintHelper *y, Model *model)
Definition: sat/diffn.cc:87
Collection of objects used to extend the Constraint Solver library.