Set_partition_iterator.h
1/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
2 * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
3 * Author(s): Siargey Kachanovich
4 *
5 * Copyright (C) 2019 Inria
6 *
7 * Modification(s):
8 * - YYYY/MM Author: Description of the modification
9 */
10
11#ifndef PERMUTAHEDRAL_REPRESENTATION_SET_PARTITION_ITERATOR_H_
12#define PERMUTAHEDRAL_REPRESENTATION_SET_PARTITION_ITERATOR_H_
13
14#include <vector>
15#include <limits>
16#include <boost/range/iterator_range.hpp>
17
18namespace Gudhi {
19
20namespace coxeter_triangulation {
21
22typedef unsigned uint;
23
28 : public boost::iterator_facade<Set_partition_iterator, std::vector<std::vector<uint>> const,
29 boost::forward_traversal_tag> {
30 using value_t = std::vector<std::vector<uint>>;
31
32 private:
33 friend class boost::iterator_core_access;
34
35 bool equal(Set_partition_iterator const& other) const { return (is_end_ && other.is_end_); }
36
37 value_t const& dereference() const { return value_; }
38
39 void update_value() {
40 for (uint i = 0; i < k_; i++) value_[i].clear();
41 for (uint i = 0; i < n_; i++) value_[rgs_[i]].push_back(i);
42 }
43
44 void increment() {
45 if (k_ <= 1) {
46 is_end_ = true;
47 return;
48 }
49 uint i = n_ - 1;
50 while (rgs_[i] + 1 > max_[i] || rgs_[i] + 1 >= k_) i--;
51 if (i == 0) {
52 is_end_ = true;
53 return;
54 }
55 rgs_[i]++;
56 uint mm = max_[i];
57 mm += (rgs_[i] >= mm);
58 max_[i + 1] = mm;
59 while (++i < n_) {
60 rgs_[i] = 0;
61 max_[i + 1] = mm;
62 }
63 uint p = k_;
64 if (mm < p) do {
65 max_[i] = p;
66 --i;
67 --p;
68 rgs_[i] = p;
69 } while (max_[i] < p);
70 update_value();
71 }
72
73 public:
74 Set_partition_iterator(const uint& n, const uint& k)
75 : value_(k), rgs_(n, 0), max_(n + 1), is_end_(n == 0), n_(n), k_(k) {
76 max_[0] = std::numeric_limits<uint>::max();
77 for (uint i = 0; i <= n - k; ++i) value_[0].push_back(i);
78 for (uint i = n - k + 1, j = 1; i < n; ++i, ++j) {
79 rgs_[i] = j;
80 value_[j].push_back(i);
81 }
82 for (uint i = 1; i <= n; i++) max_[i] = rgs_[i - 1] + 1;
83 update_value();
84 }
85
86 // Used for creating an end iterator
87 Set_partition_iterator() : is_end_(true), n_(0), k_(0) {}
88
89 void reinitialize() {
90 if (n_ > 0) is_end_ = false;
91 for (uint i = 0; i <= n_ - k_; ++i) rgs_[i] = 0;
92 for (uint i = n_ - k_ + 1, j = 1; i < n_; ++i, ++j) rgs_[i] = j;
93 for (uint i = 1; i <= n_; i++) max_[i] = rgs_[i - 1] + 1;
94 update_value();
95 }
96
97 private:
98 value_t value_; // the dereference value
99 std::vector<uint> rgs_; // restricted growth string
100 std::vector<uint> max_; // max_[i] = max(rgs_[0],...,rgs[i-1]) + 1
101 bool is_end_; // is true when the current permutation is the final one
102
103 uint n_;
104 uint k_;
105};
106
107} // namespace coxeter_triangulation
108
109} // namespace Gudhi
110
111#endif
Class that allows the user to generate set partitions of a set {0,...,n-1} in k parts.
Definition: Set_partition_iterator.h:29
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14