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"
25
26namespace operations_research {
27namespace sat {
28
29struct 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.
57std::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.
63bool 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.
74bool 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.
86bool 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.
95absl::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).
103absl::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};
131std::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).
140void 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.
156std::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 max
Definition: alldiff_cst.cc:140
int64_t min
Definition: alldiff_cst.cc:139
int64_t b
int64_t a
std::ostream & operator<<(std::ostream &os, const BoolVar &var)
Definition: cp_model.cc:86
void GetOverlappingIntervalComponents(std::vector< IndexedInterval > *intervals, std::vector< std::vector< int > > *components)
Definition: diffn_util.cc:395
std::vector< int > GetIntervalArticulationPoints(std::vector< IndexedInterval > *intervals)
Definition: diffn_util.cc:428
std::vector< absl::Span< int > > GetOverlappingRectangleComponents(const std::vector< Rectangle > &rectangles, absl::Span< int > active_rectangles)
Definition: diffn_util.cc:26
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 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 ReportEnergyConflict(Rectangle bounding_box, absl::Span< const int > boxes, SchedulingConstraintHelper *x, SchedulingConstraintHelper *y)
Definition: diffn_util.cc:52
void ConstructOverlappingSets(bool already_sorted, std::vector< IndexedInterval > *intervals, std::vector< std::vector< int > > *result)
Definition: diffn_util.cc:346
bool BoxesAreInEnergyConflict(const std::vector< Rectangle > &rectangles, const std::vector< IntegerValue > &energies, absl::Span< const int > boxes, Rectangle *conflict)
Definition: diffn_util.cc:84
absl::Span< int > FilterBoxesThatAreTooLarge(const std::vector< Rectangle > &cached_rectangles, const std::vector< IntegerValue > &energies, absl::Span< int > boxes)
Definition: diffn_util.cc:319
Collection of objects used to extend the Constraint Solver library.
IntervalVar * interval
Definition: resource.cc:100
bool operator()(const IndexedInterval &a, const IndexedInterval &b) const
Definition: diffn_util.h:126
bool operator()(const IndexedInterval &a, const IndexedInterval &b) const
Definition: diffn_util.h:120
bool operator==(const IndexedInterval &rhs) const
Definition: diffn_util.h:112
std::string DebugString() const
Definition: diffn_util.h:46
void TakeUnionWith(const Rectangle &other)
Definition: diffn_util.h:35
bool IsDisjoint(const Rectangle &other) const
Definition: diffn_util.cc:21