OR-Tools  9.2
diffn_util.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_UTIL_H_
15 #define OR_TOOLS_SAT_DIFFN_UTIL_H_
16 
17 #include <cstdint>
18 #include <vector>
19 
20 #include "absl/container/flat_hash_set.h"
21 #include "absl/strings/str_format.h"
23 #include "ortools/sat/integer.h"
24 #include "ortools/sat/intervals.h"
25 
26 namespace operations_research {
27 namespace sat {
28 
29 struct Rectangle {
30  IntegerValue x_min;
31  IntegerValue x_max;
32  IntegerValue y_min;
33  IntegerValue y_max;
34 
35  void TakeUnionWith(const Rectangle& other) {
36  x_min = std::min(x_min, other.x_min);
37  y_min = std::min(y_min, other.y_min);
38  x_max = std::max(x_max, other.x_max);
39  y_max = std::max(y_max, other.y_max);
40  }
41 
42  IntegerValue Area() const { return (x_max - x_min) * (y_max - y_min); }
43 
44  bool IsDisjoint(const Rectangle& other) const;
45 
46  std::string DebugString() const {
47  return absl::StrFormat("rectangle(x(%i..%i), y(%i..%i))", x_min.value(),
48  x_max.value(), y_min.value(), y_max.value());
49  }
50 };
51 
52 // Creates a graph when two nodes are connected iif their rectangles overlap.
53 // Then partition into connected components.
54 //
55 // This method removes all singleton components. It will modify the
56 // active_rectangle span in place.
57 std::vector<absl::Span<int>> GetOverlappingRectangleComponents(
58  const std::vector<Rectangle>& rectangles,
59  absl::Span<int> active_rectangles);
60 
61 // Visible for testing. The algo is in O(n^4) so shouldn't be used directly.
62 // Returns true if there exist a bounding box with too much energy.
63 bool BoxesAreInEnergyConflict(const std::vector<Rectangle>& rectangles,
64  const std::vector<IntegerValue>& energies,
65  absl::Span<const int> boxes,
66  Rectangle* conflict = nullptr);
67 
68 // Checks that there is indeed a conflict for the given bounding_box and
69 // report it. This returns false for convenience as we usually want to return
70 // false on a conflict.
71 //
72 // TODO(user): relax the bounding box dimension to have a relaxed explanation.
73 // We can also minimize the number of required intervals.
74 bool ReportEnergyConflict(Rectangle bounding_box, absl::Span<const int> boxes,
75  SchedulingConstraintHelper* x,
76  SchedulingConstraintHelper* y);
77 
78 // A O(n^2) algorithm to analyze all the relevant X intervals and infer a
79 // threshold of the y size of a bounding box after which there is no point
80 // checking for energy overload.
81 //
82 // Returns false on conflict, and fill the bounding box that caused the
83 // conflict.
84 //
85 // If transpose is true, we analyze the relevant Y intervals instead.
86 bool AnalyzeIntervals(bool transpose, absl::Span<const int> boxes,
87  const std::vector<Rectangle>& rectangles,
88  const std::vector<IntegerValue>& rectangle_energies,
89  IntegerValue* x_threshold, IntegerValue* y_threshold,
90  Rectangle* conflict = nullptr);
91 
92 // Removes boxes with a size above the thresholds. Also randomize the order.
93 // Because we rely on various heuristic, this allow to change the order from
94 // one call to the next.
95 absl::Span<int> FilterBoxesAndRandomize(
96  const std::vector<Rectangle>& cached_rectangles, absl::Span<int> boxes,
97  IntegerValue threshold_x, IntegerValue threshold_y, absl::BitGenRef random);
98 
99 // Given the total energy of all rectangles (sum of energies[box]) we know that
100 // any box with an area greater than that cannot participate in any "bounding
101 // box" conflict. As we remove this box, the total energy decrease, so we might
102 // remove more. This works in O(n log n).
103 absl::Span<int> FilterBoxesThatAreTooLarge(
104  const std::vector<Rectangle>& cached_rectangles,
105  const std::vector<IntegerValue>& energies, absl::Span<int> boxes);
106 
108  int index;
109  IntegerValue start;
110  IntegerValue end;
111 
112  bool operator==(const IndexedInterval& rhs) const {
113  return std::tie(start, end, index) ==
114  std::tie(rhs.start, rhs.end, rhs.index);
115  }
116 
117  // NOTE(user): We would like to use TUPLE_DEFINE_STRUCT, but sadly it doesn't
118  // support //buildenv/target:non_prod.
120  bool operator()(const IndexedInterval& a, const IndexedInterval& b) const {
121  return std::tie(a.start, a.end, a.index) <
122  std::tie(b.start, b.end, b.index);
123  }
124  };
126  bool operator()(const IndexedInterval& a, const IndexedInterval& b) const {
127  return a.start < b.start;
128  }
129  };
130 };
131 std::ostream& operator<<(std::ostream& out, const IndexedInterval& interval);
132 
133 // Given n fixed intervals, returns the subsets of intervals that overlap during
134 // at least one time unit. Note that we only return "maximal" subset and filter
135 // subset strictly included in another.
136 //
137 // All Intervals must have a positive size.
138 //
139 // The algo is in O(n log n) + O(result_size) which is usually O(n^2).
140 void ConstructOverlappingSets(bool already_sorted,
141  std::vector<IndexedInterval>* intervals,
142  std::vector<std::vector<int>>* result);
143 
144 // Given n intervals, returns the set of connected components (using the overlap
145 // relation between 2 intervals). Components are sorted by their start, and
146 // inside a component, the intervals are also sorted by start.
147 // `intervals` is only sorted (by start), and not modified otherwise.
149  std::vector<IndexedInterval>* intervals,
150  std::vector<std::vector<int>>* components);
151 
152 // Similar to GetOverlappingIntervalComponents(), but returns the indices of
153 // all intervals whose removal would create one more connected component in the
154 // interval graph. Those are sorted by start. See:
155 // https://en.wikipedia.org/wiki/Glossary_of_graph_theory#articulation_point.
156 std::vector<int> GetIntervalArticulationPoints(
157  std::vector<IndexedInterval>* intervals);
158 
159 } // namespace sat
160 } // namespace operations_research
161 
162 #endif // OR_TOOLS_SAT_DIFFN_UTIL_H_
int64_t min
Definition: alldiff_cst.cc:139
void GetOverlappingIntervalComponents(std::vector< IndexedInterval > *intervals, std::vector< std::vector< int >> *components)
Definition: diffn_util.cc:395
absl::Span< int > FilterBoxesAndRandomize(const std::vector< Rectangle > &cached_rectangles, absl::Span< int > boxes, IntegerValue threshold_x, IntegerValue threshold_y, absl::BitGenRef random)
Definition: diffn_util.cc:303
bool operator()(const IndexedInterval &a, const IndexedInterval &b) const
Definition: diffn_util.h:120
int64_t b
int64_t max
Definition: alldiff_cst.cc:140
bool operator()(const IndexedInterval &a, const IndexedInterval &b) const
Definition: diffn_util.h:126
std::string DebugString() const
Definition: diffn_util.h:46
void ConstructOverlappingSets(bool already_sorted, std::vector< IndexedInterval > *intervals, std::vector< std::vector< int >> *result)
Definition: diffn_util.cc:346
bool operator==(const IndexedInterval &rhs) const
Definition: diffn_util.h:112
void TakeUnionWith(const Rectangle &other)
Definition: diffn_util.h:35
std::vector< absl::Span< int > > GetOverlappingRectangleComponents(const std::vector< Rectangle > &rectangles, absl::Span< int > active_rectangles)
Definition: diffn_util.cc:26
bool AnalyzeIntervals(bool transpose, absl::Span< const int > local_boxes, const std::vector< Rectangle > &rectangles, const std::vector< IntegerValue > &rectangle_energies, IntegerValue *x_threshold, IntegerValue *y_threshold, Rectangle *conflict)
Definition: diffn_util.cc:151
bool BoxesAreInEnergyConflict(const std::vector< Rectangle > &rectangles, const std::vector< IntegerValue > &energies, absl::Span< const int > boxes, Rectangle *conflict)
Definition: diffn_util.cc:84
bool ReportEnergyConflict(Rectangle bounding_box, absl::Span< const int > boxes, SchedulingConstraintHelper *x, SchedulingConstraintHelper *y)
Definition: diffn_util.cc:52
Collection of objects used to extend the Constraint Solver library.
absl::Span< int > FilterBoxesThatAreTooLarge(const std::vector< Rectangle > &cached_rectangles, const std::vector< IntegerValue > &energies, absl::Span< int > boxes)
Definition: diffn_util.cc:319
std::vector< int > GetIntervalArticulationPoints(std::vector< IndexedInterval > *intervals)
Definition: diffn_util.cc:428
std::ostream & operator<<(std::ostream &os, const BoolVar &var)
Definition: cp_model.cc:86
bool IsDisjoint(const Rectangle &other) const
Definition: diffn_util.cc:21
IntervalVar * interval
Definition: resource.cc:100
int64_t a