|
@ -25,13 +25,14 @@ namespace storm { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
template <typename ValueType> |
|
|
template <typename ValueType> |
|
|
void GameViHelper<ValueType>::performValueIteration(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> b, storm::solver::OptimizationDirection const dir) { |
|
|
|
|
|
|
|
|
void GameViHelper<ValueType>::performValueIteration(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> b, storm::solver::OptimizationDirection const dir, std::vector<ValueType>& constrainedChoiceValues) { |
|
|
prepareSolversAndMultipliers(env); |
|
|
prepareSolversAndMultipliers(env); |
|
|
// Get precision for convergence check.
|
|
|
// Get precision for convergence check.
|
|
|
ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().game().getPrecision()); |
|
|
ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().game().getPrecision()); |
|
|
uint64_t maxIter = env.solver().game().getMaximalNumberOfIterations(); |
|
|
uint64_t maxIter = env.solver().game().getMaximalNumberOfIterations(); |
|
|
_b = b; |
|
|
_b = b; |
|
|
_x1.assign(_transitionMatrix.getRowGroupCount(), storm::utility::zero<ValueType>()); |
|
|
|
|
|
|
|
|
//_x1.assign(_transitionMatrix.getRowGroupCount(), storm::utility::zero<ValueType>());
|
|
|
|
|
|
_x1 = x; |
|
|
_x2 = _x1; |
|
|
_x2 = _x1; |
|
|
|
|
|
|
|
|
if (this->isProduceSchedulerSet()) { |
|
|
if (this->isProduceSchedulerSet()) { |
|
@ -42,17 +43,25 @@ namespace storm { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
uint64_t iter = 0; |
|
|
uint64_t iter = 0; |
|
|
std::vector<ValueType> result = x; |
|
|
|
|
|
|
|
|
constrainedChoiceValues = std::vector<ValueType>(b.size(), storm::utility::zero<ValueType>()); |
|
|
|
|
|
|
|
|
while (iter < maxIter) { |
|
|
while (iter < maxIter) { |
|
|
++iter; |
|
|
|
|
|
|
|
|
if(iter == maxIter - 1) { |
|
|
|
|
|
_multiplier->multiply(env, xNew(), &_b, constrainedChoiceValues); |
|
|
|
|
|
auto rowGroupIndices = this->_transitionMatrix.getRowGroupIndices(); |
|
|
|
|
|
rowGroupIndices.erase(rowGroupIndices.begin()); |
|
|
|
|
|
_multiplier->reduce(env, dir, constrainedChoiceValues, rowGroupIndices, xNew()); |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
performIterationStep(env, dir); |
|
|
performIterationStep(env, dir); |
|
|
|
|
|
|
|
|
if (checkConvergence(precision)) { |
|
|
if (checkConvergence(precision)) { |
|
|
|
|
|
_multiplier->multiply(env, xNew(), &_b, constrainedChoiceValues); |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
if (storm::utility::resources::isTerminate()) { |
|
|
if (storm::utility::resources::isTerminate()) { |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
|
|
|
++iter; |
|
|
} |
|
|
} |
|
|
x = xNew(); |
|
|
x = xNew(); |
|
|
|
|
|
|
|
@ -74,18 +83,11 @@ namespace storm { |
|
|
} else { |
|
|
} else { |
|
|
_multiplier->multiplyAndReduce(env, dir, xOld(), &_b, xNew(), choices, &_statesOfCoalition); |
|
|
_multiplier->multiplyAndReduce(env, dir, xOld(), &_b, xNew(), choices, &_statesOfCoalition); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// compare applyPointwise
|
|
|
|
|
|
storm::utility::vector::applyPointwise<ValueType, ValueType, ValueType>(xOld(), xNew(), xNew(), [&dir] (ValueType const& a, ValueType const& b) -> ValueType { |
|
|
|
|
|
if(a > b) return a; |
|
|
|
|
|
else return b; |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
template <typename ValueType> |
|
|
template <typename ValueType> |
|
|
bool GameViHelper<ValueType>::checkConvergence(ValueType threshold) const { |
|
|
bool GameViHelper<ValueType>::checkConvergence(ValueType threshold) const { |
|
|
STORM_LOG_ASSERT(_multiplier, "tried to check for convergence without doing an iteration first."); |
|
|
STORM_LOG_ASSERT(_multiplier, "tried to check for convergence without doing an iteration first."); |
|
|
|
|
|
|
|
|
// Now check whether the currently produced results are precise enough
|
|
|
// Now check whether the currently produced results are precise enough
|
|
|
STORM_LOG_ASSERT(threshold > storm::utility::zero<ValueType>(), "Did not expect a non-positive threshold."); |
|
|
STORM_LOG_ASSERT(threshold > storm::utility::zero<ValueType>(), "Did not expect a non-positive threshold."); |
|
|
auto x1It = xOld().begin(); |
|
|
auto x1It = xOld().begin(); |
|
@ -113,43 +115,6 @@ namespace storm { |
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
template <typename ValueType> |
|
|
|
|
|
void GameViHelper<ValueType>::performValueIterationUpperBound(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> b, storm::solver::OptimizationDirection const dir, uint64_t upperBound, std::vector<ValueType>& constrainedChoiceValues) { |
|
|
|
|
|
prepareSolversAndMultipliers(env); |
|
|
|
|
|
_x = x; |
|
|
|
|
|
_b = b; |
|
|
|
|
|
|
|
|
|
|
|
if (this->isProduceSchedulerSet()) { |
|
|
|
|
|
if (!this->_producedOptimalChoices.is_initialized()) { |
|
|
|
|
|
this->_producedOptimalChoices.emplace(); |
|
|
|
|
|
} |
|
|
|
|
|
this->_producedOptimalChoices->resize(this->_transitionMatrix.getRowGroupCount()); |
|
|
|
|
|
} |
|
|
|
|
|
for (uint64_t iter = 0; iter < upperBound; iter++) { |
|
|
|
|
|
if(iter == upperBound - 1) { |
|
|
|
|
|
_multiplier->multiply(env, _x, &_b, constrainedChoiceValues); |
|
|
|
|
|
} |
|
|
|
|
|
performIterationStepUpperBound(env, dir); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
x = _x; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
template <typename ValueType> |
|
|
|
|
|
void GameViHelper<ValueType>::performIterationStepUpperBound(Environment const& env, storm::solver::OptimizationDirection const dir, std::vector<uint64_t>* choices) { |
|
|
|
|
|
if (!_multiplier) { |
|
|
|
|
|
prepareSolversAndMultipliers(env); |
|
|
|
|
|
} |
|
|
|
|
|
// multiplyandreducegaussseidel
|
|
|
|
|
|
// Ax = x'
|
|
|
|
|
|
if (choices == nullptr) { |
|
|
|
|
|
_multiplier->multiplyAndReduce(env, dir, _x, &_b, _x, nullptr, &_statesOfCoalition); |
|
|
|
|
|
} else { |
|
|
|
|
|
// Also keep track of the choices made.
|
|
|
|
|
|
_multiplier->multiplyAndReduce(env, dir, _x, &_b, _x, choices, &_statesOfCoalition); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
template <typename ValueType> |
|
|
template <typename ValueType> |
|
|
void GameViHelper<ValueType>::setProduceScheduler(bool value) { |
|
|
void GameViHelper<ValueType>::setProduceScheduler(bool value) { |
|
|
_produceScheduler = value; |
|
|
_produceScheduler = value; |
|
|