14 #ifndef OR_TOOLS_UTIL_AFFINE_RELATION_H_
15 #define OR_TOOLS_UTIL_AFFINE_RELATION_H_
67 bool TryAdd(
int x,
int y, int64_t coeff, int64_t offset);
71 bool TryAdd(
int x,
int y, int64_t coeff, int64_t offset,
bool allow_rep_x,
87 Relation
Get(
int x)
const;
94 if (x >= size_.size())
return;
95 CHECK_NE(size_[x], kSizeForRemovedEntry) << x;
103 size_[x] = kSizeForRemovedEntry;
108 if (x >= representative_.size())
return 1;
113 const int kSizeForRemovedEntry = 0;
115 void IncreaseSizeOfMemberVectors(
int new_size) {
116 if (new_size <= representative_.size())
return;
117 for (
int i = representative_.size(); i < new_size; ++i) {
118 representative_.push_back(i);
120 offset_.resize(new_size, 0);
121 coeff_.resize(new_size, 1);
122 size_.resize(new_size, 1);
125 void CompressPath(
int x)
const {
130 while (parent != representative_[parent]) {
131 tmp_path_.push_back(parent);
132 parent = representative_[parent];
135 const int old_parent = representative_[
var];
136 offset_[
var] += coeff_[
var] * offset_[old_parent];
137 coeff_[
var] *= coeff_[old_parent];
138 representative_[
var] = parent;
145 mutable std::vector<int> representative_;
149 mutable std::vector<int64_t> coeff_;
150 mutable std::vector<int64_t> offset_;
158 std::vector<int> size_;
161 mutable std::vector<int> tmp_path_;
166 return TryAdd(x, y, coeff, offset,
true,
true);
170 bool allow_rep_x,
bool allow_rep_y) {
175 IncreaseSizeOfMemberVectors(
std::max(x, y) + 1);
176 CHECK_NE(size_[x], kSizeForRemovedEntry) << x;
177 CHECK_NE(size_[y], kSizeForRemovedEntry) << y;
180 const int rep_x = representative_[x];
181 const int rep_y = representative_[y];
182 if (rep_x == rep_y)
return false;
187 const int64_t coeff_x = coeff_[x];
188 const int64_t new_coeff = coeff * coeff_[y];
189 const int64_t new_offset = coeff * offset_[y] + offset - offset_[x];
190 const bool condition1 =
191 allow_rep_y && (new_coeff % coeff_x == 0) && (new_offset % coeff_x == 0);
192 const bool condition2 = allow_rep_x && (coeff_x % new_coeff == 0) &&
193 (new_offset % new_coeff == 0);
194 if (condition1 && (!condition2 || size_[x] <= size_[y])) {
195 representative_[rep_x] = rep_y;
196 size_[rep_y] += size_[rep_x];
197 coeff_[rep_x] = new_coeff / coeff_x;
198 offset_[rep_x] = new_offset / coeff_x;
199 }
else if (condition2) {
200 representative_[rep_y] = rep_x;
201 size_[rep_x] += size_[rep_y];
202 coeff_[rep_y] = coeff_x / new_coeff;
203 offset_[rep_y] = -new_offset / new_coeff;
212 if (x >= representative_.size() || representative_[x] == x)
return {x, 1, 0};
214 return {representative_[x], coeff_[x], offset_[x]};
#define CHECK_EQ(val1, val2)
#define CHECK_GE(val1, val2)
#define CHECK_GT(val1, val2)
#define DCHECK_GE(val1, val2)
#define CHECK_NE(val1, val2)
#define DCHECK_LT(val1, val2)
void IgnoreFromClassSize(int x)
bool TryAdd(int x, int y, int64_t coeff, int64_t offset)
int ClassSize(int x) const
Relation Get(int x) const
ReverseView< Container > reversed_view(const Container &c)
Collection of objects used to extend the Constraint Solver library.
const bool operator==(const Relation &other) const
Relation(int r, int64_t c, int64_t o)