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