|
@ -159,7 +159,7 @@ namespace storm { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename ValueType, typename ComponentType, LraViTransitionsType TransitionsType> |
|
|
template <typename ValueType, typename ComponentType, LraViTransitionsType TransitionsType> |
|
|
ValueType LraViHelper<ValueType, ComponentType, TransitionsType>::performValueIteration(Environment const& env, ValueGetter const& stateValueGetter, ValueGetter const& actionValueGetter, std::vector<ValueType> const* exitRates, storm::solver::OptimizationDirection const* dir, std::vector<uint64_t>* choices) { |
|
|
|
|
|
|
|
|
ValueType LraViHelper<ValueType, ComponentType, TransitionsType>::performValueIteration(Environment const& env, ValueGetter const& stateValueGetter, ValueGetter const& actionValueGetter, std::vector<ValueType> const* exitRates, storm::solver::OptimizationDirection const* dir, std::vector<uint64_t>* choices, std::vector<ValueType>* choiceValues) { |
|
|
initializeNewValues(stateValueGetter, actionValueGetter, exitRates); |
|
|
initializeNewValues(stateValueGetter, actionValueGetter, exitRates); |
|
|
ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().lra().getPrecision()); |
|
|
ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().lra().getPrecision()); |
|
|
bool relative = env.solver().lra().getRelativeTerminationCriterion(); |
|
|
bool relative = env.solver().lra().getRelativeTerminationCriterion(); |
|
@ -219,7 +219,7 @@ namespace storm { |
|
|
if(!gameNondetTs()) { |
|
|
if(!gameNondetTs()) { |
|
|
prepareNextIteration(env); |
|
|
prepareNextIteration(env); |
|
|
} |
|
|
} |
|
|
performIterationStep(env, dir, choices); |
|
|
|
|
|
|
|
|
performIterationStep(env, dir, choices, choiceValues); |
|
|
} |
|
|
} |
|
|
if(gameNondetTs()) { |
|
|
if(gameNondetTs()) { |
|
|
storm::utility::vector::applyPointwise<ValueType, ValueType>(xNew(), xNew(), [&iter] (ValueType const& x_i) -> ValueType { return x_i / (double)iter; }); |
|
|
storm::utility::vector::applyPointwise<ValueType, ValueType>(xNew(), xNew(), [&iter] (ValueType const& x_i) -> ValueType { return x_i / (double)iter; }); |
|
@ -358,7 +358,20 @@ namespace storm { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
template <typename ValueType, typename ComponentType, LraViTransitionsType TransitionsType> |
|
|
template <typename ValueType, typename ComponentType, LraViTransitionsType TransitionsType> |
|
|
void LraViHelper<ValueType, ComponentType, TransitionsType>::performIterationStep(Environment const& env, storm::solver::OptimizationDirection const* dir, std::vector<uint64_t>* choices) { |
|
|
|
|
|
|
|
|
void LraViHelper<ValueType, ComponentType, TransitionsType>::setInputModelChoiceValues(std::vector<ValueType>& choiceValues, std::vector<ValueType> const& localMecChoiceValues) const { |
|
|
|
|
|
// Transform the local choiceValues (within this mec) to choice values for the input model
|
|
|
|
|
|
uint64_t localState = 0; |
|
|
|
|
|
for (auto const& element : _component) { |
|
|
|
|
|
uint64_t elementState = element.first; |
|
|
|
|
|
uint64_t rowIndex = _transitionMatrix.getRowGroupIndices()[elementState]; |
|
|
|
|
|
uint64_t rowGroupSize = _transitionMatrix.getRowGroupEntryCount(elementState); |
|
|
|
|
|
std::copy(localMecChoiceValues.begin(), localMecChoiceValues.begin() + rowGroupSize, &choiceValues.at(rowIndex)); |
|
|
|
|
|
localState++; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
template <typename ValueType, typename ComponentType, LraViTransitionsType TransitionsType> |
|
|
|
|
|
void LraViHelper<ValueType, ComponentType, TransitionsType>::performIterationStep(Environment const& env, storm::solver::OptimizationDirection const* dir, std::vector<uint64_t>* choices, std::vector<ValueType>* choiceValues) { |
|
|
STORM_LOG_ASSERT(!((nondetTs() || nondetIs()) && dir == nullptr), "No optimization direction provided for model with nondeterminism"); |
|
|
STORM_LOG_ASSERT(!((nondetTs() || nondetIs()) && dir == nullptr), "No optimization direction provided for model with nondeterminism"); |
|
|
// Initialize value vectors, multiplers, and solver if this has not been done, yet
|
|
|
// Initialize value vectors, multiplers, and solver if this has not been done, yet
|
|
|
if (!_TsMultiplier) { |
|
|
if (!_TsMultiplier) { |
|
@ -378,19 +391,34 @@ namespace storm { |
|
|
} else { |
|
|
} else { |
|
|
// Also keep track of the choices made.
|
|
|
// Also keep track of the choices made.
|
|
|
std::vector<uint64_t> tsChoices(_TsTransitions.getRowGroupCount()); |
|
|
std::vector<uint64_t> tsChoices(_TsTransitions.getRowGroupCount()); |
|
|
_TsMultiplier->multiplyAndReduce(env, *dir, xOld(), &_TsChoiceValues, xNew(), &tsChoices); |
|
|
|
|
|
|
|
|
std::vector<ValueType> resultChoiceValues(_TsTransitions.getRowCount()); |
|
|
|
|
|
|
|
|
|
|
|
_TsMultiplier->multiply(env, xOld(), &_TsChoiceValues, resultChoiceValues); |
|
|
|
|
|
auto rowGroupIndices = this->_TsTransitions.getRowGroupIndices(); |
|
|
|
|
|
rowGroupIndices.erase(rowGroupIndices.begin()); |
|
|
|
|
|
_TsMultiplier->reduce(env, *dir, rowGroupIndices, resultChoiceValues, xNew(), &tsChoices); |
|
|
|
|
|
|
|
|
// Note that nondeterminism within the timed states means that there can not be instant states (We either have MDPs or MAs)
|
|
|
// Note that nondeterminism within the timed states means that there can not be instant states (We either have MDPs or MAs)
|
|
|
// Hence, in this branch we don't have to care for choices at instant states.
|
|
|
// Hence, in this branch we don't have to care for choices at instant states.
|
|
|
STORM_LOG_ASSERT(!_hasInstantStates, "Nondeterministic timed states are only supported if there are no instant states."); |
|
|
STORM_LOG_ASSERT(!_hasInstantStates, "Nondeterministic timed states are only supported if there are no instant states."); |
|
|
setInputModelChoices(*choices, tsChoices); |
|
|
setInputModelChoices(*choices, tsChoices); |
|
|
|
|
|
setInputModelChoiceValues(*choiceValues, resultChoiceValues); |
|
|
} |
|
|
} |
|
|
} else if(gameNondetTs()) { // TODO DRYness? exact same behaviour as case above?
|
|
|
} else if(gameNondetTs()) { // TODO DRYness? exact same behaviour as case above?
|
|
|
if (choices == nullptr) { |
|
|
if (choices == nullptr) { |
|
|
_TsMultiplier->multiplyAndReduce(env, *dir, xOld(), &_TsChoiceValues, xNew(), nullptr, _statesOfCoalition); |
|
|
_TsMultiplier->multiplyAndReduce(env, *dir, xOld(), &_TsChoiceValues, xNew(), nullptr, _statesOfCoalition); |
|
|
} else { |
|
|
} else { |
|
|
|
|
|
// Also keep track of the choices made.
|
|
|
std::vector<uint64_t> tsChoices(_TsTransitions.getRowGroupCount()); |
|
|
std::vector<uint64_t> tsChoices(_TsTransitions.getRowGroupCount()); |
|
|
_TsMultiplier->multiplyAndReduce(env, *dir, xOld(), &_TsChoiceValues, xNew(), &tsChoices, _statesOfCoalition); |
|
|
|
|
|
|
|
|
std::vector<ValueType> resultChoiceValues(_TsTransitions.getRowCount()); |
|
|
|
|
|
|
|
|
|
|
|
_TsMultiplier->multiply(env, xOld(), &_TsChoiceValues, resultChoiceValues); |
|
|
|
|
|
auto rowGroupIndices = this->_TsTransitions.getRowGroupIndices(); |
|
|
|
|
|
rowGroupIndices.erase(rowGroupIndices.begin()); |
|
|
|
|
|
_TsMultiplier->reduce(env, *dir, rowGroupIndices, resultChoiceValues, xNew(), &tsChoices); |
|
|
|
|
|
|
|
|
setInputModelChoices(*choices, tsChoices); // no components -> no need for that call?
|
|
|
setInputModelChoices(*choices, tsChoices); // no components -> no need for that call?
|
|
|
|
|
|
setInputModelChoiceValues(*choiceValues, resultChoiceValues); |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
_TsMultiplier->multiply(env, xOld(), &_TsChoiceValues, xNew()); |
|
|
_TsMultiplier->multiply(env, xOld(), &_TsChoiceValues, xNew()); |
|
|