OR-Tools  9.1
diffn.h
Go to the documentation of this file.
1 // Copyright 2010-2021 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 <vector>
18 
19 #include "ortools/base/int_type.h"
21 #include "ortools/base/logging.h"
22 #include "ortools/base/macros.h"
23 #include "ortools/sat/diffn_util.h"
25 #include "ortools/sat/integer.h"
26 #include "ortools/sat/intervals.h"
27 #include "ortools/sat/model.h"
28 #include "ortools/sat/sat_base.h"
29 
30 namespace operations_research {
31 namespace sat {
32 
33 // Propagates using a box energy reasoning.
35  public:
36  // The strict parameters indicates how to place zero width or zero height
37  // boxes. If strict is true, these boxes must not 'cross' another box, and are
38  // pushed by the other boxes.
41  Model* model)
42  : x_(*x), y_(*y), random_(model->GetOrCreate<ModelRandomGenerator>()) {}
44 
45  bool Propagate() final;
46  int RegisterWith(GenericLiteralWatcher* watcher);
47 
48  private:
49  void SortBoxesIntoNeighbors(int box, absl::Span<const int> local_boxes,
50  IntegerValue total_sum_of_areas);
51  bool FailWhenEnergyIsTooLarge(int box, absl::Span<const int> local_boxes,
52  IntegerValue total_sum_of_areas);
53 
56  ModelRandomGenerator* random_;
57 
58  // When the size of the bounding box is greater than any of the corresponding
59  // rectangles, then there is no point checking for overload.
60  IntegerValue threshold_x_;
61  IntegerValue threshold_y_;
62 
63  std::vector<int> active_boxes_;
64  std::vector<IntegerValue> cached_energies_;
65  std::vector<Rectangle> cached_rectangles_;
66 
67  struct Neighbor {
68  int box;
69  IntegerValue distance_to_bounding_box;
70  bool operator<(const Neighbor& o) const {
71  return distance_to_bounding_box < o.distance_to_bounding_box;
72  }
73  };
74  std::vector<Neighbor> neighbors_;
75 
80 };
81 
82 // Non overlapping rectangles.
84  : public PropagatorInterface {
85  public:
86  // The strict parameters indicates how to place zero width or zero height
87  // boxes. If strict is true, these boxes must not 'cross' another box, and are
88  // pushed by the other boxes.
89  // The slow_propagators select which disjunctive algorithms to propagate.
93  Model* model);
95 
96  bool Propagate() final;
97  void Register(int fast_priority, int slow_priority);
98 
99  private:
100  bool PropagateTwoBoxes();
101  bool FindBoxesThatMustOverlapAHorizontalLineAndPropagate(
103  std::function<bool()> inner_propagate);
104 
105  SchedulingConstraintHelper& global_x_;
106  SchedulingConstraintHelper& global_y_;
108  const bool strict_;
109 
110  GenericLiteralWatcher* watcher_;
111  int fast_id_; // Propagator id of the "fast" version.
112 
113  std::vector<IndexedInterval> indexed_intervals_;
114  std::vector<std::vector<int>> events_overlapping_boxes_;
115 
116  absl::flat_hash_set<absl::Span<int>> reduced_overlapping_boxes_;
117  std::vector<absl::Span<int>> boxes_to_propagate_;
118  std::vector<absl::Span<int>> disjoint_boxes_;
119 
120  DisjunctiveOverloadChecker overload_checker_;
121  DisjunctiveDetectablePrecedences forward_detectable_precedences_;
122  DisjunctiveDetectablePrecedences backward_detectable_precedences_;
123  DisjunctiveNotLast forward_not_last_;
124  DisjunctiveNotLast backward_not_last_;
125  DisjunctiveEdgeFinding forward_edge_finding_;
126  DisjunctiveEdgeFinding backward_edge_finding_;
127 
132 };
133 
134 // Add a cumulative relaxation. That is, on one dimension, it does not enforce
135 // the rectangle aspect, allowing vertical slices to move freely.
136 void AddCumulativeRelaxation(const std::vector<IntervalVariable>& x_intervals,
139 
140 // Enforces that the boxes with corners in (x, y), (x + dx, y), (x, y + dy)
141 // and (x + dx, y + dy) do not overlap.
142 // If strict is true, and if one box has a zero dimension, it still cannot
143 // intersect another box.
144 inline std::function<void(Model*)> NonOverlappingRectangles(
145  const std::vector<IntervalVariable>& x,
146  const std::vector<IntervalVariable>& y, bool is_strict,
147  bool add_cumulative_relaxation = true) {
148  return [=](Model* model) {
149  SchedulingConstraintHelper* x_helper =
151  SchedulingConstraintHelper* y_helper =
153  model->TakeOwnership(x_helper);
154  model->TakeOwnership(y_helper);
155 
156  NonOverlappingRectanglesEnergyPropagator* energy_constraint =
157  new NonOverlappingRectanglesEnergyPropagator(x_helper, y_helper, model);
158  GenericLiteralWatcher* const watcher =
159  model->GetOrCreate<GenericLiteralWatcher>();
160  watcher->SetPropagatorPriority(energy_constraint->RegisterWith(watcher), 3);
161  model->TakeOwnership(energy_constraint);
162 
164  new NonOverlappingRectanglesDisjunctivePropagator(is_strict, x_helper,
165  y_helper, model);
166  constraint->Register(/*fast_priority=*/3, /*slow_priority=*/4);
167  model->TakeOwnership(constraint);
168 
169  if (add_cumulative_relaxation) {
170  AddCumulativeRelaxation(x, x_helper, y_helper, model);
171  AddCumulativeRelaxation(y, y_helper, x_helper, model);
172  }
173  };
174 }
175 
176 } // namespace sat
177 } // namespace operations_research
178 
179 #endif // OR_TOOLS_SAT_DIFFN_H_
Class that owns everything related to a particular optimization model.
Definition: sat/model.h:38
GRBmodel * model
void AddCumulativeRelaxation(const std::vector< IntervalVariable > &x_intervals, SchedulingConstraintHelper *x, SchedulingConstraintHelper *y, Model *model)
Definition: sat/diffn.cc:80
Definition: cleanup.h:22
void SetPropagatorPriority(int id, int priority)
Definition: integer.cc:2019
NonOverlappingRectanglesDisjunctivePropagator(bool strict, SchedulingConstraintHelper *x, SchedulingConstraintHelper *y, Model *model)
Definition: sat/diffn.cc:330
Collection of objects used to extend the Constraint Solver library.
std::function< void(Model *)> NonOverlappingRectangles(const std::vector< IntervalVariable > &x, const std::vector< IntervalVariable > &y, bool is_strict, bool add_cumulative_relaxation=true)
Definition: diffn.h:144
NonOverlappingRectanglesEnergyPropagator(SchedulingConstraintHelper *x, SchedulingConstraintHelper *y, Model *model)
Definition: diffn.h:39