Permutation_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_PERMUTATION_ITERATOR_H_
12 #define PERMUTAHEDRAL_REPRESENTATION_PERMUTATION_ITERATOR_H_
13 
14 #include <cstdlib> // for std::size_t
15 #include <vector>
16 
17 #include <boost/range/iterator_range.hpp>
18 
19 namespace Gudhi {
20 
21 namespace coxeter_triangulation {
22 
23 typedef unsigned uint;
24 
29  : public boost::iterator_facade<Permutation_iterator, std::vector<uint> const, boost::forward_traversal_tag> {
30  using value_t = std::vector<uint>;
31 
32  private:
33  friend class boost::iterator_core_access;
34 
35  bool equal(Permutation_iterator const& other) const { return (is_end_ && other.is_end_); }
36 
37  value_t const& dereference() const { return value_; }
38 
39  void swap_two_indices(std::size_t i, std::size_t j) {
40  uint t = value_[i];
41  value_[i] = value_[j];
42  value_[j] = t;
43  }
44 
45  void elementary_increment() {
46  uint j = 0;
47  while (d_[j] == j + 1) {
48  d_[j] = 0;
49  ++j;
50  }
51  if (j == n_ - 1) {
52  is_end_ = true;
53  return;
54  }
55  uint k = j + 1;
56  uint x = (k % 2 ? d_[j] : 0);
57  swap_two_indices(k, x);
58  ++d_[j];
59  }
60 
61  void elementary_increment_optim_3() {
62  if (ct_ != 0) {
63  --ct_;
64  swap_two_indices(1 + (ct_ % 2), 0);
65  } else {
66  ct_ = 5;
67  uint j = 2;
68  while (d_[j] == j + 1) {
69  d_[j] = 0;
70  ++j;
71  }
72  if (j == n_ - 1) {
73  is_end_ = true;
74  return;
75  }
76  uint k = j + 1;
77  uint x = (k % 2 ? d_[j] : 0);
78  swap_two_indices(k, x);
79  ++d_[j];
80  }
81  }
82 
83  void increment() {
84  if (optim_3_)
85  elementary_increment_optim_3();
86  else
87  elementary_increment();
88  }
89 
90  public:
91  Permutation_iterator(const uint& n) : value_(n), is_end_(n == 0), optim_3_(n >= 3), n_(n), d_(n), ct_(5) {
92  for (uint i = 0; i < n; ++i) {
93  value_[i] = i;
94  d_[i] = 0;
95  }
96  if (n > 0) d_[n - 1] = -1;
97  }
98 
99  // Used for the creating an end iterator
100  Permutation_iterator() : is_end_(true), n_(0) {}
101 
102  void reinitialize() {
103  if (n_ > 0) is_end_ = false;
104  }
105 
106  private:
107  value_t value_; // the dereference value
108  bool is_end_; // is true when the current permutation is the final one
109  bool optim_3_; // true if n>=3. for n >= 3, the algorithm is optimized
110 
111  uint n_;
112  std::vector<uint> d_; // mix radix digits with radix [2 3 4 ... n-1 (sentinel=-1)]
113  uint ct_; // counter with values in {0,...,5} used in the n>=3 optimization.
114 };
115 
116 } // namespace coxeter_triangulation
117 
118 } // namespace Gudhi
119 
120 #endif
Class that allows the user to generate permutations. Based on the optimization of the Heap's algorith...
Definition: Permutation_iterator.h:29
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14