178 lines
6.0 KiB

  1. /*
  2. * GraphTransitions.h
  3. *
  4. * Created on: 17.11.2012
  5. * Author: Christian Dehnert
  6. */
  7. #ifndef STORM_MODELS_GRAPHTRANSITIONS_H_
  8. #define STORM_MODELS_GRAPHTRANSITIONS_H_
  9. #include "src/storage/SparseMatrix.h"
  10. #include <algorithm>
  11. #include <memory>
  12. namespace storm {
  13. namespace models {
  14. /*!
  15. * This class stores the predecessors of all states in a state space of the
  16. * given size.
  17. */
  18. template <class T>
  19. class GraphTransitions {
  20. public:
  21. /*!
  22. * Just typedef the iterator as a pointer to the index type.
  23. */
  24. typedef const uint_fast64_t * const statePredecessorIterator;
  25. //! Constructor
  26. /*!
  27. * Constructs an object representing the graph structure of the given
  28. * transition relation, which is given by a sparse matrix.
  29. * @param transitionMatrix The (0-based) matrix representing the transition
  30. * relation.
  31. * @param forward If set to true, this objects will store the graph structure
  32. * of the backwards transition relation.
  33. */
  34. GraphTransitions(std::shared_ptr<storm::storage::SparseMatrix<T>> transitionMatrix, bool forward)
  35. : successorList(nullptr), stateIndications(nullptr), numberOfStates(transitionMatrix->getRowCount()), numberOfNonZeroTransitions(transitionMatrix->getNonZeroEntryCount()) {
  36. if (forward) {
  37. this->initializeForward(transitionMatrix);
  38. } else {
  39. this->initializeBackward(transitionMatrix);
  40. }
  41. }
  42. //! Destructor
  43. /*!
  44. * Destructor. Frees the internal storage.
  45. */
  46. ~GraphTransitions() {
  47. if (this->successorList != nullptr) {
  48. delete[] this->successorList;
  49. }
  50. if (this->stateIndications != nullptr) {
  51. delete[] this->stateIndications;
  52. }
  53. }
  54. /*!
  55. * Returns an iterator to the successors of the given state.
  56. * @param state The state for which to get the successor iterator.
  57. * @return An iterator to the predecessors of the given states.
  58. */
  59. statePredecessorIterator beginStateSuccessorsIterator(uint_fast64_t state) const {
  60. return this->successorList + this->stateIndications[state];
  61. }
  62. /*!
  63. * Returns an iterator referring to the element after the successors of
  64. * the given state.
  65. * @param row The state for which to get the iterator.
  66. * @return An iterator referring to the element after the successors of
  67. * the given state.
  68. */
  69. statePredecessorIterator endStateSuccessorsIterator(uint_fast64_t state) const {
  70. return this->successorList + this->stateIndications[state + 1];
  71. }
  72. private:
  73. /*!
  74. * Initializes this graph transitions object using the forward transition
  75. * relation given by means of a sparse matrix.
  76. */
  77. void initializeForward(std::shared_ptr<storm::storage::SparseMatrix<T>> transitionMatrix) {
  78. this->successorList = new uint_fast64_t[numberOfNonZeroTransitions];
  79. this->stateIndications = new uint_fast64_t[numberOfStates + 1];
  80. // First, we copy the index list from the sparse matrix as this will
  81. // stay the same.
  82. std::copy(transitionMatrix->getRowIndicationsPointer().begin(), transitionMatrix->getRowIndicationsPointer().end(), this->stateIndications);
  83. // Now we can iterate over all rows of the transition matrix and record
  84. // the target state.
  85. for (uint_fast64_t i = 0, currentNonZeroElement = 0; i < numberOfStates; i++) {
  86. for (auto rowIt = transitionMatrix->beginConstColumnIterator(i); rowIt != transitionMatrix->endConstColumnIterator(i); ++rowIt) {
  87. this->stateIndications[currentNonZeroElement++] = *rowIt;
  88. }
  89. }
  90. }
  91. /*!
  92. * Initializes this graph transitions object using the backwards transition
  93. * relation, whose forward transition relation is given by means of a sparse
  94. * matrix.
  95. */
  96. void initializeBackward(std::shared_ptr<storm::storage::SparseMatrix<T>> transitionMatrix) {
  97. this->successorList = new uint_fast64_t[numberOfNonZeroTransitions];
  98. this->stateIndications = new uint_fast64_t[numberOfStates + 1];
  99. // First, we need to count how many backward transitions each state has.
  100. // NOTE: We disregard the diagonal here, as we only consider "true"
  101. // predecessors.
  102. for (uint_fast64_t i = 0; i < numberOfStates; i++) {
  103. for (auto rowIt = transitionMatrix->beginConstColumnIterator(i); rowIt != transitionMatrix->endConstColumnIterator(i); ++rowIt) {
  104. this->stateIndications[*rowIt + 1]++;
  105. }
  106. }
  107. // Now compute the accumulated offsets.
  108. for (uint_fast64_t i = 1; i < numberOfStates; i++) {
  109. this->stateIndications[i] = this->stateIndications[i - 1] + this->stateIndications[i];
  110. }
  111. // Put a sentinel element at the end of the indices list. This way,
  112. // for each state i the range of indices can be read off between
  113. // state_indices_list[i] and state_indices_list[i + 1].
  114. this->stateIndications[numberOfStates] = numberOfNonZeroTransitions;
  115. // Create an array that stores the next index for each state. Initially
  116. // this corresponds to the previously computed accumulated offsets.
  117. uint_fast64_t* nextIndicesList = new uint_fast64_t[numberOfStates];
  118. std::copy(stateIndications, stateIndications + numberOfStates, nextIndicesList);
  119. // Now we are ready to actually fill in the list of predecessors for
  120. // every state. Again, we start by considering all but the last row.
  121. for (uint_fast64_t i = 0; i < numberOfStates; i++) {
  122. for (auto rowIt = transitionMatrix->beginConstColumnIterator(i); rowIt != transitionMatrix->endConstColumnIterator(i); ++rowIt) {
  123. this->successorList[nextIndicesList[*rowIt]++] = i;
  124. }
  125. }
  126. // Now we can dispose of the auxiliary array.
  127. delete[] nextIndicesList;
  128. }
  129. /*! A list of successors for *all* states. */
  130. uint_fast64_t* successorList;
  131. /*!
  132. * A list of indices indicating at which position in the global array the
  133. * successors of a state can be found.
  134. */
  135. uint_fast64_t* stateIndications;
  136. /*!
  137. * Store the number of states to determine the highest index at which the
  138. * state_indices_list may be accessed.
  139. */
  140. uint_fast64_t numberOfStates;
  141. /*!
  142. * Store the number of non-zero transition entries to determine the highest
  143. * index at which the predecessor_list may be accessed.
  144. */
  145. uint_fast64_t numberOfNonZeroTransitions;
  146. };
  147. } // namespace models
  148. } // namespace storm
  149. #endif /* STORM_MODELS_GRAPHTRANSITIONS_H_ */