30#ifndef OR_TOOLS_ALGORITHMS_DYNAMIC_PARTITION_H_
31#define OR_TOOLS_ALGORITHMS_DYNAMIC_PARTITION_H_
37#include "absl/log/check.h"
38#include "absl/types/span.h"
74 int PartOf(
int element)
const;
110 void Refine(absl::Span<const int> distinguished_subset);
120 std::string
DebugString(
bool sort_parts_lexicographically)
const;
140 std::vector<int> element_;
143 std::vector<int> index_of_;
146 std::vector<int> part_of_;
163 Part() : start_index(0), end_index(0), parent_part(0), fprint(0) {}
164 Part(
int start_index,
int end_index,
int parent_part, uint64_t fprint)
165 : start_index(start_index),
166 end_index(end_index),
167 parent_part(parent_part),
170 std::vector<Part> part_;
175 std::vector<int> tmp_counter_of_part_;
176 std::vector<int> tmp_affected_parts_;
181 std::vector<int>::const_iterator
end()
const {
return end_; }
183 std::vector<int>::const_iterator
end_;
189 const std::vector<int>::const_iterator& e)
204 void Reset(
int num_nodes);
261 void SetParentAlongPathToRoot(
int node,
int parent);
263 std::vector<int> parent_;
264 std::vector<int> part_size_;
267 std::vector<bool> tmp_part_bit_;
276 : part_of_(num_elements, 0),
277 size_of_part_(num_elements > 0 ? 1 : 0, num_elements) {}
280 int NumParts()
const {
return size_of_part_.size(); }
281 int PartOf(
int element)
const {
return part_of_[element]; }
282 int SizeOfPart(
int part)
const {
return size_of_part_[part]; }
284 void Refine(absl::Span<const int> distinguished_subset);
289 template <
typename T>
290 std::vector<absl::Span<const T>>
GetParts(std::vector<T>* buffer);
293 std::vector<int> part_of_;
294 std::vector<int> size_of_part_;
297 std::vector<int> temp_to_clean_;
298 std::vector<int> temp_data_by_part_;
307 return IterablePart(element_.begin() + part_[i].start_index,
308 element_.begin() + part_[i].end_index);
312 DCHECK_GE(element, 0);
313 DCHECK_LT(element, part_of_.size());
314 return part_of_[element];
319 DCHECK_LT(part, part_.size());
320 const Part& p = part_[part];
321 return p.end_index - p.start_index;
326 DCHECK_LT(part, part_.size());
327 return part_[part].parent_part;
337 DCHECK_LT(part, part_.size());
338 return part_[part].fprint;
346 const int parent = parent_[child];
347 if (parent == child)
return child;
352inline void MergingPartition::SetParentAlongPathToRoot(
int node,
int parent) {
355 DCHECK_GE(parent, 0);
359 const int old_parent = parent_[child];
360 parent_[child] = parent;
361 if (old_parent == child)
return;
369 parent_[node] = node;
370 part_size_[node] = 1;
375 std::vector<T>* buffer) {
376 const int num_elements = part_of_.size();
377 const int num_parts = size_of_part_.size();
378 buffer->resize(num_elements);
380 std::vector<absl::Span<const T>> result(num_parts);
381 if (result.empty())
return result;
384 std::vector<int>& starts = temp_data_by_part_;
385 starts.resize(num_parts, 0);
386 for (
int i = 1; i < num_parts; ++i) {
387 starts[i] = starts[i - 1] + size_of_part_[i - 1];
391 for (
int i = 0; i < num_parts; ++i) {
392 result[i] = absl::MakeSpan(&(*buffer)[starts[i]], size_of_part_[i]);
396 for (
int element = 0; element < num_elements; ++element) {
397 (*buffer)[starts[part_of_[element]]++] = T(element);
int ParentOfPart(int part) const
const std::vector< int > & ElementsInHierarchicalOrder() const
int NumElements() const
Accessors.
std::string DebugString(bool sort_parts_lexicographically) const
IterablePart ElementsInSamePartAs(int i) const
int SizeOfPart(int part) const
void UndoRefineUntilNumPartsEqual(int original_num_parts)
uint64_t FprintOfPart(int part) const
void Refine(absl::Span< const int > distinguished_subset)
IterablePart ElementsInPart(int i) const
*** Implementation of inline methods of the above classes. ***
int PartOf(int element) const
DynamicPartition(int num_elements)
void KeepOnlyOneNodePerPart(std::vector< int > *nodes)
int NumNodesInSamePartAs(int node)
int MergePartsOf(int node1, int node2)
void Reset(int num_nodes)
MergingPartition(int num_nodes)
int FillEquivalenceClasses(std::vector< int > *node_equivalence_classes)
MergingPartition()
At first, all nodes are in their own singleton part.
int GetRoot(int node) const
std::string DebugString()
int GetRootAndCompressPath(int node)
int PartOf(int element) const
std::vector< absl::Span< const T > > GetParts(std::vector< T > *buffer)
void Refine(absl::Span< const int > distinguished_subset)
int SizeOfPart(int part) const
SimpleDynamicPartition(int num_elements)
In SWIG mode, we don't want anything besides these top-level includes.
int value_type
These typedefs allow this iterator to be used within testing::ElementsAre.
std::vector< int >::const_iterator end_
std::vector< int >::const_iterator begin_
IterablePart(const std::vector< int >::const_iterator &b, const std::vector< int >::const_iterator &e)
std::vector< int >::const_iterator begin() const
std::vector< int >::const_iterator end() const
std::vector< int >::const_iterator const_iterator