Storm 1.11.1.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
permutation.cpp
Go to the documentation of this file.
2
3#include <algorithm>
4#include <deque>
5#include <numeric>
6#include <random>
7
14
16
20std::string orderKindtoString(OrderKind order) {
21 switch (order) {
22 case OrderKind::Bfs:
23 return "bfs";
24 case OrderKind::Dfs:
25 return "dfs";
27 return "reverse-bfs";
29 return "reverse-dfs";
31 return "random";
32 }
33 STORM_LOG_ASSERT(false, "unreachable");
34 return "";
35}
36
37OrderKind orderKindFromString(std::string const& order) {
39 if (order == orderKindtoString(kind)) {
40 return kind;
41 }
42 }
43 STORM_LOG_ASSERT(false, "Unknown order kind");
44 return OrderKind::Bfs;
45}
46
47std::vector<std::string> orderKinds() {
48 std::vector<std::string> kinds;
50 kinds.push_back(orderKindtoString(kind));
51 }
52 return kinds;
53}
54
55std::vector<index_type> createRandomPermutation(index_type size) {
56 std::random_device rd;
57 return createRandomPermutation(size, rd());
58}
59
60std::vector<index_type> createRandomPermutation(index_type size, index_type seed) {
61 std::vector<index_type> permutation(size);
62 std::iota(permutation.begin(), permutation.end(), 0);
63 // The random number engine below assumes that it operates on 64-bit unsigned integers.
64 static_assert(std::is_same_v<index_type, uint64_t>, "index_type is assumed to be a 64-bit unsigned integer");
65 std::shuffle(permutation.begin(), permutation.end(), std::mt19937_64(seed));
66 return permutation;
67}
68
69template<typename ValueType>
70std::vector<index_type> createPermutation(OrderKind order, storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
71 storm::storage::BitVector const& initialStates) {
72 if (order == OrderKind::Random) {
73 return createRandomPermutation(transitionMatrix.getRowGroupCount());
74 }
76 "Unknown order kind");
77 STORM_LOG_ASSERT(initialStates.size() == transitionMatrix.getRowGroupCount(), "Unexpected dimensions of initial states and transition matrix.");
78 STORM_LOG_ASSERT(initialStates.size() == transitionMatrix.getColumnCount(), "Unexpected dimensions of initial states and transition matrix.");
79 std::vector<index_type> permutation;
80 permutation.reserve(transitionMatrix.getRowGroupCount());
81
82 std::deque<index_type> stack(initialStates.begin(), initialStates.end());
83 storm::storage::BitVector discoveredStates = initialStates;
84 bool const useFifoStack = order == OrderKind::Bfs || order == OrderKind::ReverseBfs;
85
86 while (!stack.empty()) {
87 auto current = stack.front();
88 stack.pop_front();
89 permutation.push_back(current);
90 for (auto const& entry : transitionMatrix.getRowGroup(current)) {
91 if (auto const successor = entry.getColumn(); !discoveredStates.get(successor)) {
92 discoveredStates.set(successor, true);
93 if (useFifoStack) {
94 stack.push_back(successor);
95 } else {
96 stack.push_front(successor);
97 }
98 }
99 }
100 }
101 if (order == OrderKind::ReverseDfs || order == OrderKind::ReverseBfs) {
102 reversePermutationInPlace(permutation);
103 }
104 return permutation;
105}
106
107std::vector<index_type> invertPermutation(std::vector<index_type> const& permutation) {
108 std::vector<index_type> inverted(permutation.size());
109 for (index_type i = 0; i < permutation.size(); ++i) {
110 inverted[permutation[i]] = i;
111 }
112 return inverted;
113}
114
115void reversePermutationInPlace(std::vector<index_type>& permutation) {
116 auto const max = permutation.size() - 1;
117 for (auto& i : permutation) {
118 i = max - i;
119 }
120}
121
122bool isValidPermutation(std::vector<index_type> const& permutation) {
123 storage::BitVector occurring(permutation.size(), false);
124 for (auto i : permutation) {
125 if (occurring.get(i)) {
126 return false;
127 }
128 occurring.set(i, true);
129 }
130 return occurring.full();
131}
132
133template std::vector<index_type> createPermutation(OrderKind order, storm::storage::SparseMatrix<double> const& transitionMatrix,
134 storm::storage::BitVector const& initialStates);
135template std::vector<index_type> createPermutation(OrderKind order, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix,
136 storm::storage::BitVector const& initialStates);
137template std::vector<index_type> createPermutation(OrderKind order, storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix,
138 storm::storage::BitVector const& initialStates);
139template std::vector<index_type> createPermutation(OrderKind order, storm::storage::SparseMatrix<storm::Interval> const& transitionMatrix,
140 storm::storage::BitVector const& initialStates);
141
142} // namespace storm::utility::permutation
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:16
bool full() const
Retrieves whether all bits are set in this bit vector.
const_iterator end() const
Returns an iterator pointing at the element past the back of the bit vector.
void set(uint64_t index, bool value=true)
Sets the given truth value at the given index.
const_iterator begin() const
Returns an iterator to the indices of the set bits in the bit vector.
size_t size() const
Retrieves the number of bits this bit vector can store.
bool get(uint64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
A class that holds a possibly non-square matrix in the compressed row storage format.
const_rows getRowGroup(index_type rowGroup) const
Returns an object representing the given row group.
index_type getRowGroupCount() const
Returns the number of row groups in the matrix.
index_type getColumnCount() const
Returns the number of columns of the matrix.
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:11
OrderKind
The order in which the states of a matrix are visited in a depth-first search or breadth-first search...
Definition permutation.h:21
std::vector< index_type > createRandomPermutation(index_type size)
Creates a random (uniformly distributed) permutation of the given size.
std::string orderKindtoString(OrderKind order)
Converts the given order to a string.
std::vector< index_type > createPermutation(OrderKind order, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::BitVector const &initialStates)
Creates a permutation that orders the states of the given matrix in the given exploration order.
void reversePermutationInPlace(std::vector< index_type > &permutation)
Reverses the given permutation.
std::vector< index_type > invertPermutation(std::vector< index_type > const &permutation)
Inverts the given permutation.
std::vector< std::string > orderKinds()
Returns a list of possible order kinds.
OrderKind orderKindFromString(std::string const &order)
Gets the order from the given string.
bool isValidPermutation(std::vector< index_type > const &permutation)
Returns true if the given vector is a permutation of the numbers 0, 1, ..., n-1 for n = permutation....
ValueType max(ValueType const &first, ValueType const &second)