Browse Source

work towards generating schedulers (and some other related stuff)

Former-commit-id: 23cbcb5fb5
tempestpy_adaptions
dehnert 9 years ago
parent
commit
dee44056d1
  1. 3
      src/counterexamples/MILPMinimalLabelSetGenerator.h
  2. 4
      src/counterexamples/SMTMinimalCommandSetGenerator.h
  3. 18
      src/modelchecker/CheckTask.h
  4. 2
      src/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp
  5. 4
      src/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp
  6. 25
      src/modelchecker/prctl/helper/MDPModelCheckingHelperReturnType.h
  7. 18
      src/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp
  8. 4
      src/modelchecker/prctl/helper/SparseMdpPrctlHelper.h
  9. 9
      src/solver/LinearEquationSolver.h
  10. 39
      src/solver/MinMaxLinearEquationSolver.h
  11. 46
      src/solver/SolveGoal.cpp
  12. 94
      src/solver/SolveGoal.h

3
src/counterexamples/MILPMinimalLabelSetGenerator.h

@ -923,7 +923,6 @@ namespace storm {
}
public:
static boost::container::flat_set<uint_fast64_t> getMinimalLabelSet(storm::logic::Formula const& pathFormula, storm::models::sparse::Mdp<T> const& labeledMdp, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, double probabilityThreshold, bool strictBound, bool checkThresholdFeasible = false, bool includeSchedulerCuts = false) {
// (0) Check whether the MDP is indeed labeled.
if (!labeledMdp.hasChoiceLabeling()) {
@ -934,7 +933,7 @@ namespace storm {
double maximalReachabilityProbability = 0;
if (checkThresholdFeasible) {
storm::modelchecker::helper::SparseMdpPrctlHelper<T> modelcheckerHelper;
std::vector<T> result = std::move(modelcheckerHelper.computeUntilProbabilities(false, labeledMdp.getTransitionMatrix(), labeledMdp.getBackwardTransitions(), phiStates, psiStates, false, false, storm::utility::solver::MinMaxLinearEquationSolverFactory<T>()).result);
std::vector<T> result = std::move(modelcheckerHelper.computeUntilProbabilities(false, labeledMdp.getTransitionMatrix(), labeledMdp.getBackwardTransitions(), phiStates, psiStates, false, false, storm::utility::solver::MinMaxLinearEquationSolverFactory<T>()).values);
for (auto state : labeledMdp.getInitialStates()) {
maximalReachabilityProbability = std::max(maximalReachabilityProbability, result[state]);
}

4
src/counterexamples/SMTMinimalCommandSetGenerator.h

@ -1628,7 +1628,7 @@ namespace storm {
if (checkThresholdFeasible) {
storm::modelchecker::helper::SparseMdpPrctlHelper<T> modelCheckerHelper;
LOG4CPLUS_DEBUG(logger, "Invoking model checker.");
std::vector<T> result = std::move(modelCheckerHelper.computeUntilProbabilities(false, labeledMdp.getTransitionMatrix(), labeledMdp.getBackwardTransitions(), phiStates, psiStates, false, false, storm::utility::solver::MinMaxLinearEquationSolverFactory<T>()).result);
std::vector<T> result = std::move(modelCheckerHelper.computeUntilProbabilities(false, labeledMdp.getTransitionMatrix(), labeledMdp.getBackwardTransitions(), phiStates, psiStates, false, false, storm::utility::solver::MinMaxLinearEquationSolverFactory<T>()).values);
for (auto state : labeledMdp.getInitialStates()) {
maximalReachabilityProbability = std::max(maximalReachabilityProbability, result[state]);
}
@ -1692,7 +1692,7 @@ namespace storm {
storm::models::sparse::Mdp<T> subMdp = labeledMdp.restrictChoiceLabels(commandSet);
storm::modelchecker::helper::SparseMdpPrctlHelper<T> modelCheckerHelper;
LOG4CPLUS_DEBUG(logger, "Invoking model checker.");
std::vector<T> result = std::move(modelCheckerHelper.computeUntilProbabilities(false, subMdp.getTransitionMatrix(), subMdp.getBackwardTransitions(), phiStates, psiStates, false, false, storm::utility::solver::MinMaxLinearEquationSolverFactory<T>()).result);
std::vector<T> result = std::move(modelCheckerHelper.computeUntilProbabilities(false, subMdp.getTransitionMatrix(), subMdp.getBackwardTransitions(), phiStates, psiStates, false, false, storm::utility::solver::MinMaxLinearEquationSolverFactory<T>()).values);
LOG4CPLUS_DEBUG(logger, "Computed model checking results.");
totalModelCheckingTime += std::chrono::high_resolution_clock::now() - modelCheckingClock;

18
src/modelchecker/CheckTask.h

@ -30,7 +30,7 @@ namespace storm {
*/
CheckTask(FormulaType const& formula, bool onlyInitialStatesRelevant = false) : formula(formula) {
this->onlyInitialStatesRelevant = onlyInitialStatesRelevant;
this->produceStrategies = true;
this->produceSchedulers = true;
this->qualitative = false;
if (formula.isOperatorFormula()) {
@ -76,7 +76,7 @@ namespace storm {
*/
template<typename NewFormulaType>
CheckTask<NewFormulaType, ValueType> replaceFormula(NewFormulaType const& newFormula) const {
return CheckTask<NewFormulaType, ValueType>(newFormula, this->optimizationDirection, this->rewardModel, this->onlyInitialStatesRelevant, this->bound, this->qualitative, this->produceStrategies);
return CheckTask<NewFormulaType, ValueType>(newFormula, this->optimizationDirection, this->rewardModel, this->onlyInitialStatesRelevant, this->bound, this->qualitative, this->produceSchedulers);
}
/*!
@ -166,10 +166,10 @@ namespace storm {
}
/*!
* Retrieves whether strategies are to be produced (if supported).
* Retrieves whether scheduler(s) are to be produced (if supported).
*/
bool isProduceStrategiesSet() const {
return produceStrategies;
bool isProduceSchedulersSet() const {
return produceSchedulers;
}
private:
@ -185,10 +185,10 @@ namespace storm {
* together with the flag that indicates only initial states of the model are relevant.
* @param qualitative A flag specifying whether the property needs to be checked qualitatively, i.e. compared
* with bounds 0/1.
* @param produceStrategies If supported by the model checker and the model formalism, strategies to achieve
* @param produceSchedulers If supported by the model checker and the model formalism, schedulers to achieve
* a value will be produced if this flag is set.
*/
CheckTask(std::reference_wrapper<FormulaType const> const& formula, boost::optional<storm::OptimizationDirection> const& optimizationDirection, boost::optional<std::string> const& rewardModel, bool onlyInitialStatesRelevant, boost::optional<std::pair<storm::logic::ComparisonType, ValueType>> const& bound, bool qualitative, bool produceStrategies) : formula(formula), optimizationDirection(optimizationDirection), rewardModel(rewardModel), onlyInitialStatesRelevant(onlyInitialStatesRelevant), bound(bound), qualitative(qualitative), produceStrategies(produceStrategies) {
CheckTask(std::reference_wrapper<FormulaType const> const& formula, boost::optional<storm::OptimizationDirection> const& optimizationDirection, boost::optional<std::string> const& rewardModel, bool onlyInitialStatesRelevant, boost::optional<std::pair<storm::logic::ComparisonType, ValueType>> const& bound, bool qualitative, bool produceSchedulers) : formula(formula), optimizationDirection(optimizationDirection), rewardModel(rewardModel), onlyInitialStatesRelevant(onlyInitialStatesRelevant), bound(bound), qualitative(qualitative), produceSchedulers(produceSchedulers) {
// Intentionally left empty.
}
@ -210,9 +210,9 @@ namespace storm {
// A flag specifying whether the property needs to be checked qualitatively, i.e. compared with bounds 0/1.
bool qualitative;
// If supported by the model checker and the model formalism, strategies to achieve a value will be produced
// If supported by the model checker and the model formalism, schedulers to achieve a value will be produced
// if this flag is set.
bool produceStrategies;
bool produceSchedulers;
};
}

2
src/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp

@ -184,7 +184,7 @@ namespace storm {
template<typename ValueType>
std::vector<ValueType> SparseMarkovAutomatonCslHelper<ValueType>::computeUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
return std::move(storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeUntilProbabilities(dir, transitionMatrix, backwardTransitions, phiStates, psiStates, qualitative, false, minMaxLinearEquationSolverFactory).result);
return std::move(storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeUntilProbabilities(dir, transitionMatrix, backwardTransitions, phiStates, psiStates, qualitative, false, minMaxLinearEquationSolverFactory).values);
}
template <typename ValueType>

4
src/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp

@ -87,8 +87,8 @@ namespace storm {
std::unique_ptr<CheckResult> rightResultPointer = this->check(pathFormula.getRightSubformula());
ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult();
ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult();
auto ret = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeUntilProbabilities(checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), false, *minMaxLinearEquationSolverFactory);
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(ret.result)));
auto ret = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeUntilProbabilities(checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), checkTask.isProduceSchedulersSet(), *minMaxLinearEquationSolverFactory);
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(ret.values)));
}
template<typename SparseMdpModelType>

25
src/modelchecker/prctl/helper/MDPModelCheckingHelperReturnType.h

@ -12,33 +12,30 @@ namespace storm {
namespace modelchecker {
namespace helper {
template<typename ValueType>
struct MDPSparseModelCheckingHelperReturnType {
MDPSparseModelCheckingHelperReturnType(MDPSparseModelCheckingHelperReturnType const&) = delete;
MDPSparseModelCheckingHelperReturnType(MDPSparseModelCheckingHelperReturnType&&) = default;
explicit MDPSparseModelCheckingHelperReturnType(std::vector<ValueType> && res) : result(std::move(res))
{
MDPSparseModelCheckingHelperReturnType(std::vector<ValueType>&& values, std::unique_ptr<storm::storage::PartialScheduler> && scheduler = nullptr) : values(std::move(values)), scheduler(std::move(scheduler)) {
// Intentionally left empty.
}
MDPSparseModelCheckingHelperReturnType(std::vector<ValueType> && res, std::unique_ptr<storm::storage::PartialScheduler> && pSched) :
result(std::move(res)), partScheduler(std::move(pSched)) {}
virtual ~MDPSparseModelCheckingHelperReturnType() { }
virtual ~MDPSparseModelCheckingHelperReturnType() {
// Intentionally left empty.
}
// The values computed for the states.
std::vector<ValueType> values;
std::vector<ValueType> result;
std::unique_ptr<storm::storage::PartialScheduler> partScheduler;
// A scheduler, if it was computed.
std::unique_ptr<storm::storage::PartialScheduler> scheduler;
};
}
}
}
#endif /* MDPMODELCHECKINGRETURNTYPE_H */

18
src/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp

@ -73,7 +73,7 @@ namespace storm {
template<typename ValueType>
MDPSparseModelCheckingHelperReturnType<ValueType> SparseMdpPrctlHelper<ValueType>::computeUntilProbabilities(storm::solver::SolveGoal const& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, bool getPolicy, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
MDPSparseModelCheckingHelperReturnType<ValueType> SparseMdpPrctlHelper<ValueType>::computeUntilProbabilities(storm::solver::SolveGoal const& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, bool producePolicy, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
// We need to identify the states which have to be taken out of the matrix, i.e.
// all states that have probability 0 and 1 of satisfying the until-formula.
@ -128,17 +128,15 @@ namespace storm {
return MDPSparseModelCheckingHelperReturnType<ValueType>(std::move(result));
}
template<typename ValueType>
MDPSparseModelCheckingHelperReturnType<ValueType> SparseMdpPrctlHelper<ValueType>::computeUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, bool getPolicy, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
MDPSparseModelCheckingHelperReturnType<ValueType> SparseMdpPrctlHelper<ValueType>::computeUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, bool producePolicy, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
storm::solver::SolveGoal goal(dir);
return std::move(computeUntilProbabilities(goal, transitionMatrix, backwardTransitions, phiStates, psiStates, qualitative, getPolicy, minMaxLinearEquationSolverFactory));
return std::move(computeUntilProbabilities(goal, transitionMatrix, backwardTransitions, phiStates, psiStates, qualitative, producePolicy, minMaxLinearEquationSolverFactory));
}
template<typename ValueType>
std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeGloballyProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, bool useMecBasedTechnique) {
if (useMecBasedTechnique) {
storm::storage::MaximalEndComponentDecomposition<ValueType> mecDecomposition(transitionMatrix, backwardTransitions, psiStates);
storm::storage::BitVector statesInPsiMecs(transitionMatrix.getRowGroupCount());
@ -148,9 +146,9 @@ namespace storm {
}
}
return std::move(computeUntilProbabilities(dir, transitionMatrix, backwardTransitions, psiStates, statesInPsiMecs, qualitative, false, minMaxLinearEquationSolverFactory).result);
return std::move(computeUntilProbabilities(dir, transitionMatrix, backwardTransitions, psiStates, statesInPsiMecs, qualitative, false, minMaxLinearEquationSolverFactory).values);
} else {
std::vector<ValueType> result = computeUntilProbabilities(dir == OptimizationDirection::Minimize ? OptimizationDirection::Maximize : OptimizationDirection::Minimize, transitionMatrix, backwardTransitions, storm::storage::BitVector(transitionMatrix.getRowGroupCount(), true), ~psiStates, qualitative, false, minMaxLinearEquationSolverFactory).result;
std::vector<ValueType> result = computeUntilProbabilities(dir == OptimizationDirection::Minimize ? OptimizationDirection::Maximize : OptimizationDirection::Minimize, transitionMatrix, backwardTransitions, storm::storage::BitVector(transitionMatrix.getRowGroupCount(), true), ~psiStates, qualitative, false, minMaxLinearEquationSolverFactory).values;
for (auto& element : result) {
element = storm::utility::one<ValueType>() - element;
}
@ -519,14 +517,14 @@ namespace storm {
initialStatesBitVector.set(initialState);
storm::storage::BitVector allStates(initialStatesBitVector.size(), true);
std::vector<ValueType> conditionProbabilities = std::move(computeUntilProbabilities(OptimizationDirection::Maximize, transitionMatrix, backwardTransitions, allStates, conditionStates, false, false, minMaxLinearEquationSolverFactory).result);
std::vector<ValueType> conditionProbabilities = std::move(computeUntilProbabilities(OptimizationDirection::Maximize, transitionMatrix, backwardTransitions, allStates, conditionStates, false, false, minMaxLinearEquationSolverFactory).values);
// If the conditional probability is undefined for the initial state, we return directly.
if (storm::utility::isZero(conditionProbabilities[initialState])) {
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(initialState, storm::utility::infinity<ValueType>()));
}
std::vector<ValueType> targetProbabilities = std::move(computeUntilProbabilities(OptimizationDirection::Maximize, transitionMatrix, backwardTransitions, allStates, fixedTargetStates, false, false, minMaxLinearEquationSolverFactory).result);
std::vector<ValueType> targetProbabilities = std::move(computeUntilProbabilities(OptimizationDirection::Maximize, transitionMatrix, backwardTransitions, allStates, fixedTargetStates, false, false, minMaxLinearEquationSolverFactory).values);
storm::storage::BitVector statesWithProbabilityGreater0E(transitionMatrix.getRowGroupCount(), true);
storm::storage::sparse::state_type state = 0;
@ -594,7 +592,7 @@ namespace storm {
newGoalStates.set(newGoalState);
storm::storage::SparseMatrix<ValueType> newTransitionMatrix = builder.build();
storm::storage::SparseMatrix<ValueType> newBackwardTransitions = newTransitionMatrix.transpose(true);
std::vector<ValueType> goalProbabilities = std::move(computeUntilProbabilities(OptimizationDirection::Maximize, newTransitionMatrix, newBackwardTransitions, storm::storage::BitVector(newFailState + 1, true), newGoalStates, false, false, minMaxLinearEquationSolverFactory).result);
std::vector<ValueType> goalProbabilities = std::move(computeUntilProbabilities(OptimizationDirection::Maximize, newTransitionMatrix, newBackwardTransitions, storm::storage::BitVector(newFailState + 1, true), newGoalStates, false, false, minMaxLinearEquationSolverFactory).values);
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(initialState, dir == OptimizationDirection::Maximize ? goalProbabilities[numberOfStatesBeforeRelevantStates[initialState]] : storm::utility::one<ValueType>() - goalProbabilities[numberOfStatesBeforeRelevantStates[initialState]]));
}

4
src/modelchecker/prctl/helper/SparseMdpPrctlHelper.h

@ -36,9 +36,9 @@ namespace storm {
static std::vector<ValueType> computeNextProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory);
static MDPSparseModelCheckingHelperReturnType<ValueType> computeUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, bool getPolicy, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory);
static MDPSparseModelCheckingHelperReturnType<ValueType> computeUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, bool producePolicy, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory);
static MDPSparseModelCheckingHelperReturnType<ValueType> computeUntilProbabilities(storm::solver::SolveGoal const& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, bool getPolicy, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory);
static MDPSparseModelCheckingHelperReturnType<ValueType> computeUntilProbabilities(storm::solver::SolveGoal const& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, bool producePolicy, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory);
static std::vector<ValueType> computeGloballyProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, bool useMecBasedTechnique = false);

9
src/solver/LinearEquationSolver.h

@ -4,6 +4,7 @@
#include <vector>
#include "src/storage/SparseMatrix.h"
#include "src/solver/AllowEarlyTerminationCondition.h"
namespace storm {
namespace solver {
@ -15,7 +16,6 @@ namespace storm {
template<class Type>
class LinearEquationSolver {
public:
virtual ~LinearEquationSolver() {
// Intentionally left empty.
}
@ -45,6 +45,13 @@ namespace storm {
* vector must be equal to the number of rows of A.
*/
virtual void performMatrixVectorMultiplication(std::vector<Type>& x, std::vector<Type> const* b = nullptr, uint_fast64_t n = 1, std::vector<Type>* multiplyResult = nullptr) const = 0;
void setEarlyTerminationCriterion(std::unique_ptr<AllowEarlyTerminationCondition<ValueType>> v) {
earlyTermination = std::move(v);
}
// A termination criterion to be used (can be unset).
std::unique_ptr<AllowEarlyTerminationCondition<ValueType>> earlyTermination;
};
} // namespace solver

39
src/solver/MinMaxLinearEquationSolver.h

@ -6,8 +6,8 @@
#include <memory>
#include "SolverSelectionOptions.h"
#include "src/storage/sparse/StateType.h"
#include "AllowEarlyTerminationCondition.h"
#include "OptimizationDirection.h"
#include "src/solver/AllowEarlyTerminationCondition.h"
#include "src/solver/OptimizationDirection.h"
namespace storm {
namespace storage {
@ -15,17 +15,18 @@ namespace storm {
}
namespace solver {
/**
* Abstract base class which provides value-type independent helpers.
*/
class AbstractMinMaxLinearEquationSolver {
public:
void setPolicyTracking(bool setToTrue=true);
void setSchedulerTracking(bool trackScheduler = true);
std::vector<storm::storage::sparse::state_type> getPolicy() const;
std::vector<storm::storage::sparse::state_type> getScheduler() const {
STORM_LOG_THROW(scheduler, storm::exceptions::Invali, "Cannot retrieve scheduler, because none was generated.");
reutrn scheduler.get();
}
void setOptimizationDirection(OptimizationDirection d) {
direction = convert(d);
@ -35,14 +36,16 @@ namespace storm {
direction = OptimizationDirectionSetting::Unset;
}
void setEarlyTerminationCriterion(std::unique_ptr<AllowEarlyTerminationCondition<ValueType>> v) {
earlyTermination = std::move(v);
}
protected:
AbstractMinMaxLinearEquationSolver(double precision, bool relativeError, uint_fast64_t maximalIterations, bool trackPolicy, MinMaxTechniqueSelection prefTech);
AbstractMinMaxLinearEquationSolver(double precision, bool relativeError, uint_fast64_t maximalIterations, bool trackScheduler, MinMaxTechniqueSelection prefTech);
/// The direction in which to optimize, can be unset.
OptimizationDirectionSetting direction;
/// The required precision for the iterative methods.
double precision;
@ -55,11 +58,14 @@ namespace storm {
/// Whether value iteration or policy iteration is to be used.
bool useValueIteration;
/// Whether we track the policy we generate.
bool trackPolicy;
/// Whether we generate a scheduler during solving.
bool trackScheduler;
///
mutable std::vector<storm::storage::sparse::state_type> policy;
/// The scheduler (if it could be successfully generated).
boost::optional<storm::storage::Scheduler> scheduler;
// A termination criterion to be used (can be unset).
std::unique_ptr<AllowEarlyTerminationCondition<ValueType>> earlyTermination;
};
/*!
@ -77,7 +83,6 @@ namespace storm {
}
public:
virtual ~MinMaxLinearEquationSolver() {
// Intentionally left empty.
}
@ -107,6 +112,7 @@ namespace storm {
assert(isSet(this->direction));
solveEquationSystem(convert(this->direction), x, b, multiplyResult, newX);
}
/*!
* 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
@ -134,15 +140,8 @@ namespace storm {
return performMatrixVectorMultiplication(convert(this->direction), x, b, n, multiplyResult);
}
void setEarlyTerminationCriterion(std::unique_ptr<AllowEarlyTerminationCondition<ValueType>> v) {
earlyTermination = std::move(v);
}
protected:
storm::storage::SparseMatrix<ValueType> const& A;
std::unique_ptr<AllowEarlyTerminationCondition<ValueType>> earlyTermination;
};
} // namespace solver

46
src/solver/SolveGoal.cpp

@ -1,36 +1,56 @@
#include "SolveGoal.h"
#include <memory>
#include "src/utility/solver.h"
#include "src/solver/LinearEquationSolver.h"
#include "src/solver/MinMaxLinearEquationSolver.h"
#include <memory>
namespace storm {
namespace storage {
template <typename VT> class SparseMatrix;
template <typename ValueType> class SparseMatrix;
}
namespace solver {
template<typename VT>
std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<VT>> configureMinMaxLinearEquationSolver(BoundedGoal<VT> const& goal, storm::utility::solver::MinMaxLinearEquationSolverFactory<VT> const& factory, storm::storage::SparseMatrix<VT> const& matrix) {
std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<VT>> p = factory.create(matrix);
template<typename ValueType>
std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> configureMinMaxLinearEquationSolver(BoundedGoal<ValueType> const& goal, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& factory, storm::storage::SparseMatrix<ValueType> const& matrix) {
std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> p = factory.create(matrix);
p->setOptimizationDirection(goal.direction());
p->setEarlyTerminationCriterion(std::make_unique<TerminateAfterFilteredExtremumPassesThresholdValue<double>>(goal.relevantColumns(), goal.threshold, goal.minimize()));
p->setEarlyTerminationCriterion(std::make_unique<TerminateAfterFilteredExtremumPassesThresholdValue<double>>(goal.relevantColumns(), goal.thresholdValue(), goal.minimize()));
return p;
}
template<typename VT>
std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<VT>> configureMinMaxLinearEquationSolver(SolveGoal const& goal, storm::utility::solver::MinMaxLinearEquationSolverFactory<VT> const& factory, storm::storage::SparseMatrix<VT> const& matrix) {
if(goal.isBounded()) {
return configureMinMaxLinearEquationSolver(static_cast<BoundedGoal<VT> const&>(goal), factory, matrix);
template<typename ValueType>
std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> configureMinMaxLinearEquationSolver(SolveGoal const& goal, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& factory, storm::storage::SparseMatrix<ValueType> const& matrix) {
if (goal.isBounded()) {
return configureMinMaxLinearEquationSolver(static_cast<BoundedGoal<ValueType> const&>(goal), factory, matrix);
}
std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<VT>> p = factory.create(matrix);
std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> p = factory.create(matrix);
p->setOptimizationDirection(goal.direction());
return p;
}
template<typename ValueType>
std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> configureLinearEquationSolver(BoundedGoal<ValueType> const& goal, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& factory, storm::storage::SparseMatrix<ValueType> const& matrix) {
std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> p = factory.create(matrix);
p->setOptimizationDirection(goal.direction());
p->setEarlyTerminationCriterion(std::make_unique<TerminateAfterFilteredExtremumPassesThresholdValue<double>>(goal.relevantColumns(), goal.thresholdValue(), goal.minimize()));
return p;
}
}
template<typename ValueType>
std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> configureLinearEquationSolver(SolveGoal const& goal, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& factory, storm::storage::SparseMatrix<ValueType> const& matrix) {
if (goal.isBounded()) {
return configureLinearEquationSolver(static_cast<BoundedGoal<ValueType> const&>(goal), factory, matrix);
}
return factory.create(matrix);
}
template std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<double>> configureMinMaxLinearEquationSolver(BoundedGoal<double> const& goal, storm::utility::solver::MinMaxLinearEquationSolverFactory<double> const& factory, storm::storage::SparseMatrix<double> const& matrix);
template std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<double>> configureMinMaxLinearEquationSolver(BoundedGoal<double> const& goal, storm::utility::solver::MinMaxLinearEquationSolverFactory<double> const& factory, storm::storage::SparseMatrix<double> const& matrix);
template std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<double>> configureMinMaxLinearEquationSolver(SolveGoal const& goal, storm::utility::solver::MinMaxLinearEquationSolverFactory<double> const& factory, storm::storage::SparseMatrix<double> const& matrix);
template std::unique_ptr<storm::solver::LinearEquationSolver<double>> configureLinearEquationSolver(BoundedGoal<double> const& goal, storm::utility::solver::LinearEquationSolverFactory<double> const& factory, storm::storage::SparseMatrix<double> const& matrix);
template std::unique_ptr<storm::solver::LinearEquationSolver<double>> configureLinearEquationSolver(SolveGoal const& goal, storm::utility::solver::LinearEquationSolverFactory<double> const& factory, storm::storage::SparseMatrix<double> const& matrix);
}
}

94
src/solver/SolveGoal.h

@ -10,59 +10,99 @@
namespace storm {
namespace storage {
template<typename VT> class SparseMatrix;
template<typename ValueType> class SparseMatrix;
}
namespace utility {
namespace solver {
template<typename VT> class MinMaxLinearEquationSolverFactory;
template<typename ValueType> class MinMaxLinearEquationSolverFactory;
template<typename ValueType> class LinearEquationSolverFactory;
}
}
namespace solver {
template<typename VT> class MinMaxLinearEquationSolver;
template<typename ValueType> class MinMaxLinearEquationSolver;
template<typename ValueType> class LinearEquationSolver;
class SolveGoal {
public:
SolveGoal(bool minimize) : optDirection(minimize ? OptimizationDirection::Minimize : OptimizationDirection::Maximize) {}
SolveGoal(OptimizationDirection d) : optDirection(d) {}
virtual ~SolveGoal() {}
SolveGoal(bool minimize) : optimizationDirection(minimize ? OptimizationDirection::Minimize : OptimizationDirection::Maximize) {
// Intentionally left empty.
}
SolveGoal(OptimizationDirection d) : optimizationDirection(d) {
// Intentionally left empty.
}
virtual ~SolveGoal() {
// Intentionally left empty.
}
bool minimize() const { return optDirection == OptimizationDirection::Minimize; }
OptimizationDirection direction() const { return optDirection; }
virtual bool isBounded() const { return false; }
bool minimize() const {
return optimizationDirection == OptimizationDirection::Minimize;
}
OptimizationDirection direction() const {
return optimizationDirection;
}
virtual bool isBounded() const {
return false;
}
private:
OptimizationDirection optDirection;
OptimizationDirection optimizationDirection;
};
template<typename VT>
template<typename ValueType>
class BoundedGoal : public SolveGoal {
public:
BoundedGoal(OptimizationDirection dir, storm::logic::ComparisonType ct, VT const& threshold, storm::storage::BitVector const& relColumns) : SolveGoal(dir), boundType(ct), threshold(threshold), relevantColumnVector(relColumns) {}
BoundedGoal(OptimizationDirection dir, storm::logic::BoundInfo<VT> const& bi, storm::storage::BitVector const& relColumns) : SolveGoal(dir), boundType(bi.boundType), threshold(bi.bound), relevantColumnVector(relColumns) {}
virtual ~BoundedGoal() {}
BoundedGoal(OptimizationDirection optimizationDirection, storm::logic::ComparisonType ct, ValueType const& threshold, storm::storage::BitVector const& relColumns) : SolveGoal(optimizationDirection), boundType(ct), threshold(threshold), relevantColumnVector(relColumns) {
// Intentionally left empty.
}
bool isBounded() const override { return true; }
BoundedGoal(OptimizationDirection optimizationDirection, storm::logic::BoundInfo<ValueType> const& boundInfo, storm::storage::BitVector const& relevantColumns) : SolveGoal(optimizationDirection), boundType(boundInfo.boundType), threshold(boundInfo.bound), relevantColumnVector(relevantColumns) {
// Intentionally left empty.
}
virtual ~BoundedGoal() {
// Intentionally left empty.
}
bool isBounded() const override {
return true;
}
bool boundIsALowerBound() const {
return (boundType == storm::logic::ComparisonType::Greater |
boundType == storm::logic::ComparisonType::GreaterEqual);
return (boundType == storm::logic::ComparisonType::Greater || boundType == storm::logic::ComparisonType::GreaterEqual);
}
ValueType const& thresholdValue() const {
return threshold;
}
VT thresholdValue() const { return threshold; }
storm::storage::BitVector relevantColumns() const { return relevantColumnVector; }
storm::storage::BitVector const& relevantColumns() const {
return relevantColumnVector;
}
private:
storm::logic::ComparisonType boundType;
VT threshold;
ValueType threshold;
storm::storage::BitVector relevantColumnVector;
};
template<typename VT>
std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<VT>> configureMinMaxLinearEquationSolver(BoundedGoal<VT> const& goal, storm::utility::solver::MinMaxLinearEquationSolverFactory<VT> const& factory, storm::storage::SparseMatrix<VT> const& matrix);
template<typename VT>
std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<VT>> configureMinMaxLinearEquationSolver(SolveGoal const& goal, storm::utility::solver::MinMaxLinearEquationSolverFactory<VT> const& factory, storm::storage::SparseMatrix<VT> const& matrix);
template<typename ValueType>
std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> configureMinMaxLinearEquationSolver(BoundedGoal<ValueType> const& goal, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& factory, storm::storage::SparseMatrix<ValueType> const& matrix);
template<typename ValueType>
std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> configureMinMaxLinearEquationSolver(SolveGoal const& goal, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& factory, storm::storage::SparseMatrix<ValueType> const& matrix);
template<typename ValueType>
std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> configureLinearEquationSolver(BoundedGoal<ValueType> const& goal, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& factory, storm::storage::SparseMatrix<ValueType> const& matrix);
template<typename ValueType>
std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> configureLinearEquationSolver(SolveGoal const& goal, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& factory, storm::storage::SparseMatrix<ValueType> const& matrix);
}
}

Loading…
Cancel
Save