/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria * * Modification(s): * - YYYY/MM Author: Description of the modification */ #ifndef PERMUTAHEDRAL_REPRESENTATION_SET_PARTITION_ITERATOR_H_ #define PERMUTAHEDRAL_REPRESENTATION_SET_PARTITION_ITERATOR_H_ #include #include #include namespace Gudhi { namespace coxeter_triangulation { typedef unsigned uint; /** \brief Class that allows the user to generate set partitions of a set {0,...,n-1} in k parts. * */ class Set_partition_iterator : public boost::iterator_facade> const, boost::forward_traversal_tag> { using value_t = std::vector>; private: friend class boost::iterator_core_access; bool equal(Set_partition_iterator const& other) const { return (is_end_ && other.is_end_); } value_t const& dereference() const { return value_; } void update_value() { for (uint i = 0; i < k_; i++) value_[i].clear(); for (uint i = 0; i < n_; i++) value_[rgs_[i]].push_back(i); } void increment() { if (k_ <= 1) { is_end_ = true; return; } uint i = n_ - 1; while (rgs_[i] + 1 > max_[i] || rgs_[i] + 1 >= k_) i--; if (i == 0) { is_end_ = true; return; } rgs_[i]++; uint mm = max_[i]; mm += (rgs_[i] >= mm); max_[i + 1] = mm; while (++i < n_) { rgs_[i] = 0; max_[i + 1] = mm; } uint p = k_; if (mm < p) do { max_[i] = p; --i; --p; rgs_[i] = p; } while (max_[i] < p); update_value(); } public: Set_partition_iterator(const uint& n, const uint& k) : value_(k), rgs_(n, 0), max_(n + 1), is_end_(n == 0), n_(n), k_(k) { max_[0] = std::numeric_limits::max(); for (uint i = 0; i <= n - k; ++i) value_[0].push_back(i); for (uint i = n - k + 1, j = 1; i < n; ++i, ++j) { rgs_[i] = j; value_[j].push_back(i); } for (uint i = 1; i <= n; i++) max_[i] = rgs_[i - 1] + 1; update_value(); } // Used for creating an end iterator Set_partition_iterator() : is_end_(true), n_(0), k_(0) {} void reinitialize() { if (n_ > 0) is_end_ = false; for (uint i = 0; i <= n_ - k_; ++i) rgs_[i] = 0; for (uint i = n_ - k_ + 1, j = 1; i < n_; ++i, ++j) rgs_[i] = j; for (uint i = 1; i <= n_; i++) max_[i] = rgs_[i - 1] + 1; update_value(); } private: value_t value_; // the dereference value std::vector rgs_; // restricted growth string std::vector max_; // max_[i] = max(rgs_[0],...,rgs[i-1]) + 1 bool is_end_; // is true when the current permutation is the final one uint n_; uint k_; }; } // namespace coxeter_triangulation } // namespace Gudhi #endif