Storm 1.11.1.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
SparseInfiniteHorizonHelper.cpp
Go to the documentation of this file.
2
13
14namespace storm {
15namespace modelchecker {
16namespace helper {
17
18template<typename ValueType, bool Nondeterministic>
20 : _transitionMatrix(transitionMatrix),
21 _markovianStates(nullptr),
22 _exitRates(nullptr),
23 _backwardTransitions(nullptr),
24 _longRunComponentDecomposition(nullptr) {
25 // Intentionally left empty.
26}
27
28template<typename ValueType, bool Nondeterministic>
30 storm::storage::BitVector const& markovianStates,
31 std::vector<ValueType> const& exitRates)
32 : _transitionMatrix(transitionMatrix),
33 _markovianStates(&markovianStates),
34 _exitRates(&exitRates),
35 _backwardTransitions(nullptr),
36 _longRunComponentDecomposition(nullptr) {
37 // Intentionally left empty.
38}
39
40template<typename ValueType, bool Nondeterministic>
42 std::vector<ValueType> const& exitRates)
43 : _transitionMatrix(transitionMatrix),
44 _markovianStates(nullptr),
45 _exitRates(&exitRates),
46 _backwardTransitions(nullptr),
47 _longRunComponentDecomposition(nullptr) {
48 // Intentionally left empty.
50
51template<typename ValueType, bool Nondeterministic>
53 STORM_LOG_WARN_COND(_backwardTransitions == nullptr, "Backwards transitions were provided but they were already computed or provided before.");
54 _backwardTransitions = &backwardTransitions;
56
57template<typename ValueType, bool Nondeterministic>
60 STORM_LOG_WARN_COND(_longRunComponentDecomposition == nullptr,
61 "Long Run Component Decomposition was provided but it was already computed or provided before.");
62 _longRunComponentDecomposition = &decomposition;
63}
64
65template<typename ValueType, bool Nondeterministic>
67 Environment const& env, storm::storage::BitVector const& psiStates) {
68 return computeLongRunAverageValues(
69 env, [&psiStates](uint64_t stateIndex) { return psiStates.get(stateIndex) ? storm::utility::one<ValueType>() : storm::utility::zero<ValueType>(); },
70 [](uint64_t) { return storm::utility::zero<ValueType>(); });
71}
72
73template<typename ValueType, bool Nondeterministic>
76 ValueGetter stateRewardsGetter;
77 if (rewardModel.hasStateRewards()) {
78 stateRewardsGetter = [&rewardModel](uint64_t stateIndex) { return rewardModel.getStateReward(stateIndex); };
79 } else {
80 stateRewardsGetter = [](uint64_t) { return storm::utility::zero<ValueType>(); };
81 }
82 ValueGetter actionRewardsGetter;
83 if (rewardModel.hasStateActionRewards() || rewardModel.hasTransitionRewards()) {
84 if (rewardModel.hasTransitionRewards()) {
85 actionRewardsGetter = [&](uint64_t globalChoiceIndex) {
86 return rewardModel.getStateActionAndTransitionReward(globalChoiceIndex, this->_transitionMatrix);
87 };
88 } else {
89 actionRewardsGetter = [&](uint64_t globalChoiceIndex) { return rewardModel.getStateActionReward(globalChoiceIndex); };
90 }
91 } else {
92 actionRewardsGetter = [](uint64_t) { return storm::utility::zero<ValueType>(); };
93 }
94
95 return computeLongRunAverageValues(env, stateRewardsGetter, actionRewardsGetter);
96}
97
98template<typename ValueType, bool Nondeterministic>
100 std::vector<ValueType> const* stateValues,
101 std::vector<ValueType> const* actionValues) {
102 ValueGetter stateValuesGetter;
103 if (stateValues) {
104 stateValuesGetter = [&stateValues](uint64_t stateIndex) { return (*stateValues)[stateIndex]; };
105 } else {
106 stateValuesGetter = [](uint64_t) { return storm::utility::zero<ValueType>(); };
107 }
108 ValueGetter actionValuesGetter;
109 if (actionValues) {
110 actionValuesGetter = [&actionValues](uint64_t globalChoiceIndex) { return (*actionValues)[globalChoiceIndex]; };
111 } else {
112 actionValuesGetter = [](uint64_t) { return storm::utility::zero<ValueType>(); };
113 }
115 return computeLongRunAverageValues(env, stateValuesGetter, actionValuesGetter);
116}
117
118template<typename ValueType, bool Nondeterministic>
120 ValueGetter const& stateRewardsGetter,
121 ValueGetter const& actionRewardsGetter) {
122 // We will compute the long run average value for each MEC individually and then set-up an Equation system to compute the value also at non-mec states.
123 // For a description of this approach see, e.g., Guck et al.: Modelling and Analysis of Markov Reward Automata (ATVA'14),
124 // https://doi.org/10.1007/978-3-319-11936-6_13
125
126 // Prepare an environment for the underlying solvers.
127 auto underlyingSolverEnvironment = env;
128 if (env.solver().isForceSoundness()) {
129 // For sound computations, the error in the MECS plus the error in the remaining system should not exceed the user defined precsion.
130 storm::RationalNumber newPrecision = env.solver().lra().getPrecision() / storm::utility::convertNumber<storm::RationalNumber>(2);
131 underlyingSolverEnvironment.solver().minMax().setPrecision(newPrecision);
132 underlyingSolverEnvironment.solver().minMax().setRelativeTerminationCriterion(env.solver().lra().getRelativeTerminationCriterion());
133 underlyingSolverEnvironment.solver().setLinearEquationSolverPrecision(newPrecision, env.solver().lra().getRelativeTerminationCriterion());
134 underlyingSolverEnvironment.solver().lra().setPrecision(newPrecision);
135 }
136
137 // If requested, allocate memory for the choices made
138 if (Nondeterministic && this->isProduceSchedulerSet()) {
139 if (!_producedOptimalChoices.is_initialized()) {
140 _producedOptimalChoices.emplace();
141 }
142 _producedOptimalChoices->resize(_transitionMatrix.getRowGroupCount());
143 }
144 STORM_LOG_ASSERT(Nondeterministic || !this->isProduceSchedulerSet(), "Scheduler production enabled for deterministic model.");
145
146 // Decompose the model to their bottom components (MECS or BSCCS)
147 createDecomposition();
148
149 // Compute the long-run average for all components in isolation.
150 // Set up some logging
151 std::string const componentString = (Nondeterministic ? std::string("Maximal end") : std::string("Bottom strongly connected")) +
152 (_longRunComponentDecomposition->size() == 1 ? std::string(" component") : std::string(" components"));
153 storm::utility::ProgressMeasurement progress(componentString);
154 progress.setMaxCount(_longRunComponentDecomposition->size());
155 progress.startNewMeasurement(0);
156 STORM_LOG_INFO("Computing long run average values for " << _longRunComponentDecomposition->size() << " " << componentString << " individually...");
157 std::vector<ValueType> componentLraValues;
158 componentLraValues.reserve(_longRunComponentDecomposition->size());
159 for (auto const& c : *_longRunComponentDecomposition) {
160 componentLraValues.push_back(computeLraForComponent(underlyingSolverEnvironment, stateRewardsGetter, actionRewardsGetter, c));
161 progress.updateProgress(componentLraValues.size());
162 }
163
164 // Solve the resulting SSP where end components are collapsed into single auxiliary states
165 STORM_LOG_INFO("Solving stochastic shortest path problem.");
166 return buildAndSolveSsp(underlyingSolverEnvironment, componentLraValues);
167}
168
169template<typename ValueType, bool Nondeterministic>
171 STORM_LOG_ASSERT((_markovianStates == nullptr) || (_exitRates != nullptr), "Inconsistent information given: Have Markovian states but no exit rates.");
172 return _exitRates != nullptr;
173}
174
175template<typename ValueType, bool Nondeterministic>
177 if (this->_backwardTransitions == nullptr) {
178 this->_computedBackwardTransitions =
179 std::make_unique<storm::storage::SparseMatrix<ValueType>>(this->_transitionMatrix.transpose(true, false)); // will drop zeroes
180 this->_backwardTransitions = this->_computedBackwardTransitions.get();
181 }
182}
183
186
190
191} // namespace helper
192} // namespace modelchecker
193} // namespace storm
SolverEnvironment & solver()
storm::RationalNumber const & getPrecision() const
LongRunAverageSolverEnvironment & lra()
Helper class for model checking queries that depend on the long run behavior of the (nondeterministic...
void provideBackwardTransitions(storm::storage::SparseMatrix< ValueType > const &backwardsTransitions)
Provides backward transitions that can be used during the computation.
std::vector< ValueType > computeLongRunAverageRewards(Environment const &env, storm::models::sparse::StandardRewardModel< ValueType > const &rewardModel)
Computes the long run average rewards, i.e., the average reward collected per time unit.
std::function< ValueType(uint64_t)> ValueGetter
Function mapping from indices to values.
void provideLongRunComponentDecomposition(storm::storage::Decomposition< LongRunComponentType > const &decomposition)
Provides the decomposition into long run components (BSCCs/MECs) that can be used during the computat...
SparseInfiniteHorizonHelper(storm::storage::SparseMatrix< ValueType > const &transitionMatrix)
Initializes the helper for a discrete time (i.e.
std::vector< ValueType > computeLongRunAverageProbabilities(Environment const &env, storm::storage::BitVector const &psiStates)
Computes the long run average probabilities, i.e., the fraction of the time we are in a psiState.
std::vector< ValueType > computeLongRunAverageValues(Environment const &env, std::vector< ValueType > const *stateValues=nullptr, std::vector< ValueType > const *actionValues=nullptr)
Computes the long run average value given the provided state and action-based rewards.
bool hasTransitionRewards() const
Retrieves whether the reward model has transition rewards.
ValueType getStateActionAndTransitionReward(uint_fast64_t choiceIndex, storm::storage::SparseMatrix< MatrixValueType > const &transitionMatrix) const
ValueType const & getStateReward(uint_fast64_t state) const
ValueType const & getStateActionReward(uint_fast64_t choiceIndex) const
Retrieves the state-action reward for the given choice.
bool hasStateRewards() const
Retrieves whether the reward model has state rewards.
bool hasStateActionRewards() const
Retrieves whether the reward model has state-action rewards.
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:16
bool get(uint64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
This class represents the decomposition of a model into blocks which are of the template type.
A class that holds a possibly non-square matrix in the compressed row storage format.
A class that provides convenience operations to display run times.
bool updateProgress(uint64_t count)
Updates the progress to the current count and prints it if the delay passed.
void setMaxCount(uint64_t maxCount)
Sets the maximal possible count.
void startNewMeasurement(uint64_t startCount)
Starts a new measurement, dropping all progress information collected so far.
#define STORM_LOG_INFO(message)
Definition logging.h:24
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:11
#define STORM_LOG_WARN_COND(cond, message)
Definition macros.h:38