12namespace modelchecker {
14namespace rewardbounded {
16template<
typename ValueType>
18 std::vector<ValueType> epochResult;
23 while (*stepChoiceIt < state) {
28 if (*stepChoiceIt == state) {
29 epochResult.push_back(epochModel.
objectiveRewards.front()[state] + *stepSolutionIt);
34 if (*stepChoiceIt == state) {
35 epochResult.push_back(*stepSolutionIt);
37 epochResult.push_back(storm::utility::zero<ValueType>());
44template<
typename ValueType>
47 boost::optional<ValueType>
const &lowerBound, boost::optional<ValueType>
const &upperBound) {
50 x.assign(epochModel.
epochMatrix.getRowGroupCount(), storm::utility::zero<ValueType>());
58 if (epochMatrixAcyclic) {
61 linEqSolver = linearEquationSolverFactory.
create(acyclicEnv, epochModel.
epochMatrix);
65 linEqSolver->setCachingEnabled(
true);
66 auto req = linEqSolver->getRequirements(epochMatrixAcyclic ? acyclicEnv : env);
68 linEqSolver->setLowerBound(lowerBound.get());
69 req.clearLowerBounds();
72 linEqSolver->setUpperBound(upperBound.get());
73 req.clearUpperBounds();
75 if (epochMatrixAcyclic) {
78 STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException,
79 "Solver requirements " + req.getEnabledRequirementsAsString() +
" not checked.");
81 storm::exceptions::UnexpectedException,
82 "The constructed solver uses a different equation problem format then the one that has been specified initially.");
86 b.assign(epochModel.
epochMatrix.getRowCount(), storm::utility::zero<ValueType>());
87 std::vector<ValueType>
const &objectiveValues = epochModel.
objectiveRewards.front();
89 b[choice] = objectiveValues[choice];
93 b[choice] += *stepSolutionIt;
99 linEqSolver->solveEquations(env, x, b);
104template<
typename ValueType>
107 assert(epochModel.
epochMatrix.getEntryCount() == 0);
109 std::vector<ValueType> epochResult;
117 uint64_t lastChoice = epochModel.
epochMatrix.getRowGroupIndices()[state + 1];
118 bool isFirstChoice =
true;
119 for (uint64_t choice = epochModel.
epochMatrix.getRowGroupIndices()[state]; choice < lastChoice; ++choice) {
120 while (*stepChoiceIt < choice) {
125 ValueType choiceValue = storm::utility::zero<ValueType>();
129 if (*stepChoiceIt == choice) {
130 choiceValue += *stepSolutionIt;
134 bestValue = std::move(choiceValue);
135 isFirstChoice =
false;
138 if (choiceValue < bestValue) {
139 bestValue = std::move(choiceValue);
142 if (choiceValue > bestValue) {
143 bestValue = std::move(choiceValue);
149 epochResult.push_back(std::move(bestValue));
154template<
typename ValueType>
156 std::vector<ValueType> &x, std::vector<ValueType> &b,
158 boost::optional<ValueType>
const &lowerBound, boost::optional<ValueType>
const &upperBound) {
161 x.assign(epochModel.
epochMatrix.getRowGroupCount(), storm::utility::zero<ValueType>());
165 if (epochMatrixAcyclic) {
168 minMaxSolver = minMaxLinearEquationSolverFactory.
create(acyclicEnv, epochModel.
epochMatrix);
170 minMaxSolver = minMaxLinearEquationSolverFactory.
create(env, epochModel.
epochMatrix);
172 minMaxSolver->setHasUniqueSolution();
173 minMaxSolver->setHasNoEndComponents();
174 minMaxSolver->setOptimizationDirection(dir);
175 minMaxSolver->setCachingEnabled(
true);
176 minMaxSolver->setTrackScheduler(!epochMatrixAcyclic);
177 auto req = minMaxSolver->getRequirements(epochMatrixAcyclic ? acyclicEnv : env, dir,
false);
179 minMaxSolver->setLowerBound(lowerBound.get());
180 req.clearLowerBounds();
183 minMaxSolver->setUpperBound(upperBound.get());
184 req.clearUpperBounds();
186 if (epochMatrixAcyclic) {
189 STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException,
190 "Solver requirements " + req.getEnabledRequirementsAsString() +
" not checked.");
191 minMaxSolver->setRequirementsChecked();
193 if (minMaxSolver && minMaxSolver->isTrackSchedulerSet()) {
194 auto choicesTmp = minMaxSolver->getSchedulerChoices();
195 minMaxSolver->setInitialScheduler(std::move(choicesTmp));
200 b.assign(epochModel.
epochMatrix.getRowCount(), storm::utility::zero<ValueType>());
201 std::vector<ValueType>
const &objectiveValues = epochModel.
objectiveRewards.front();
203 b[choice] = objectiveValues[choice];
207 b[choice] += *stepSolutionIt;
213 minMaxSolver->solveEquations(env, x, b);
221 const boost::optional<double> &lowerBound,
const boost::optional<double> &upperBound) {
222 STORM_LOG_ASSERT(epochMatrix.hasTrivialRowGrouping(),
"This operation is only allowed if no nondeterminism is present.");
223 STORM_LOG_ASSERT(equationSolverProblemFormat.is_initialized(),
"Unknown equation problem format.");
226 if ((convertToEquationSystem && epochMatrix.isIdentityMatrix()) || (!convertToEquationSystem && epochMatrix.getEntryCount() == 0)) {
227 return analyzeTrivialDtmcEpochModel<double>(*
this);
229 return analyzeNonTrivialDtmcEpochModel<double>(env, *
this, x, b, linEqSolver, lowerBound, upperBound);
235 std::vector<double> &b,
237 const boost::optional<double> &lowerBound,
const boost::optional<double> &upperBound) {
239 if (epochMatrix.getEntryCount() == 0) {
240 return analyzeTrivialMdpEpochModel<double>(dir, *
this);
242 return analyzeNonTrivialMdpEpochModel<double>(env, dir, *
this, x, b, minMaxSolver, lowerBound, upperBound);
248 const storm::Environment &env, std::vector<storm::RationalNumber> &x, std::vector<storm::RationalNumber> &b,
250 const boost::optional<storm::RationalNumber> &upperBound) {
251 STORM_LOG_ASSERT(epochMatrix.hasTrivialRowGrouping(),
"This operation is only allowed if no nondeterminism is present.");
252 STORM_LOG_ASSERT(equationSolverProblemFormat.is_initialized(),
"Unknown equation problem format.");
255 if ((convertToEquationSystem && epochMatrix.isIdentityMatrix()) || (!convertToEquationSystem && epochMatrix.getEntryCount() == 0)) {
256 return analyzeTrivialDtmcEpochModel<storm::RationalNumber>(*
this);
258 return analyzeNonTrivialDtmcEpochModel<storm::RationalNumber>(env, *
this, x, b, linEqSolver, lowerBound, upperBound);
266 const boost::optional<storm::RationalNumber> &upperBound) {
268 if (epochMatrix.getEntryCount() == 0) {
269 return analyzeTrivialMdpEpochModel<storm::RationalNumber>(dir, *
this);
271 return analyzeNonTrivialMdpEpochModel<storm::RationalNumber>(env, dir, *
this, x, b, minMaxSolver, lowerBound, upperBound);
SolverEnvironment & solver()
void setMethod(storm::solver::MinMaxMethod value, bool isSetFromDefault=false)
void setLinearEquationSolverType(storm::solver::EquationSolverType const &value, bool isSetFromDefault=false)
MinMaxSolverEnvironment & minMax()
virtual std::unique_ptr< LinearEquationSolver< ValueType > > create(Environment const &env) const override
Creates an equation solver with the current settings, but without a matrix.
virtual std::unique_ptr< MinMaxLinearEquationSolver< ValueType, SolutionType > > create(Environment const &env) const override
An interface that represents an abstract linear equation solver.
A class representing the interface that all min-max linear equation solvers shall implement.
const_iterator begin() const
Returns an iterator to the indices of the set bits in the bit vector.
uint_fast64_t getNumberOfSetBits() const
Returns the number of bits that are set to true in this bit vector.
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
std::vector< ValueType > analyzeNonTrivialMdpEpochModel(Environment const &env, OptimizationDirection dir, EpochModel< ValueType, true > &epochModel, std::vector< ValueType > &x, std::vector< ValueType > &b, std::unique_ptr< storm::solver::MinMaxLinearEquationSolver< ValueType > > &minMaxSolver, boost::optional< ValueType > const &lowerBound, boost::optional< ValueType > const &upperBound)
std::vector< ValueType > analyzeTrivialDtmcEpochModel(EpochModel< ValueType, true > &epochModel)
std::vector< ValueType > analyzeNonTrivialDtmcEpochModel(Environment const &env, EpochModel< ValueType, true > &epochModel, std::vector< ValueType > &x, std::vector< ValueType > &b, std::unique_ptr< storm::solver::LinearEquationSolver< ValueType > > &linEqSolver, boost::optional< ValueType > const &lowerBound, boost::optional< ValueType > const &upperBound)
std::vector< ValueType > analyzeTrivialMdpEpochModel(OptimizationDirection dir, EpochModel< ValueType, true > &epochModel)
bool constexpr minimize(OptimizationDirection d)
bool hasCycle(storm::storage::SparseMatrix< T > const &transitionMatrix, boost::optional< storm::storage::BitVector > const &subsystem)
Returns true if the graph represented by the given matrix has a cycle.
std::vector< Type > filterVector(std::vector< Type > const &in, storm::storage::BitVector const &filter)
std::vector< storm::storage::BitVector > objectiveRewardFilter
std::vector< ValueType > analyzeSingleObjective(Environment const &env, OptimizationDirection dir, std::vector< ValueType > &x, std::vector< ValueType > &b, std::unique_ptr< storm::solver::MinMaxLinearEquationSolver< ValueType > > &minMaxSolver, boost::optional< ValueType > const &lowerBound, boost::optional< ValueType > const &upperBound)
Analyzes the epoch model, i.e., solves the represented equation system.
storm::storage::SparseMatrix< ValueType > epochMatrix
std::vector< std::vector< ValueType > > objectiveRewards
boost::optional< storm::solver::LinearEquationSolverProblemFormat > equationSolverProblemFormat
In case of DTMCs we have different options for the equation problem format the epoch model will have.
std::vector< SolutionType > stepSolutions
storm::storage::BitVector epochInStates
storm::storage::BitVector stepChoices