#ifndef STORM_SOLVER_MINMAXLINEAREQUATIONSOLVER_H_ #define STORM_SOLVER_MINMAXLINEAREQUATIONSOLVER_H_ #include #include #include #include #include "storm/solver/AbstractEquationSolver.h" #include "storm/solver/SolverSelectionOptions.h" #include "storm/storage/sparse/StateType.h" #include "storm/storage/Scheduler.h" #include "storm/solver/OptimizationDirection.h" #include "storm/solver/MinMaxLinearEquationSolverRequirements.h" #include "storm/exceptions/InvalidSettingsException.h" #include "storm/utility/macros.h" namespace storm { class Environment; namespace storage { template class SparseMatrix; } namespace solver { /*! * A class representing the interface that all min-max linear equation solvers shall implement. */ template class MinMaxLinearEquationSolver : public AbstractEquationSolver { protected: MinMaxLinearEquationSolver(OptimizationDirectionSetting direction = OptimizationDirectionSetting::Unset); public: virtual ~MinMaxLinearEquationSolver(); virtual void setMatrix(storm::storage::SparseMatrix const& matrix) = 0; virtual void setMatrix(storm::storage::SparseMatrix&& matrix) = 0; /*! * Solves the equation system x = min/max(A*x + b) given by the parameters. Note that the matrix A has * to be given upon construction time of the solver object. * * @param d For minimum, all the value of a group of rows is the taken as the minimum over all rows and as * the maximum otherwise. * @param x The solution vector x. The initial values of x represent a guess of the real values to the * solver, but may be ignored. * @param b The vector to add after matrix-vector multiplication. */ bool solveEquations(Environment const& env, OptimizationDirection d, std::vector& x, std::vector const& b) const; /*! * Behaves the same as the other variant of solveEquations, with the distinction that * instead of providing the optimization direction as an argument, the internally set optimization direction * is used. Note: this method can only be called after setting the optimization direction. */ void solveEquations(Environment const& env, std::vector& x, std::vector const& b) const; /*! * Performs (repeated) matrix-vector multiplication with the given parameters, i.e. computes * x[i+1] = min/max(A*x[i] + b) until x[n], where x[0] = x. After each multiplication and addition, the * minimal/maximal value out of each row group is selected to reduce the resulting vector to obtain the * vector for the next iteration. Note that the matrix A has to be given upon construction time of the * solver object. * * @param d For minimum, all the value of a group of rows is the taken as the minimum over all rows and as * the maximum otherwise. * @param x The initial vector that is to be multiplied with the matrix. This is also the output parameter, * i.e. after the method returns, this vector will contain the computed values. * @param b If not null, this vector is added after each multiplication. * @param n Specifies the number of iterations the matrix-vector multiplication is performed. * @param multiplyResult If non-null, this memory is used as a scratch memory. If given, the length of this * vector must be equal to the number of rows of A. * @return The result of the repeated matrix-vector multiplication as the content of the vector x. */ virtual void repeatedMultiply(Environment const& env, OptimizationDirection d, std::vector& x, std::vector const* b, uint_fast64_t n = 1) const = 0; /*! * Behaves the same as the other variant of multiply, with the * distinction that instead of providing the optimization direction as an argument, the internally set * optimization direction is used. Note: this method can only be called after setting the optimization direction. */ virtual void repeatedMultiply(Environment const& env, std::vector& x, std::vector* b , uint_fast64_t n) const; /*! * Sets an optimization direction to use for calls to methods that do not explicitly provide one. */ void setOptimizationDirection(OptimizationDirection direction); /*! * Unsets the optimization direction to use for calls to methods that do not explicitly provide one. */ void unsetOptimizationDirection(); /*! * Sets whether the solution to the min max equation system is known to be unique. */ void setHasUniqueSolution(bool value = true); /*! * Retrieves whether the solution to the min max equation system is assumed to be unique */ bool hasUniqueSolution() const; /*! * Sets whether schedulers are generated when solving equation systems. If the argument is false, the currently * stored scheduler (if any) is deleted. */ void setTrackScheduler(bool trackScheduler = true); /*! * Retrieves whether this solver is set to generate schedulers. */ bool isTrackSchedulerSet() const; /*! * Retrieves whether the solver generated a scheduler. */ bool hasScheduler() const; /*! * Retrieves the generated scheduler. Note: it is only legal to call this function if a scheduler was generated. */ storm::storage::Scheduler computeScheduler() const; /*! * Retrieves the generated (deterministic) choices of the optimal scheduler. Note: it is only legal to call this function if a scheduler was generated. */ std::vector const& getSchedulerChoices() const; /*! * Sets whether some of the generated data during solver calls should be cached. * This possibly decreases the runtime of subsequent calls but also increases memory consumption. */ void setCachingEnabled(bool value); /*! * Retrieves whether some of the generated data during solver calls should be cached. */ bool isCachingEnabled() const; /* * Clears the currently cached data that has been stored during previous calls of the solver. */ virtual void clearCache() const; /*! * Sets a valid initial scheduler that is required by some solvers (see requirements of solvers). */ void setInitialScheduler(std::vector&& choices); /*! * Returns true iff an initial scheduler is set. */ bool hasInitialScheduler() const; /*! * Retrieves the initial scheduler if one was set. */ std::vector const& getInitialScheduler() const; /*! * Retrieves the requirements of this solver for solving equations with the current settings. The requirements * are guaranteed to be ordered according to their appearance in the SolverRequirement type. */ virtual MinMaxLinearEquationSolverRequirements getRequirements(Environment const& env, boost::optional const& direction = boost::none) const; /*! * Notifies the solver that the requirements for solving equations have been checked. If this has not been * done before solving equations, the solver might issue a warning, perform the checks itself or even fail. */ void setRequirementsChecked(bool value = true); /*! * Retrieves whether the solver is aware that the requirements were checked. */ bool isRequirementsCheckedSet() const; protected: virtual bool internalSolveEquations(Environment const& env, OptimizationDirection d, std::vector& x, std::vector const& b) const = 0; /// The optimization direction to use for calls to functions that do not provide it explicitly. Can also be unset. OptimizationDirectionSetting direction; /// Whether we generate a scheduler during solving. bool trackScheduler; /// The scheduler choices that induce the optimal values (if they could be successfully generated). mutable boost::optional> schedulerChoices; // A scheduler that can be used by solvers that require a valid initial scheduler. boost::optional> initialScheduler; private: // Whether the solver can assume that the min-max equation system has a unique solution bool uniqueSolution; /// Whether some of the generated data during solver calls should be cached. bool cachingEnabled; /// A flag storing whether the requirements of the solver were checked. bool requirementsChecked; }; template class MinMaxLinearEquationSolverFactory { public: MinMaxLinearEquationSolverFactory(); virtual ~MinMaxLinearEquationSolverFactory() = default; std::unique_ptr> create(Environment const& env, storm::storage::SparseMatrix const& matrix) const; std::unique_ptr> create(Environment const& env, storm::storage::SparseMatrix&& matrix) const; virtual std::unique_ptr> create(Environment const& env) const = 0; /*! * Retrieves the requirements of the solver that would be created when calling create() right now. The * requirements are guaranteed to be ordered according to their appearance in the SolverRequirement type. */ MinMaxLinearEquationSolverRequirements getRequirements(Environment const& env, bool hasUniqueSolution = false, boost::optional const& direction = boost::none) const; void setRequirementsChecked(bool value = true); bool isRequirementsCheckedSet() const; private: bool requirementsChecked; }; template class GeneralMinMaxLinearEquationSolverFactory : public MinMaxLinearEquationSolverFactory { public: GeneralMinMaxLinearEquationSolverFactory(); // Make the other create methods visible. using MinMaxLinearEquationSolverFactory::create; virtual std::unique_ptr> create(Environment const& env) const override; }; } // namespace solver } // namespace storm #endif /* STORM_SOLVER_MINMAXLINEAREQUATIONSOLVER_H_ */