30 #ifndef OR_TOOLS_ALGORITHMS_DYNAMIC_PARTITION_H_ 31 #define OR_TOOLS_ALGORITHMS_DYNAMIC_PARTITION_H_ 36 #include "ortools/base/logging.h" 49 class DynamicPartition {
53 explicit DynamicPartition(
int num_elements);
57 explicit DynamicPartition(
const std::vector<int>& initial_part_of_element);
60 int NumElements()
const {
return element_.size(); }
61 const int NumParts()
const {
return part_.size(); }
70 IterablePart ElementsInPart(
int i)
const;
72 int PartOf(
int element)
const;
73 int SizeOfPart(
int part)
const;
74 int ParentOfPart(
int part)
const;
78 IterablePart ElementsInSamePartAs(
int i)
const;
85 uint64 FprintOfPart(
int part)
const;
108 void Refine(
const std::vector<int>& distinguished_subset);
113 void UndoRefineUntilNumPartsEqual(
int original_num_parts);
117 enum DebugStringSorting {
120 SORT_LEXICOGRAPHICALLY,
124 std::string DebugString(DebugStringSorting sorting)
const;
136 const std::vector<int>& ElementsInHierarchicalOrder()
const {
144 std::vector<int> element_;
147 std::vector<int> index_of_;
150 std::vector<int> part_of_;
167 Part() : start_index(0), end_index(0), parent_part(0), fprint(0) {}
168 Part(
int start_index,
int end_index,
int parent_part, uint64 fprint)
169 : start_index(start_index),
170 end_index(end_index),
171 parent_part(parent_part),
174 std::vector<Part> part_;
179 std::vector<int> tmp_counter_of_part_;
180 std::vector<int> tmp_affected_parts_;
183 struct DynamicPartition::IterablePart {
184 std::vector<int>::const_iterator begin()
const {
return begin_; }
185 std::vector<int>::const_iterator end()
const {
return end_; }
186 std::vector<int>::const_iterator begin_;
187 std::vector<int>::const_iterator end_;
189 int size()
const {
return end_ - begin_; }
192 IterablePart(
const std::vector<int>::const_iterator& b,
193 const std::vector<int>::const_iterator& e)
194 : begin_(b), end_(e) {}
197 typedef int value_type;
198 typedef std::vector<int>::const_iterator const_iterator;
203 class MergingPartition {
206 MergingPartition() { Reset(0); }
207 explicit MergingPartition(
int num_nodes) { Reset(num_nodes); }
208 void Reset(
int num_nodes);
210 int NumNodes()
const {
return parent_.size(); }
221 int MergePartsOf(
int node1,
int node2);
226 int GetRootAndCompressPath(
int node);
230 void KeepOnlyOneNodePerPart(std::vector<int>* nodes);
238 int FillEquivalenceClasses(std::vector<int>* node_equivalence_classes);
242 std::string DebugString();
249 void ResetNode(
int node);
251 int NumNodesInSamePartAs(
int node) {
252 return part_size_[GetRootAndCompressPath(node)];
260 int GetRoot(
int node)
const;
265 void SetParentAlongPathToRoot(
int node,
int parent);
267 std::vector<int> parent_;
268 std::vector<int> part_size_;
271 std::vector<bool> tmp_part_bit_;
276 inline DynamicPartition::IterablePart DynamicPartition::ElementsInPart(
279 DCHECK_LT(i, NumParts());
280 return IterablePart(element_.begin() + part_[i].start_index,
281 element_.begin() + part_[i].end_index);
284 inline int DynamicPartition::PartOf(
int element)
const {
285 DCHECK_GE(element, 0);
286 DCHECK_LT(element, part_of_.size());
287 return part_of_[element];
290 inline int DynamicPartition::SizeOfPart(
int part)
const {
292 DCHECK_LT(part, part_.size());
293 const Part& p = part_[part];
294 return p.end_index - p.start_index;
297 inline int DynamicPartition::ParentOfPart(
int part)
const {
299 DCHECK_LT(part, part_.size());
300 return part_[part].parent_part;
303 inline DynamicPartition::IterablePart DynamicPartition::ElementsInSamePartAs(
305 return ElementsInPart(PartOf(i));
308 inline uint64 DynamicPartition::FprintOfPart(
int part)
const {
310 DCHECK_LT(part, part_.size());
311 return part_[part].fprint;
314 inline int MergingPartition::GetRoot(
int node)
const {
316 DCHECK_LT(node, NumNodes());
319 const int parent = parent_[child];
320 if (parent == child)
return child;
325 inline void MergingPartition::SetParentAlongPathToRoot(
int node,
int parent) {
327 DCHECK_LT(node, NumNodes());
328 DCHECK_GE(parent, 0);
329 DCHECK_LT(parent, NumNodes());
332 const int old_parent = parent_[child];
333 parent_[child] = parent;
334 if (old_parent == child)
return;
339 inline void MergingPartition::ResetNode(
int node) {
341 DCHECK_LT(node, NumNodes());
342 parent_[node] = node;
343 part_size_[node] = 1;
348 #endif // OR_TOOLS_ALGORITHMS_DYNAMIC_PARTITION_H_