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,
90 Relation
Get(
int x)
const;
97 if (x >= size_.size())
return;
98 CHECK_NE(size_[x], kSizeForRemovedEntry) << x;
106 size_[x] = kSizeForRemovedEntry;
111 if (x >= representative_.size())
return 1;
116 const int kSizeForRemovedEntry = 0;
118 void IncreaseSizeOfMemberVectors(
int new_size) {
119 if (new_size <= representative_.size())
return;
120 for (
int i = representative_.size(); i < new_size; ++i) {
121 representative_.push_back(i);
123 offset_.resize(new_size, 0);
124 coeff_.resize(new_size, 1);
125 size_.resize(new_size, 1);
128 void CompressPath(
int x)
const {
133 while (parent != representative_[parent]) {
134 tmp_path_.push_back(parent);
135 parent = representative_[parent];
138 const int old_parent = representative_[
var];
139 offset_[
var] += coeff_[
var] * offset_[old_parent];
140 coeff_[
var] *= coeff_[old_parent];
141 representative_[
var] = parent;
148 mutable std::vector<int> representative_;
152 mutable std::vector<int64_t> coeff_;
153 mutable std::vector<int64_t> offset_;
161 std::vector<int> size_;
164 mutable std::vector<int> tmp_path_;
173 bool allow_rep_x,
bool allow_rep_y) {
178 IncreaseSizeOfMemberVectors(
std::max(x, y) + 1);
179 CHECK_NE(size_[x], kSizeForRemovedEntry) << x;
180 CHECK_NE(size_[y], kSizeForRemovedEntry) << y;
183 const int rep_x = representative_[x];
184 const int rep_y = representative_[y];
185 if (rep_x == rep_y)
return false;
190 const int64_t coeff_x = coeff_[x];
191 const int64_t new_coeff =
coeff * coeff_[y];
192 const int64_t new_offset =
coeff * offset_[y] + offset - offset_[x];
193 const bool condition1 =
194 allow_rep_y && (new_coeff % coeff_x == 0) && (new_offset % coeff_x == 0);
195 const bool condition2 = allow_rep_x && (coeff_x % new_coeff == 0) &&
196 (new_offset % new_coeff == 0);
197 if (condition1 && (!condition2 || size_[x] <= size_[y])) {
198 representative_[rep_x] = rep_y;
199 size_[rep_y] += size_[rep_x];
200 coeff_[rep_x] = new_coeff / coeff_x;
201 offset_[rep_x] = new_offset / coeff_x;
202 }
else if (condition2) {
203 representative_[rep_y] = rep_x;
204 size_[rep_x] += size_[rep_y];
205 coeff_[rep_y] = coeff_x / new_coeff;
206 offset_[rep_y] = -new_offset / new_coeff;
215 if (x >= representative_.size() || representative_[x] == x)
return {x, 1, 0};
217 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)