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);
44template<
typename ValueType>
47 boost::optional<ValueType>
const &lowerBound, boost::optional<ValueType>
const &upperBound) {
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.");
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) {
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) {
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));
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) {
226 if ((convertToEquationSystem &&
epochMatrix.isIdentityMatrix()) || (!convertToEquationSystem &&
epochMatrix.getEntryCount() == 0)) {
235 std::vector<double> &b,
237 const boost::optional<double> &lowerBound,
const boost::optional<double> &upperBound) {
248 const storm::Environment &env, std::vector<storm::RationalNumber> &x, std::vector<storm::RationalNumber> &b,
250 const boost::optional<storm::RationalNumber> &upperBound) {
255 if ((convertToEquationSystem &&
epochMatrix.isIdentityMatrix()) || (!convertToEquationSystem &&
epochMatrix.getEntryCount() == 0)) {
266 const boost::optional<storm::RationalNumber> &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.
uint64_t getNumberOfSetBits() const
Returns the number of bits that are set to true in this bit vector.
const_iterator begin() const
Returns an iterator to the indices of the set bits in the 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)
solver::OptimizationDirection OptimizationDirection
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