#pragma once #include #include "storm/storage/Scheduler.h" #include "storm/models/sparse/Mdp.h" #include "storm/models/sparse/MarkovAutomaton.h" #include "storm/modelchecker/multiobjective/SparseMultiObjectivePreprocessorResult.h" #include "storm/modelchecker/multiobjective/Objective.h" namespace storm { namespace modelchecker { namespace multiobjective { /*! * Helper Class that takes a weight vector and ... * - computes the optimal value w.r.t. the weighted sum of the individual objectives * - extracts the scheduler that induces this optimum * - computes for each objective the value induced by this scheduler */ template class PcaaWeightVectorChecker { public: typedef typename ModelType::ValueType ValueType; /* * Creates a weight vector checker. * * @param objectives The (preprocessed) objectives * */ PcaaWeightVectorChecker(std::vector> const& objectives); virtual ~PcaaWeightVectorChecker() = default; virtual void check(std::vector const& weightVector) = 0; /*! * Retrieves the results of the individual objectives at the initial state of the given model. * Note that check(..) has to be called before retrieving results. Otherwise, an exception is thrown. * Also note that there is no guarantee that the under/over approximation is in fact correct * as long as the underlying solution methods are unsound (e.g., standard value iteration). */ virtual std::vector getUnderApproximationOfInitialStateResults() const = 0; virtual std::vector getOverApproximationOfInitialStateResults() const = 0; /*! * Sets the precision of this weight vector checker. After calling check() the following will hold: * Let h_lower and h_upper be two hyperplanes such that * * the normal vector is the provided weight-vector where the entry for minimizing objectives is negated * * getUnderApproximationOfInitialStateResults() lies on h_lower and * * getOverApproximationOfInitialStateResults() lies on h_upper. * Then the distance between the two hyperplanes is at most weightedPrecision */ void setWeightedPrecision(ValueType const& value); /*! * Returns the precision of this weight vector checker. */ ValueType const& getWeightedPrecision() const; /*! * Retrieves a scheduler that induces the current values (if such a scheduler was generated). * Note that check(..) has to be called before retrieving the scheduler. Otherwise, an exception is thrown. */ virtual storm::storage::Scheduler computeScheduler() const; protected: /*! * Computes the weighted lower or upper bounds for the provided set of objectives. * @param lower if true, lower result bounds are computed. otherwise upper result bounds * @param weightVector the weight vector ooof the current check */ boost::optional computeWeightedResultBound(bool lower, std::vector const& weightVector, storm::storage::BitVector const& objectiveFilter) const; // The (preprocessed) objectives std::vector> objectives; // The precision of this weight vector checker. ValueType weightedPrecision; }; template class WeightVectorCheckerFactory { public: template>::value, int>::type = 0> static std::unique_ptr> create(SparseMultiObjectivePreprocessorResult const& preprocessorResult); template>::value, int>::type = 0> static std::unique_ptr> create(SparseMultiObjectivePreprocessorResult const& preprocessorResult); }; } } }