Storm 1.10.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
MinMaxLinearEquationSolver.cpp
Go to the documentation of this file.
2
3#include <cstdint>
4#include <memory>
5
11
13
15
20
21namespace storm::solver {
22
23template<typename ValueType, typename SolutionType>
25 : direction(direction), trackScheduler(false), uniqueSolution(false), noEndComponents(false), cachingEnabled(false), requirementsChecked(false) {
26 // Intentionally left empty.
27}
28
29template<typename ValueType, typename SolutionType>
33
34template<typename ValueType, typename SolutionType>
36 std::vector<ValueType> const& b) const {
37 STORM_LOG_WARN_COND_DEBUG(this->isRequirementsCheckedSet(),
38 "The requirements of the solver have not been marked as checked. Please provide the appropriate check or mark the requirements "
39 "as checked (if applicable).");
40 return internalSolveEquations(env, d, x, b);
41}
42
43template<typename ValueType, typename SolutionType>
45 std::vector<ValueType> const& b) const {
46 STORM_LOG_THROW(isSet(this->direction), storm::exceptions::IllegalFunctionCallException, "Optimization direction not set.");
47 solveEquations(env, convert(this->direction), x, b);
48}
49
50template<typename ValueType, typename SolutionType>
54
55template<typename ValueType, typename SolutionType>
59
60template<typename ValueType, typename SolutionType>
62 uniqueSolution = value;
63}
64
65template<typename ValueType, typename SolutionType>
67 return uniqueSolution || noEndComponents;
68}
69
70template<typename ValueType, typename SolutionType>
72 noEndComponents = value;
73}
74
75template<typename ValueType, typename SolutionType>
77 return noEndComponents;
78}
79
80template<typename ValueType, typename SolutionType>
82 this->trackScheduler = trackScheduler;
83 if (!this->trackScheduler) {
84 schedulerChoices = boost::none;
85 }
86}
87
88template<typename ValueType, typename SolutionType>
90 return this->trackScheduler;
91}
92
93template<typename ValueType, typename SolutionType>
95 return static_cast<bool>(schedulerChoices);
96}
97
98template<typename ValueType, typename SolutionType>
100 STORM_LOG_THROW(hasScheduler(), storm::exceptions::IllegalFunctionCallException, "Cannot retrieve scheduler, because none was generated.");
101 storm::storage::Scheduler<ValueType> result(schedulerChoices->size());
102 uint_fast64_t state = 0;
103 for (auto const& schedulerChoice : schedulerChoices.get()) {
104 result.setChoice(schedulerChoice, state);
105 ++state;
106 }
107 return result;
108}
109
110template<typename ValueType, typename SolutionType>
112 STORM_LOG_THROW(hasScheduler(), storm::exceptions::IllegalFunctionCallException, "Cannot retrieve scheduler choices, because they were not generated.");
113 return schedulerChoices.get();
114}
115
116template<typename ValueType, typename SolutionType>
118 STORM_LOG_THROW(hasScheduler(), storm::exceptions::IllegalFunctionCallException,
119 "Cannot retrieve robust index into scheduler choices, because they were not generated.");
120 return robustSchedulerIndex.get();
121}
122
123template<typename ValueType, typename SolutionType>
125 if (cachingEnabled && !value) {
126 // caching will be turned off. Hence we clear the cache at this point
127 clearCache();
129 cachingEnabled = value;
130}
131
132template<typename ValueType, typename SolutionType>
134 return cachingEnabled;
135}
136
137template<typename ValueType, typename SolutionType>
139 // Intentionally left empty.
140}
141
142template<typename ValueType, typename SolutionType>
144 initialScheduler = std::move(choices);
145}
146
147template<typename ValueType, typename SolutionType>
149 return static_cast<bool>(initialScheduler);
150}
151
152template<typename ValueType, typename SolutionType>
154 return initialScheduler.get();
155}
156
157template<typename ValueType, typename SolutionType>
159 Environment const&, boost::optional<storm::solver::OptimizationDirection> const& direction, bool const& hasInitialScheduler) const {
161}
162
163template<typename ValueType, typename SolutionType>
165 this->requirementsChecked = value;
166}
167
168template<typename ValueType, typename SolutionType>
170 return requirementsChecked;
171}
172
173template<typename ValueType, typename SolutionType>
175 STORM_LOG_ASSERT(this->hasInitialScheduler(), "Expecting an initial scheduler to be set before setting the states for which the choices are fixed");
176 this->choiceFixedForRowGroup = std::move(schedulerFixedForRowGroup);
177}
178
179template<typename ValueType, typename SolutionType>
181 // Intentionally left empty
182}
183
184template<typename ValueType, typename SolutionType>
186 this->requirementsChecked = value;
187}
189template<typename ValueType, typename SolutionType>
191 return this->requirementsChecked;
192}
194template<typename ValueType, typename SolutionType>
196 this->robustUncertainty = robust;
197}
198
199template<typename ValueType, typename SolutionType>
201 return this->robustUncertainty;
202}
203
204template<typename ValueType, typename SolutionType>
206 Environment const& env, bool hasUniqueSolution, bool hasNoEndComponents, boost::optional<storm::solver::OptimizationDirection> const& direction,
207 bool hasInitialScheduler, bool trackScheduler) const {
208 // Create dummy solver and ask it for requirements.
209 std::unique_ptr<MinMaxLinearEquationSolver<ValueType, SolutionType>> solver = this->create(env);
210 solver->setTrackScheduler(trackScheduler);
211 solver->setHasUniqueSolution(hasUniqueSolution);
212 solver->setHasNoEndComponents(hasNoEndComponents);
213 return solver->getRequirements(env, direction, hasInitialScheduler);
214}
215
216template<typename ValueType, typename SolutionType>
217std::unique_ptr<MinMaxLinearEquationSolver<ValueType, SolutionType>> MinMaxLinearEquationSolverFactory<ValueType, SolutionType>::create(
218 Environment const& env, storm::storage::SparseMatrix<ValueType> const& matrix) const {
219 std::unique_ptr<MinMaxLinearEquationSolver<ValueType, SolutionType>> solver = this->create(env);
220 solver->setMatrix(matrix);
221 return solver;
222}
223
224template<typename ValueType, typename SolutionType>
225std::unique_ptr<MinMaxLinearEquationSolver<ValueType, SolutionType>> MinMaxLinearEquationSolverFactory<ValueType, SolutionType>::create(
226 Environment const& env, storm::storage::SparseMatrix<ValueType>&& matrix) const {
227 std::unique_ptr<MinMaxLinearEquationSolver<ValueType, SolutionType>> solver = this->create(env);
228 solver->setMatrix(std::move(matrix));
229 return solver;
230}
231
232template<typename ValueType, typename SolutionType>
237
238template<typename ValueType, typename SolutionType>
239std::unique_ptr<MinMaxLinearEquationSolver<ValueType, SolutionType>> GeneralMinMaxLinearEquationSolverFactory<ValueType, SolutionType>::create(
240 Environment const& env) const {
241 std::unique_ptr<MinMaxLinearEquationSolver<ValueType, SolutionType>> result;
242 // TODO some minmax linear equation solvers only support SolutionType == ValueType.
243 auto method = env.solver().minMax().getMethod();
244 if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch ||
245 method == MinMaxMethod::IntervalIteration || method == MinMaxMethod::SoundValueIteration || method == MinMaxMethod::OptimisticValueIteration ||
246 method == MinMaxMethod::ViToPi) {
247 result = std::make_unique<IterativeMinMaxLinearEquationSolver<ValueType, SolutionType>>(
248 std::make_unique<GeneralLinearEquationSolverFactory<SolutionType>>());
249 } else if (method == MinMaxMethod::Topological) {
250 if constexpr (std::is_same_v<ValueType, storm::Interval>) {
251 STORM_LOG_ERROR("Topological method not implemented for ValueType==Interval.");
252 } else {
253 result = std::make_unique<TopologicalMinMaxLinearEquationSolver<ValueType, SolutionType>>();
254 }
255 } else if (method == MinMaxMethod::LinearProgramming || method == MinMaxMethod::ViToLp) {
256 if constexpr (std::is_same_v<ValueType, storm::Interval>) {
257 STORM_LOG_ERROR("LP method not implemented for ValueType==Interval.");
258 } else {
259 result = std::make_unique<LpMinMaxLinearEquationSolver<ValueType>>(storm::utility::solver::getLpSolverFactory<ValueType>());
261 } else if (method == MinMaxMethod::Acyclic) {
262 if constexpr (std::is_same_v<ValueType, storm::Interval>) {
263 STORM_LOG_ERROR("Acyclic method not implemented for ValueType==Interval");
264 } else {
265 result = std::make_unique<AcyclicMinMaxLinearEquationSolver<ValueType>>();
266 }
267 } else {
268 STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Unsupported technique.");
269 }
270 result->setRequirementsChecked(this->isRequirementsCheckedSet());
271 return result;
272}
273
274template<>
275std::unique_ptr<MinMaxLinearEquationSolver<storm::RationalNumber>> GeneralMinMaxLinearEquationSolverFactory<storm::RationalNumber>::create(
276 Environment const& env) const {
277 std::unique_ptr<MinMaxLinearEquationSolver<storm::RationalNumber>> result;
278 auto method = env.solver().minMax().getMethod();
279 if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch ||
280 method == MinMaxMethod::IntervalIteration || method == MinMaxMethod::SoundValueIteration || method == MinMaxMethod::OptimisticValueIteration ||
281 method == MinMaxMethod::ViToPi) {
282 result = std::make_unique<IterativeMinMaxLinearEquationSolver<storm::RationalNumber>>(
283 std::make_unique<GeneralLinearEquationSolverFactory<storm::RationalNumber>>());
284 } else if (method == MinMaxMethod::LinearProgramming || method == MinMaxMethod::ViToLp) {
285 result = std::make_unique<LpMinMaxLinearEquationSolver<storm::RationalNumber>>(storm::utility::solver::getLpSolverFactory<storm::RationalNumber>());
286 } else if (method == MinMaxMethod::Acyclic) {
287 result = std::make_unique<AcyclicMinMaxLinearEquationSolver<storm::RationalNumber>>();
288 } else if (method == MinMaxMethod::Topological) {
289 result = std::make_unique<TopologicalMinMaxLinearEquationSolver<storm::RationalNumber>>();
290 } else {
291 STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Unsupported technique.");
292 }
293 result->setRequirementsChecked(this->isRequirementsCheckedSet());
294 return result;
295}
296
298
301
305
309} // 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
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.
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.
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:18
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:37
A class that holds a possibly non-square matrix in the compressed row storage format.
#define STORM_LOG_ERROR(message)
Definition logging.h:31
#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)