19 #include "absl/strings/str_format.h"
20 #include "absl/strings/str_join.h"
26 uint64_t FprintOfInt32(
int i) {
34 element_.assign(num_elements, -1);
35 index_of_.assign(num_elements, -1);
36 for (
int i = 0; i < num_elements; ++i) {
40 part_of_.assign(num_elements, 0);
42 for (
int i = 0; i < num_elements; ++i) fprint ^= FprintOfInt32(i);
43 part_.push_back(Part(0, num_elements,
49 const std::vector<int>& initial_part_of_element) {
50 if (initial_part_of_element.empty())
return;
51 part_of_ = initial_part_of_element;
52 const int n = part_of_.size();
53 const int num_parts = 1 + *std::max_element(part_of_.begin(), part_of_.end());
54 DCHECK_EQ(0, *std::min_element(part_of_.begin(), part_of_.end()));
55 part_.resize(num_parts);
58 for (
int i = 0; i < n; ++i) part_[part_of_[i]].fprint ^= FprintOfInt32(i);
63 for (
int p = 0; p < num_parts; ++p) {
64 part_[p].end_index = 0;
65 part_[p].parent_part = p;
67 for (
const int p : part_of_) ++part_[p].end_index;
68 int sum_part_sizes = 0;
69 for (
int p = 0; p < num_parts; ++p) {
70 part_[p].start_index = sum_part_sizes;
71 sum_part_sizes += part_[p].end_index;
77 for (Part& part : part_) part.end_index = part.start_index;
78 element_.assign(n, -1);
79 index_of_.assign(n, -1);
80 for (
int element = 0; element < n; ++element) {
81 Part*
const part = &part_[part_of_[element]];
82 element_[part->end_index] = element;
83 index_of_[element] = part->end_index;
92 for (
int p = 1; p <
NumParts(); ++p) {
93 DCHECK_EQ(part_[p - 1].end_index, part_[p].start_index);
100 tmp_counter_of_part_.resize(
NumParts(), 0);
102 tmp_affected_parts_.clear();
103 for (
const int element : distinguished_subset) {
106 const int part = part_of_[element];
107 const int num_distinguished_elements_in_part = ++tmp_counter_of_part_[part];
109 if (num_distinguished_elements_in_part == 1) {
111 tmp_affected_parts_.push_back(part);
114 const int old_index = index_of_[element];
115 const int new_index =
116 part_[part].end_index - num_distinguished_elements_in_part;
118 <<
"Duplicate element given to Refine(): " << element;
120 index_of_[element] = new_index;
121 index_of_[element_[new_index]] = old_index;
122 std::swap(element_[old_index], element_[new_index]);
128 std::sort(tmp_affected_parts_.begin(), tmp_affected_parts_.end());
132 for (
const int part : tmp_affected_parts_) {
133 const int start_index = part_[part].start_index;
134 const int end_index = part_[part].end_index;
135 const int split_index = end_index - tmp_counter_of_part_[part];
136 tmp_counter_of_part_[part] = 0;
141 if (split_index == start_index)
continue;
144 uint64_t new_fprint = 0;
145 for (
int i = split_index; i < end_index; ++i) {
146 new_fprint ^= FprintOfInt32(element_[i]);
152 part_[part].end_index = split_index;
153 part_[part].fprint ^= new_fprint;
154 part_.push_back(Part( split_index, end_index,
157 part_of_[element] = new_part;
165 while (
NumParts() > original_num_parts) {
166 const int part_index =
NumParts() - 1;
167 const Part& part = part_[part_index];
168 const int parent_part_index = part.parent_part;
169 DCHECK_LT(parent_part_index, part_index) <<
"UndoRefineUntilNumPartsEqual()"
171 "'original_num_parts' too low";
175 part_of_[element] = parent_part_index;
177 Part*
const parent_part = &part_[parent_part_index];
178 DCHECK_EQ(part.start_index, parent_part->end_index);
179 parent_part->end_index = part.end_index;
180 parent_part->fprint ^= part.fprint;
187 return absl::StrFormat(
"Unsupported sorting: %d", sorting);
189 std::vector<std::vector<int>> parts;
190 for (
int i = 0; i <
NumParts(); ++i) {
192 parts.emplace_back(iterable_part.
begin(), iterable_part.
end());
193 std::sort(parts.back().begin(), parts.back().end());
196 std::sort(parts.begin(), parts.end());
199 for (
const std::vector<int>& part : parts) {
200 if (!out.empty()) out +=
" | ";
201 out += absl::StrJoin(part,
" ");
208 part_size_.assign(num_nodes, 1);
209 parent_.assign(num_nodes, -1);
210 for (
int i = 0; i < num_nodes; ++i) parent_[i] = i;
211 tmp_part_bit_.assign(num_nodes,
false);
221 if (root1 == root2)
return -1;
222 int s1 = part_size_[root1];
223 int s2 = part_size_[root2];
225 if (s1 < s2 || (s1 == s2 && root1 > root2)) {
232 part_size_[root1] += part_size_[root2];
233 SetParentAlongPathToRoot(node1, root1);
234 SetParentAlongPathToRoot(node2, root1);
241 const int root =
GetRoot(node);
242 SetParentAlongPathToRoot(node, root);
247 int num_nodes_kept = 0;
248 for (
const int node : *
nodes) {
252 (*nodes)[num_nodes_kept++] = node;
255 nodes->resize(num_nodes_kept);
259 for (
const int node : *
nodes) tmp_part_bit_[
GetRoot(node)] =
false;
263 std::vector<int>* node_equivalence_classes) {
264 node_equivalence_classes->assign(
NumNodes(), -1);
266 for (
int node = 0; node <
NumNodes(); ++node) {
268 if ((*node_equivalence_classes)[root] < 0) {
269 (*node_equivalence_classes)[root] = num_roots;
272 (*node_equivalence_classes)[node] = (*node_equivalence_classes)[root];
278 std::vector<std::vector<int>> sorted_parts(
NumNodes());
279 for (
int i = 0; i <
NumNodes(); ++i) {
282 for (std::vector<int>& part : sorted_parts)
283 std::sort(part.begin(), part.end());
284 std::sort(sorted_parts.begin(), sorted_parts.end());
288 for (
const std::vector<int>& part : sorted_parts) {
289 if (!out.empty()) out +=
" | ";
290 out += absl::StrJoin(part,
" ");
#define DCHECK_GE(val1, val2)
#define DCHECK_LT(val1, val2)
#define DCHECK_EQ(val1, val2)
IterablePart ElementsInPart(int i) const
void Refine(const std::vector< int > &distinguished_subset)
void UndoRefineUntilNumPartsEqual(int original_num_parts)
DynamicPartition(int num_elements)
std::string DebugString(DebugStringSorting sorting) const
const int NumParts() const
void Reset(int num_nodes)
std::string DebugString()
int MergePartsOf(int node1, int node2)
int FillEquivalenceClasses(std::vector< int > *node_equivalence_classes)
void KeepOnlyOneNodePerPart(std::vector< int > *nodes)
int GetRootAndCompressPath(int node)
int GetRoot(int node) const
void swap(IdMap< K, V > &a, IdMap< K, V > &b)
Collection of objects used to extend the Constraint Solver library.
uint64_t MurmurHash64(const char *buf, const size_t len)
std::vector< int >::const_iterator end() const
std::vector< int >::const_iterator begin() const