Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
SubsetEnumerator.cpp
Go to the documentation of this file.
1#include "SubsetEnumerator.h"
2
5
6namespace storm {
7namespace storage {
8namespace geometry {
9
10template<typename DataType>
11SubsetEnumerator<DataType>::SubsetEnumerator(uint_fast64_t n, uint_fast64_t k, DataType const& data, SubsetFilter subsetFilter)
12 : n(n), k(k), data(data), filter(subsetFilter) {
13 // Intentionally left empty
14}
15
16template<typename DataType>
18 // Intentionally left empty
19}
20
21template<typename DataType>
22std::vector<uint_fast64_t> const& SubsetEnumerator<DataType>::getCurrentSubset() {
23 return this->current;
24}
25
26template<typename DataType>
28 if (n < k) {
29 return false;
30 }
31 // set the upper boundaries first.
32 upperBoundaries.clear();
33 upperBoundaries.reserve(k);
34 for (uint_fast64_t bound = (n - k); bound < n; ++bound) {
35 upperBoundaries.push_back(bound);
36 }
37 // now set the current subset to the very first one
38 current.clear();
39 current.reserve(k);
40 uint_fast64_t newItem = 0;
41 while (current.size() != k && newItem <= upperBoundaries[current.size()]) {
42 // Check if it is okay to add the new item...
43 if (filter(current, newItem, data)) {
44 current.push_back(newItem);
45 }
46 ++newItem;
47 }
48 // Note that we only insert things into the vector if it is "okay" to do so.
49 // Hence, we have failed iff we were not able to insert k elements.
50 return current.size() == k;
51}
52
53template<typename DataType>
55 // The currentSelection will be the numbers that are already inside of our new subset.
56 std::vector<uint_fast64_t> currentSelection(current);
57 currentSelection.pop_back();
58 uint_fast64_t pos = k - 1;
59 while (true) {
60 // check whether we can increment at the current position
61 if (current[pos] == upperBoundaries[pos]) {
62 if (pos == 0) {
63 // we already moved to the very left and still can not increment.
64 // Hence, we are already at the last subset
65 return false;
66 }
67 currentSelection.pop_back();
68 --pos;
69 } else {
70 ++current[pos];
71 // check if the new subset is inside our filter
72 if (filter(currentSelection, current[pos], data)) {
73 // it is, so add it and go on with the position on the right
74 currentSelection.push_back(current[pos]);
75 ++pos;
76 if (pos == k) {
77 // we are already at the very right.
78 // Hence, we have found our new subset of size k
79 return true;
80 }
81 // initialize the value at the new position
82 current[pos] = current[pos - 1];
83 }
84 }
85 }
86}
87
88template<typename DataType>
89bool SubsetEnumerator<DataType>::trueFilter(std::vector<uint_fast64_t> const&, uint_fast64_t const&, DataType const&) {
90 return true;
91}
92
98} // namespace geometry
99} // namespace storage
100} // namespace storm
This class can be used to enumerate all k-sized subsets of {0,...,n-1}.
static bool trueFilter(std::vector< uint_fast64_t > const &subset, uint_fast64_t const &item, DataType const &data)
std::vector< uint_fast64_t > const & getCurrentSubset()
bool(* SubsetFilter)(std::vector< uint_fast64_t > const &subset, uint_fast64_t const &item, DataType const &data)
SubsetEnumerator(uint_fast64_t n, uint_fast64_t k, DataType const &data=DataType(), SubsetFilter subsetFilter=trueFilter)