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 
18 namespace Gudhi {
19 
20 namespace coxeter_triangulation {
21 
22 typedef 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