3#include "storm-config.h"
14namespace modelchecker {
17template<
typename ValueType>
19 std::vector<ValueType>
const& rewards,
20 std::vector<ValueType>
const& oneStepTargetProbabilities)
21 : transitionMatrix(transitionMatrix),
22 originalRewards(rewards),
23 originalOneStepTargetProbabilities(oneStepTargetProbabilities),
24 backwardTransitions(transitionMatrix.transpose()),
25 p(transitionMatrix.getRowGroupCount()),
26 w(transitionMatrix.getRowGroupCount()),
28 targetProbabilities(oneStepTargetProbabilities) {
32template<
typename ValueType>
35 std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now();
37 ValueType lambda = computeLambda();
41 std::vector<ValueType> result(transitionMatrix.getRowGroupCount());
42 auto one = storm::utility::one<ValueType>();
44 result[state] = w[state] + (one - p[state]) * lambda;
48 ValueType max = storm::utility::zero<ValueType>();
49 uint64_t nonZeroCount = 0;
50 for (
auto const& e : result) {
53 max = std::max(max, e);
56 STORM_LOG_TRACE(
"DS-MPI computed " << nonZeroCount <<
" non-zero upper bounds and a maximal bound of " << max <<
".");
58 std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now();
59 STORM_LOG_TRACE(
"Computed upper bounds on rewards in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() <<
"ms.");
63template<
typename ValueType>
65 ValueType lambda = storm::utility::zero<ValueType>();
67 lambda = std::max(lambda, computeLambdaForChoice(state));
72template<
typename ValueType>
74 ValueType localLambda = storm::utility::zero<ValueType>();
75 uint64_t state = this->getStateForChoice(choice);
78 ValueType probSum = originalOneStepTargetProbabilities[choice];
79 for (
auto const& e : transitionMatrix.getRow(choice)) {
80 probSum += e.getValue() * p[e.getColumn()];
83 if (p[state] < probSum) {
84 STORM_LOG_TRACE(
"Condition (I) does apply for state " << state <<
" as " << p[state] <<
" < " << probSum <<
".");
86 localLambda = probSum - p[state];
87 ValueType nominator = originalRewards[choice];
88 for (
auto const& e : transitionMatrix.getRow(choice)) {
89 nominator += e.getValue() * w[e.getColumn()];
91 nominator -= w[state];
92 localLambda = nominator / localLambda;
94 STORM_LOG_TRACE(
"Condition (I) does not apply for state " << state << std::setprecision(30) <<
" as " << probSum <<
" <= " << p[state] <<
".");
100 ValueType rewardSum = originalRewards[choice];
101 for (
auto const& e : transitionMatrix.getRow(choice)) {
102 rewardSum += e.getValue() * w[e.getColumn()];
107 "Expected condition (II) to hold in state " << state <<
", but " << w[state] <<
" < " << rewardSum <<
".");
109 "Expected condition (II) to hold in state " << state <<
", but " << probSum <<
" != " << p[state] <<
".");
116template<
typename ValueType>
121template<
typename ValueType>
129 ValueType pa = dsmpi.targetProbabilities[a];
130 ValueType pb = dsmpi.targetProbabilities[b];
133 }
else if (pa == pb) {
134 return dsmpi.rewards[a] > dsmpi.rewards[b];
143template<
typename ValueType>
152 while (!queue.
empty()) {
157 visited.
set(currentState);
160 w[currentState] = rewards[currentState];
161 p[currentState] = targetProbabilities[currentState];
163 for (
auto const& e : backwardTransitions.getRow(currentState)) {
164 if (visited.
get(e.getColumn())) {
169 rewards[e.getColumn()] += e.getValue() * w[currentState];
170 targetProbabilities[e.getColumn()] += e.getValue() * p[currentState];
178template<
typename ValueType>
180 std::vector<ValueType>
const& rewards,
181 std::vector<ValueType>
const& oneStepTargetProbabilities)
186 for (uint64_t state = 0; state <
transitionMatrix.getRowGroupCount(); ++state) {
189 boost::optional<ValueType> minReward;
190 ValueType maxProb = storm::utility::zero<ValueType>();
192 for (uint64_t row = choice, endRow =
transitionMatrix.getRowGroupIndices()[state + 1]; row < endRow; ++row) {
193 choiceToState[row] = state;
197 minReward = this->rewards[row];
199 }
else if (this->
targetProbabilities[row] == maxProb && (!minReward || minReward.get() > this->rewards[row])) {
200 minReward = this->rewards[row];
205 setChoiceInState(state, choice);
209template<
typename ValueType>
211 ValueType lambda = storm::utility::zero<ValueType>();
213 lambda = std::max(lambda, this->computeLambdaForChoice(this->getChoiceInState(state)));
218template<
typename ValueType>
219uint64_t DsMpiMdpUpperRewardBoundsComputer<ValueType>::getStateForChoice(uint64_t choice)
const {
220 return choiceToState[choice];
223template<
typename ValueType>
231 uint64_t choiceA = dsmpi.getChoiceInState(a);
232 uint64_t choiceB = dsmpi.getChoiceInState(b);
234 ValueType pa = dsmpi.targetProbabilities[choiceA];
235 ValueType pb = dsmpi.targetProbabilities[choiceB];
238 }
else if (pa == pb) {
239 return dsmpi.rewards[choiceB] > dsmpi.rewards[choiceB];
248template<
typename ValueType>
249void DsMpiMdpUpperRewardBoundsComputer<ValueType>::sweep() {
252 DsMpiMdpPriorityLess<ValueType>(*
this));
257 while (!queue.empty()) {
262 visited.set(currentState);
265 uint64_t choiceInCurrentState = this->getChoiceInState(currentState);
266 this->w[currentState] = this->rewards[choiceInCurrentState];
267 this->p[currentState] = this->targetProbabilities[choiceInCurrentState];
269 for (
auto const& choiceEntry : this->backwardTransitions.getRow(currentState)) {
270 uint64_t predecessor = this->getStateForChoice(choiceEntry.getColumn());
271 if (visited.get(predecessor)) {
276 this->rewards[choiceEntry.getColumn()] += choiceEntry.getValue() * this->w[currentState];
277 this->targetProbabilities[choiceEntry.getColumn()] += choiceEntry.getValue() * this->p[currentState];
281 uint64_t currentChoiceInPredecessor = this->getChoiceInState(predecessor);
282 if (currentChoiceInPredecessor != choiceEntry.getColumn()) {
284 ValueType
const& newTargetProbability = this->targetProbabilities[choiceEntry.getColumn()];
285 ValueType
const& newReward = this->rewards[choiceEntry.getColumn()];
286 ValueType
const& currentTargetProbability = this->targetProbabilities[this->getChoiceInState(predecessor)];
287 ValueType
const& currentReward = this->rewards[this->getChoiceInState(predecessor)];
289 if (newTargetProbability > currentTargetProbability || (newTargetProbability == currentTargetProbability && newReward < currentReward)) {
290 setChoiceInState(predecessor, choiceEntry.getColumn());
295 queue.increase(predecessor);
300template<
typename ValueType>
301uint64_t DsMpiMdpUpperRewardBoundsComputer<ValueType>::getChoiceInState(uint64_t state)
const {
302 return policy[state];
305template<
typename ValueType>
306void DsMpiMdpUpperRewardBoundsComputer<ValueType>::setChoiceInState(uint64_t state, uint64_t choice) {
307 policy[state] = choice;
310template class DsMpiDtmcUpperRewardBoundsComputer<double>;
311template class DsMpiMdpUpperRewardBoundsComputer<double>;
313template class DsMpiDtmcUpperRewardBoundsComputer<storm::RationalNumber>;
314template class DsMpiMdpUpperRewardBoundsComputer<storm::RationalNumber>;
DsMpiDtmcPriorityLess(DsMpiDtmcUpperRewardBoundsComputer< ValueType > const &dsmpi)
bool operator()(storm::storage::sparse::state_type const &a, storm::storage::sparse::state_type const &b)
virtual void sweep()
Performs a Dijkstra sweep.
virtual ValueType computeLambda() const
Computes the lambda used for the estimation.
storm::storage::SparseMatrix< ValueType > const & transitionMatrix
ValueType computeLambdaForChoice(uint64_t choice) const
Computes the lambda just for the provided choice.
std::vector< ValueType > computeUpperBounds()
Computes upper bounds on the expected rewards.
DsMpiDtmcUpperRewardBoundsComputer(storm::storage::SparseMatrix< ValueType > const &transitionMatrix, std::vector< ValueType > const &rewards, std::vector< ValueType > const &oneStepTargetProbabilities)
Creates an object that can compute upper bounds on the expected rewards for the provided DTMC.
std::vector< ValueType > targetProbabilities
virtual uint64_t getStateForChoice(uint64_t choice) const
Retrieves the state associated with the given choice.
bool operator()(storm::storage::sparse::state_type const &a, storm::storage::sparse::state_type const &b)
DsMpiMdpPriorityLess(DsMpiMdpUpperRewardBoundsComputer< ValueType > const &dsmpi)
DsMpiMdpUpperRewardBoundsComputer(storm::storage::SparseMatrix< ValueType > const &transitionMatrix, std::vector< ValueType > const &rewards, std::vector< ValueType > const &oneStepTargetProbabilities)
Creates an object that can compute upper bounds on the minimal expected rewards for the provided MDP.
A bit vector that is internally represented as a vector of 64-bit values.
void set(uint64_t index, bool value=true)
Sets the given truth value at the given index.
bool get(uint64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
void increase(uint64_t element)
A class that holds a possibly non-square matrix in the compressed row storage format.
bool isEqual(ValueType const &value1, ValueType const &value2) const
#define STORM_LOG_TRACE(message)
#define STORM_LOG_WARN_COND(cond, message)
bool isZero(ValueType const &a)