Storm 1.11.1.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
MinMaxLinearEquationSolver.cpp
Go to the documentation of this file.
2
3#include <memory>
4
17
18namespace storm::solver {
19
20template<typename ValueType, typename SolutionType>
22 : direction(direction), trackScheduler(false), uniqueSolution(false), noEndComponents(false), cachingEnabled(false), requirementsChecked(false) {
23 // Intentionally left empty.
24}
25
26template<typename ValueType, typename SolutionType>
30
31template<typename ValueType, typename SolutionType>
33 std::vector<ValueType> const& b) const {
34 STORM_LOG_WARN_COND_DEBUG(this->isRequirementsCheckedSet(),
35 "The requirements of the solver have not been marked as checked. Please provide the appropriate check or mark the requirements "
36 "as checked (if applicable).");
37 return internalSolveEquations(env, d, x, b);
38}
39
40template<typename ValueType, typename SolutionType>
42 std::vector<ValueType> const& b) const {
43 STORM_LOG_THROW(isSet(this->direction), storm::exceptions::IllegalFunctionCallException, "Optimization direction not set.");
44 solveEquations(env, convert(this->direction), x, b);
45}
46
47template<typename ValueType, typename SolutionType>
51
52template<typename ValueType, typename SolutionType>
56
57template<typename ValueType, typename SolutionType>
59 uniqueSolution = value;
60}
61
62template<typename ValueType, typename SolutionType>
64 return uniqueSolution || noEndComponents;
65}
66
67template<typename ValueType, typename SolutionType>
69 noEndComponents = value;
70}
71
72template<typename ValueType, typename SolutionType>
76
77template<typename ValueType, typename SolutionType>
79 this->trackScheduler = trackScheduler;
80 if (!this->trackScheduler) {
81 schedulerChoices = boost::none;
82 }
83}
84
85template<typename ValueType, typename SolutionType>
89
90template<typename ValueType, typename SolutionType>
92 return static_cast<bool>(schedulerChoices);
94
95template<typename ValueType, typename SolutionType>
97 STORM_LOG_THROW(hasScheduler(), storm::exceptions::IllegalFunctionCallException, "Cannot retrieve scheduler, because none was generated.");
98 storm::storage::Scheduler<ValueType> result(schedulerChoices->size());
99 uint_fast64_t state = 0;
100 for (auto const& schedulerChoice : schedulerChoices.get()) {
101 result.setChoice(schedulerChoice, state);
102 ++state;
103 }
104 return result;
105}
106
107template<typename ValueType, typename SolutionType>
109 STORM_LOG_THROW(hasScheduler(), storm::exceptions::IllegalFunctionCallException, "Cannot retrieve scheduler choices, because they were not generated.");
110 return schedulerChoices.get();
111}
113template<typename ValueType, typename SolutionType>
115 STORM_LOG_THROW(hasScheduler(), storm::exceptions::IllegalFunctionCallException,
116 "Cannot retrieve robust index into scheduler choices, because they were not generated.");
117 return robustSchedulerIndex.get();
119
120template<typename ValueType, typename SolutionType>
122 if (cachingEnabled && !value) {
123 // caching will be turned off. Hence we clear the cache at this point
124 clearCache();
125 }
126 cachingEnabled = value;
127}
129template<typename ValueType, typename SolutionType>
134template<typename ValueType, typename SolutionType>
136 // Intentionally left empty.
137}
139template<typename ValueType, typename SolutionType>
141 initialScheduler = std::move(choices);
142}
144template<typename ValueType, typename SolutionType>
146 return static_cast<bool>(initialScheduler);
147}
148
149template<typename ValueType, typename SolutionType>
151 return initialScheduler.get();
152}
153
154template<typename ValueType, typename SolutionType>
156 Environment const&, boost::optional<storm::solver::OptimizationDirection> const& direction, bool const& hasInitialScheduler) const {
158}
160template<typename ValueType, typename SolutionType>
162 this->requirementsChecked = value;
163}
165template<typename ValueType, typename SolutionType>
170template<typename ValueType, typename SolutionType>
172 STORM_LOG_ASSERT(this->hasInitialScheduler(), "Expecting an initial scheduler to be set before setting the states for which the choices are fixed");
173 this->choiceFixedForRowGroup = std::move(schedulerFixedForRowGroup);
175
176template<typename ValueType, typename SolutionType>
178 // Intentionally left empty
179}
181template<typename ValueType, typename SolutionType>
183 this->requirementsChecked = value;
184}
185
186template<typename ValueType, typename SolutionType>
188 return this->requirementsChecked;
189}
190
191template<typename ValueType, typename SolutionType>
193 this->robustUncertainty = robust;
194}
195
196template<typename ValueType, typename SolutionType>
198 return this->robustUncertainty;
199}
200
201template<typename ValueType, typename SolutionType>
203 Environment const& env, bool hasUniqueSolution, bool hasNoEndComponents, boost::optional<storm::solver::OptimizationDirection> const& direction,
204 bool hasInitialScheduler, bool trackScheduler) const {
205 // Create dummy solver and ask it for requirements.
206 std::unique_ptr<MinMaxLinearEquationSolver<ValueType, SolutionType>> solver = this->create(env);
207 solver->setTrackScheduler(trackScheduler);
208 solver->setHasUniqueSolution(hasUniqueSolution);
209 solver->setHasNoEndComponents(hasNoEndComponents);
210 return solver->getRequirements(env, direction, hasInitialScheduler);
211}
212
213template<typename ValueType, typename SolutionType>
214std::unique_ptr<MinMaxLinearEquationSolver<ValueType, SolutionType>> MinMaxLinearEquationSolverFactory<ValueType, SolutionType>::create(
215 Environment const& env, storm::storage::SparseMatrix<ValueType> const& matrix) const {
216 std::unique_ptr<MinMaxLinearEquationSolver<ValueType, SolutionType>> solver = this->create(env);
217 solver->setMatrix(matrix);
218 return solver;
219}
220
221template<typename ValueType, typename SolutionType>
222std::unique_ptr<MinMaxLinearEquationSolver<ValueType, SolutionType>> MinMaxLinearEquationSolverFactory<ValueType, SolutionType>::create(
223 Environment const& env, storm::storage::SparseMatrix<ValueType>&& matrix) const {
224 std::unique_ptr<MinMaxLinearEquationSolver<ValueType, SolutionType>> solver = this->create(env);
225 solver->setMatrix(std::move(matrix));
226 return solver;
227}
228
229template<typename ValueType, typename SolutionType>
234
235template<typename ValueType, typename SolutionType>
236std::unique_ptr<MinMaxLinearEquationSolver<ValueType, SolutionType>> GeneralMinMaxLinearEquationSolverFactory<ValueType, SolutionType>::create(
237 Environment const& env) const {
238 std::unique_ptr<MinMaxLinearEquationSolver<ValueType, SolutionType>> result;
239 // TODO some minmax linear equation solvers only support SolutionType == ValueType.
240 auto method = env.solver().minMax().getMethod();
241 if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch ||
242 method == MinMaxMethod::IntervalIteration || method == MinMaxMethod::SoundValueIteration || method == MinMaxMethod::OptimisticValueIteration ||
243 method == MinMaxMethod::GuessingValueIteration || method == MinMaxMethod::ViToPi) {
244 result = std::make_unique<IterativeMinMaxLinearEquationSolver<ValueType, SolutionType>>(
245 std::make_unique<GeneralLinearEquationSolverFactory<SolutionType>>());
246 } else if (method == MinMaxMethod::Topological) {
247 if constexpr (std::is_same_v<ValueType, storm::Interval>) {
248 STORM_LOG_ERROR("Topological method not implemented for ValueType==Interval.");
249 } else {
250 result = std::make_unique<TopologicalMinMaxLinearEquationSolver<ValueType, SolutionType>>();
251 }
252 } else if (method == MinMaxMethod::LinearProgramming || method == MinMaxMethod::ViToLp) {
253 if constexpr (std::is_same_v<ValueType, storm::Interval>) {
254 STORM_LOG_ERROR("LP method not implemented for ValueType==Interval.");
255 } else {
256 result = std::make_unique<LpMinMaxLinearEquationSolver<ValueType>>(storm::utility::solver::getLpSolverFactory<ValueType>());
258 } else if (method == MinMaxMethod::Acyclic) {
259 if constexpr (std::is_same_v<ValueType, storm::Interval>) {
260 STORM_LOG_ERROR("Acyclic method not implemented for ValueType==Interval");
261 } else {
262 result = std::make_unique<AcyclicMinMaxLinearEquationSolver<ValueType>>();
263 }
264 } else {
265 STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Unsupported technique.");
266 }
267 result->setRequirementsChecked(this->isRequirementsCheckedSet());
268 return result;
269}
270
271template<>
272std::unique_ptr<MinMaxLinearEquationSolver<storm::RationalNumber>> GeneralMinMaxLinearEquationSolverFactory<storm::RationalNumber>::create(
273 Environment const& env) const {
274 std::unique_ptr<MinMaxLinearEquationSolver<storm::RationalNumber>> result;
275 auto method = env.solver().minMax().getMethod();
276 if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch ||
277 method == MinMaxMethod::IntervalIteration || method == MinMaxMethod::SoundValueIteration || method == MinMaxMethod::OptimisticValueIteration ||
278 method == MinMaxMethod::GuessingValueIteration || method == MinMaxMethod::ViToPi) {
279 result = std::make_unique<IterativeMinMaxLinearEquationSolver<storm::RationalNumber>>(
280 std::make_unique<GeneralLinearEquationSolverFactory<storm::RationalNumber>>());
281 } else if (method == MinMaxMethod::LinearProgramming || method == MinMaxMethod::ViToLp) {
282 result = std::make_unique<LpMinMaxLinearEquationSolver<storm::RationalNumber>>(storm::utility::solver::getLpSolverFactory<storm::RationalNumber>());
283 } else if (method == MinMaxMethod::Acyclic) {
284 result = std::make_unique<AcyclicMinMaxLinearEquationSolver<storm::RationalNumber>>();
285 } else if (method == MinMaxMethod::Topological) {
286 result = std::make_unique<TopologicalMinMaxLinearEquationSolver<storm::RationalNumber>>();
287 } else {
288 STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Unsupported technique.");
289 }
290 result->setRequirementsChecked(this->isRequirementsCheckedSet());
291 return result;
292}
293
295
298
302
306} // namespace storm::solver
SolverEnvironment & solver()
storm::solver::MinMaxMethod const & getMethod() const
MinMaxSolverEnvironment & minMax()
virtual std::unique_ptr< MinMaxLinearEquationSolver< ValueType, SolutionType > > create(Environment const &env) const override
MinMaxLinearEquationSolverRequirements getRequirements(Environment const &env, bool hasUniqueSolution=false, bool hasNoEndComponents=false, boost::optional< storm::solver::OptimizationDirection > const &direction=boost::none, bool hasInitialScheduler=false, bool trackScheduler=false) const
Retrieves the requirements of the solver that would be created when calling create() right now.
std::unique_ptr< MinMaxLinearEquationSolver< ValueType, SolutionType > > create(Environment const &env, storm::storage::SparseMatrix< ValueType > const &matrix) const
A class representing the interface that all min-max linear equation solvers shall implement.
virtual void setSchedulerFixedForRowGroup(storm::storage::BitVector &&schedulerFixedForRowGroup)
Sets the states for which the choices are fixed.
void unsetOptimizationDirection()
Unsets the optimization direction to use for calls to methods that do not explicitly provide one.
storm::storage::Scheduler< ValueType > computeScheduler() const
Retrieves the generated scheduler.
void setHasUniqueSolution(bool value=true)
Sets whether the solution to the min max equation system is known to be unique.
void setUncertaintyIsRobust(bool robust)
Set whether uncertainty should be interpreted adverserially (robust) or not.
bool solveEquations(Environment const &env, OptimizationDirection d, std::vector< SolutionType > &x, std::vector< ValueType > const &b) const
Solves the equation system x = min/max(A*x + b) given by the parameters.
virtual void clearCache() const
Clears the currently cached data that has been stored during previous calls of the solver.
void setOptimizationDirection(OptimizationDirection direction)
Sets an optimization direction to use for calls to methods that do not explicitly provide one.
MinMaxLinearEquationSolver(OptimizationDirectionSetting direction=OptimizationDirectionSetting::Unset)
void setInitialScheduler(std::vector< uint_fast64_t > &&choices)
Sets a valid initial scheduler that is required by some solvers (see requirements of solvers).
bool hasScheduler() const
Retrieves whether the solver generated a scheduler.
std::vector< uint_fast64_t > const & getSchedulerChoices() const
Retrieves the generated (deterministic) choices of the optimal scheduler.
std::vector< uint_fast64_t > const & getInitialScheduler() const
Retrieves the initial scheduler if one was set.
void setRequirementsChecked(bool value=true)
Notifies the solver that the requirements for solving equations have been checked.
bool hasUniqueSolution() const
Retrieves whether the solution to the min max equation system is assumed to be unique.
virtual MinMaxLinearEquationSolverRequirements getRequirements(Environment const &env, boost::optional< storm::solver::OptimizationDirection > const &direction=boost::none, bool const &hasInitialScheduler=false) const
Retrieves the requirements of this solver for solving equations with the current settings.
void setHasNoEndComponents(bool value=true)
Sets whether the min max equation system is known to not have any end components.
bool isUncertaintyRobust() const
Is the uncertainty to be interpreted robustly (adverserially) or not?
std::vector< uint_fast64_t > const & getRobustSchedulerIndex() const
Retrieves the generated robust index into the scheduler.
bool isTrackSchedulerSet() const
Retrieves whether this solver is set to generate schedulers.
bool hasNoEndComponents() const
Retrieves whether the min max equation system is known to not have any end components.
void setCachingEnabled(bool value)
Sets whether some of the generated data during solver calls should be cached.
bool isRequirementsCheckedSet() const
Retrieves whether the solver is aware that the requirements were checked.
bool isCachingEnabled() const
Retrieves whether some of the generated data during solver calls should be cached.
bool hasInitialScheduler() const
Returns true iff an initial scheduler is set.
void setTrackScheduler(bool trackScheduler=true)
Sets whether schedulers are generated when solving equation systems.
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:16
This class defines which action is chosen in a particular state of a non-deterministic model.
Definition Scheduler.h:18
void setChoice(SchedulerChoice< ValueType > const &choice, uint_fast64_t modelState, uint_fast64_t memoryState=0)
Sets the choice defined by the scheduler for the given state.
Definition Scheduler.cpp:38
A class that holds a possibly non-square matrix in the compressed row storage format.
#define STORM_LOG_ERROR(message)
Definition logging.h:26
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:11
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
#define STORM_LOG_WARN_COND_DEBUG(cond, message)
Definition macros.h:18
OptimizationDirection convert(OptimizationDirectionSetting s)
bool isSet(OptimizationDirectionSetting s)