5 changed files with 315 additions and 6 deletions
			
			
		- 
					101src/modelchecker/multiobjective/pcaa/SparsePcaaAchievabilityQuery.cpp
 - 
					58src/modelchecker/multiobjective/pcaa/SparsePcaaAchievabilityQuery.h
 - 
					101src/modelchecker/multiobjective/pcaa/SparsePcaaParetoQuery.cpp
 - 
					47src/modelchecker/multiobjective/pcaa/SparsePcaaParetoQuery.h
 - 
					14test/functional/transformer/EndComponentEliminatorTest.cpp
 
@ -0,0 +1,101 @@ | 
				
			|||
#include "src/modelchecker/multiobjective/pcaa/SparsePcaaAchievabilityQuery.h"
 | 
				
			|||
 | 
				
			|||
#include "src/adapters/CarlAdapter.h"
 | 
				
			|||
#include "src/models/sparse/Mdp.h"
 | 
				
			|||
#include "src/models/sparse/MarkovAutomaton.h"
 | 
				
			|||
#include "src/models/sparse/StandardRewardModel.h"
 | 
				
			|||
#include "src/modelchecker/results/ExplicitQualitativeCheckResult.h"
 | 
				
			|||
#include "src/utility/constants.h"
 | 
				
			|||
#include "src/utility/vector.h"
 | 
				
			|||
#include "src/settings//SettingsManager.h"
 | 
				
			|||
#include "src/settings/modules/GeneralSettings.h"
 | 
				
			|||
#include "src/settings/modules/MultiObjectiveSettings.h"
 | 
				
			|||
 | 
				
			|||
namespace storm { | 
				
			|||
    namespace modelchecker { | 
				
			|||
        namespace multiobjective { | 
				
			|||
             | 
				
			|||
             | 
				
			|||
            template <class SparseModelType, typename GeometryValueType> | 
				
			|||
            SparsePcaaAchievabilityQuery<SparseModelType, GeometryValueType>::SparsePcaaAchievabilityQuery(SparsePcaaPreprocessorReturnType<SparseModelType>& preprocessorResult) : SparsePcaaQuery<SparseModelType, GeometryValueType>(preprocessorResult) { | 
				
			|||
                STORM_LOG_ASSERT(preprocessorResult.queryType==SparsePcaaPreprocessorReturnType<SparseModelType>::QueryType::Achievability, "Invalid query Type"); | 
				
			|||
                initializeThresholdData(); | 
				
			|||
                 | 
				
			|||
                // Set the maximum gap between lower and upper bound of the weightVectorChecker result.
 | 
				
			|||
                // This is the maximal edge length of the box we have to consider around each computed point
 | 
				
			|||
                // We pick the gap such that the maximal distance between two points within this box is less than the given precision divided by two.
 | 
				
			|||
                typename SparseModelType::ValueType gap = storm::utility::convertNumber<typename SparseModelType::ValueType>(storm::settings::getModule<storm::settings::modules::MultiObjectiveSettings>().getPrecision()); | 
				
			|||
                gap /= (storm::utility::one<typename SparseModelType::ValueType>() + storm::utility::one<typename SparseModelType::ValueType>()); | 
				
			|||
                gap /= storm::utility::sqrt(static_cast<typename SparseModelType::ValueType>(this->objectives.size())); | 
				
			|||
                this->weightVectorChecker->setMaximumLowerUpperBoundGap(gap); | 
				
			|||
                 | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            template <class SparseModelType, typename GeometryValueType> | 
				
			|||
            void SparsePcaaAchievabilityQuery<SparseModelType, GeometryValueType>::initializeThresholdData() { | 
				
			|||
                thresholds.reserve(this->objectives.size()); | 
				
			|||
                strictThresholds = storm::storage::BitVector(this->objectives.size(), false); | 
				
			|||
                for(uint_fast64_t objIndex = 0; objIndex < this->objectives.size(); ++objIndex) { | 
				
			|||
                    thresholds.push_back(storm::utility::convertNumber<GeometryValueType>(*this->objectives[objIndex].threshold)); | 
				
			|||
                    strictThresholds.set(objIndex, this->objectives[objIndex].thresholdIsStrict); | 
				
			|||
                } | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            template <class SparseModelType, typename GeometryValueType> | 
				
			|||
            std::unique_ptr<CheckResult> SparsePcaaAchievabilityQuery<SparseModelType, GeometryValueType>::check() { | 
				
			|||
                | 
				
			|||
                bool result = this->checkAchievability(); | 
				
			|||
                 | 
				
			|||
                return std::unique_ptr<CheckResult>(new ExplicitQualitativeCheckResult(this->originalModel.getInitialStates().getNextSetIndex(0), result)); | 
				
			|||
                 | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            template <class SparseModelType, typename GeometryValueType> | 
				
			|||
            bool SparsePcaaAchievabilityQuery<SparseModelType, GeometryValueType>::checkAchievability() { | 
				
			|||
                // repeatedly refine the over/ under approximation until the threshold point is either in the under approx. or not in the over approx.
 | 
				
			|||
                while(!this->maxStepsPerformed()){ | 
				
			|||
                    WeightVector separatingVector = this->findSeparatingVector(thresholds); | 
				
			|||
                    this->performRefinementStep(std::move(separatingVector)); | 
				
			|||
                    if(!checkIfThresholdsAreSatisfied(this->overApproximation)){ | 
				
			|||
                        return false; | 
				
			|||
                    } | 
				
			|||
                    if(checkIfThresholdsAreSatisfied(this->underApproximation)){ | 
				
			|||
                        return true; | 
				
			|||
                    } | 
				
			|||
                } | 
				
			|||
                STORM_LOG_ERROR("Could not check whether thresholds are achievable: Exceeded maximum number of refinement steps"); | 
				
			|||
                return false; | 
				
			|||
            } | 
				
			|||
 | 
				
			|||
             | 
				
			|||
            template <class SparseModelType, typename GeometryValueType> | 
				
			|||
            bool SparsePcaaAchievabilityQuery<SparseModelType, GeometryValueType>::checkIfThresholdsAreSatisfied(std::shared_ptr<storm::storage::geometry::Polytope<GeometryValueType>> const& polytope) { | 
				
			|||
                std::vector<storm::storage::geometry::Halfspace<GeometryValueType>> halfspaces = polytope->getHalfspaces(); | 
				
			|||
                for(auto const& h : halfspaces) { | 
				
			|||
                    GeometryValueType distance = h.distance(thresholds); | 
				
			|||
                    if(distance < storm::utility::zero<GeometryValueType>()) { | 
				
			|||
                        return false; | 
				
			|||
                    } | 
				
			|||
                    if(distance == storm::utility::zero<GeometryValueType>()) { | 
				
			|||
                        // In this case, the thresholds point is on the boundary of the polytope.
 | 
				
			|||
                        // Check if this is problematic for the strict thresholds
 | 
				
			|||
                        for(auto strictThreshold : strictThresholds) { | 
				
			|||
                            if(h.normalVector()[strictThreshold] > storm::utility::zero<GeometryValueType>()) { | 
				
			|||
                                return false; | 
				
			|||
                            } | 
				
			|||
                        } | 
				
			|||
                    } | 
				
			|||
                } | 
				
			|||
                return true; | 
				
			|||
            } | 
				
			|||
 | 
				
			|||
#ifdef STORM_HAVE_CARL
 | 
				
			|||
            template class SparsePcaaAchievabilityQuery<storm::models::sparse::Mdp<double>, storm::RationalNumber>; | 
				
			|||
            template class SparsePcaaAchievabilityQuery<storm::models::sparse::MarkovAutomaton<double>, storm::RationalNumber>; | 
				
			|||
             | 
				
			|||
            template class SparsePcaaAchievabilityQuery<storm::models::sparse::Mdp<storm::RationalNumber>, storm::RationalNumber>; | 
				
			|||
         //   template class SparsePcaaAchievabilityQuery<storm::models::sparse::MarkovAutomaton<storm::RationalNumber>, storm::RationalNumber>;
 | 
				
			|||
#endif
 | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
@ -0,0 +1,58 @@ | 
				
			|||
#ifndef STORM_MODELCHECKER_MULTIOBJECTIVE_PCAA_SPARSEPCAAACHIEVABILITYQUERY_H_ | 
				
			|||
#define STORM_MODELCHECKER_MULTIOBJECTIVE_PCAA_SPARSEPCAAACHIEVABILITYQUERY_H_ | 
				
			|||
 | 
				
			|||
#include "src/modelchecker/multiobjective/pcaa/SparsePcaaQuery.h" | 
				
			|||
 | 
				
			|||
namespace storm { | 
				
			|||
    namespace modelchecker { | 
				
			|||
        namespace multiobjective { | 
				
			|||
             | 
				
			|||
            /* | 
				
			|||
             * This class represents a query for the Pareto curve approximation algorithm (Pcaa). | 
				
			|||
             * It implements the necessary computations for the different query types. | 
				
			|||
             */ | 
				
			|||
            template <class SparseModelType, typename GeometryValueType> | 
				
			|||
            class SparsePcaaAchievabilityQuery : public SparsePcaaQuery<SparseModelType, GeometryValueType> { | 
				
			|||
            public: | 
				
			|||
                 | 
				
			|||
                // Typedefs for simple geometric objects | 
				
			|||
                typedef std::vector<GeometryValueType> Point; | 
				
			|||
                typedef std::vector<GeometryValueType> WeightVector; | 
				
			|||
                 | 
				
			|||
                /* | 
				
			|||
                 * Creates a new query for the Pareto curve approximation algorithm (Pcaa) | 
				
			|||
                 * @param preprocessorResult the result from preprocessing | 
				
			|||
                 */ | 
				
			|||
                SparsePcaaAchievabilityQuery(SparsePcaaPreprocessorReturnType<SparseModelType>& preprocessorResult); | 
				
			|||
                 | 
				
			|||
                 | 
				
			|||
                /* | 
				
			|||
                 * Invokes the computation and retrieves the result | 
				
			|||
                 */ | 
				
			|||
                virtual std::unique_ptr<CheckResult> check() override; | 
				
			|||
                 | 
				
			|||
            private: | 
				
			|||
                 | 
				
			|||
                void initializeThresholdData(); | 
				
			|||
                 | 
				
			|||
                /*  | 
				
			|||
                 * Returns whether the given thresholds are achievable. | 
				
			|||
                 */ | 
				
			|||
                bool checkAchievability(); | 
				
			|||
                 | 
				
			|||
                /* | 
				
			|||
                 * Returns true iff there is one point in the given polytope that satisfies the given thresholds. | 
				
			|||
                 * It is assumed that the given polytope contains the downward closure of its vertices. | 
				
			|||
                 */ | 
				
			|||
                bool checkIfThresholdsAreSatisfied(std::shared_ptr<storm::storage::geometry::Polytope<GeometryValueType>> const& polytope); | 
				
			|||
 | 
				
			|||
                 | 
				
			|||
                Point thresholds; | 
				
			|||
                storm::storage::BitVector strictThresholds; | 
				
			|||
            }; | 
				
			|||
             | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
 | 
				
			|||
#endif /* STORM_MODELCHECKER_MULTIOBJECTIVE_PCAA_SPARSEPCAAACHIEVABILITYQUERY_H_ */ | 
				
			|||
@ -0,0 +1,101 @@ | 
				
			|||
#include "src/modelchecker/multiobjective/pcaa/SparsePcaaParetoQuery.h"
 | 
				
			|||
 | 
				
			|||
#include "src/adapters/CarlAdapter.h"
 | 
				
			|||
#include "src/models/sparse/Mdp.h"
 | 
				
			|||
#include "src/models/sparse/MarkovAutomaton.h"
 | 
				
			|||
#include "src/models/sparse/StandardRewardModel.h"
 | 
				
			|||
#include "src/modelchecker/results/ParetoCurveCheckResult.h"
 | 
				
			|||
#include "src/utility/constants.h"
 | 
				
			|||
#include "src/utility/vector.h"
 | 
				
			|||
#include "src/settings//SettingsManager.h"
 | 
				
			|||
#include "src/settings/modules/MultiObjectiveSettings.h"
 | 
				
			|||
#include "src/settings/modules/GeneralSettings.h"
 | 
				
			|||
 | 
				
			|||
 | 
				
			|||
namespace storm { | 
				
			|||
    namespace modelchecker { | 
				
			|||
        namespace multiobjective { | 
				
			|||
             | 
				
			|||
            template <class SparseModelType, typename GeometryValueType> | 
				
			|||
            SparsePcaaParetoQuery<SparseModelType, GeometryValueType>::SparsePcaaParetoQuery(SparsePcaaPreprocessorReturnType<SparseModelType>& preprocessorResult) : SparsePcaaQuery<SparseModelType, GeometryValueType>(preprocessorResult) { | 
				
			|||
                STORM_LOG_ASSERT(preprocessorResult.queryType==SparsePcaaPreprocessorReturnType<SparseModelType>::QueryType::Pareto, "Invalid query Type"); | 
				
			|||
                 | 
				
			|||
                // Set the maximum gap between lower and upper bound of the weightVectorChecker result.
 | 
				
			|||
                // This is the maximal edge length of the box we have to consider around each computed point
 | 
				
			|||
                // We pick the gap such that the maximal distance between two points within this box is less than the given precision divided by two.
 | 
				
			|||
                typename SparseModelType::ValueType gap = storm::utility::convertNumber<typename SparseModelType::ValueType>(storm::settings::getModule<storm::settings::modules::MultiObjectiveSettings>().getPrecision()); | 
				
			|||
                gap /= (storm::utility::one<typename SparseModelType::ValueType>() + storm::utility::one<typename SparseModelType::ValueType>()); | 
				
			|||
                gap /= storm::utility::sqrt(static_cast<typename SparseModelType::ValueType>(this->objectives.size())); | 
				
			|||
                this->weightVectorChecker->setMaximumLowerUpperBoundGap(gap); | 
				
			|||
                 | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            template <class SparseModelType, typename GeometryValueType> | 
				
			|||
            std::unique_ptr<CheckResult> SparsePcaaParetoQuery<SparseModelType, GeometryValueType>::check() { | 
				
			|||
                 | 
				
			|||
                // refine the approximation
 | 
				
			|||
                exploreSetOfAchievablePoints(); | 
				
			|||
                 | 
				
			|||
                // obtain the data for the checkresult
 | 
				
			|||
                std::vector<std::vector<typename SparseModelType::ValueType>> paretoOptimalPoints; | 
				
			|||
                paretoOptimalPoints.reserve(this->refinementSteps.size()); | 
				
			|||
                for(auto const& step : this->refinementSteps) { | 
				
			|||
                    paretoOptimalPoints.push_back(storm::utility::vector::convertNumericVector<typename SparseModelType::ValueType>(this->transformPointToOriginalModel(step.lowerBoundPoint))); | 
				
			|||
                } | 
				
			|||
                return std::unique_ptr<CheckResult>(new ParetoCurveCheckResult<typename SparseModelType::ValueType>(this->originalModel.getInitialStates().getNextSetIndex(0), | 
				
			|||
                                                                        std::move(paretoOptimalPoints), | 
				
			|||
                                                                        this->transformPolytopeToOriginalModel(this->underApproximation)->template convertNumberRepresentation<typename SparseModelType::ValueType>(), | 
				
			|||
                                                                        this->transformPolytopeToOriginalModel(this->overApproximation)->template convertNumberRepresentation<typename SparseModelType::ValueType>())); | 
				
			|||
                 | 
				
			|||
                 | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            template <class SparseModelType, typename GeometryValueType> | 
				
			|||
            void SparsePcaaParetoQuery<SparseModelType, GeometryValueType>::exploreSetOfAchievablePoints() { | 
				
			|||
             | 
				
			|||
                //First consider the objectives individually
 | 
				
			|||
                for(uint_fast64_t objIndex = 0; objIndex<this->objectives.size() && !this->maxStepsPerformed(); ++objIndex) { | 
				
			|||
                    WeightVector direction(this->objectives.size(), storm::utility::zero<GeometryValueType>()); | 
				
			|||
                    direction[objIndex] = storm::utility::one<GeometryValueType>(); | 
				
			|||
                    this->performRefinementStep(std::move(direction)); | 
				
			|||
                } | 
				
			|||
                 | 
				
			|||
                while(!this->maxStepsPerformed()) { | 
				
			|||
                    // Get the halfspace of the underApproximation with maximal distance to a vertex of the overApproximation
 | 
				
			|||
                    std::vector<storm::storage::geometry::Halfspace<GeometryValueType>> underApproxHalfspaces = this->underApproximation->getHalfspaces(); | 
				
			|||
                    std::vector<Point> overApproxVertices = this->overApproximation->getVertices(); | 
				
			|||
                    uint_fast64_t farestHalfspaceIndex = underApproxHalfspaces.size(); | 
				
			|||
                    GeometryValueType farestDistance = storm::utility::zero<GeometryValueType>(); | 
				
			|||
                    for(uint_fast64_t halfspaceIndex = 0; halfspaceIndex < underApproxHalfspaces.size(); ++halfspaceIndex) { | 
				
			|||
                        for(auto const& vertex : overApproxVertices) { | 
				
			|||
                            GeometryValueType distance = -underApproxHalfspaces[halfspaceIndex].euclideanDistance(vertex); | 
				
			|||
                            if(distance > farestDistance) { | 
				
			|||
                                farestHalfspaceIndex = halfspaceIndex; | 
				
			|||
                                farestDistance = distance; | 
				
			|||
                            } | 
				
			|||
                        } | 
				
			|||
                    } | 
				
			|||
                    if(farestDistance < storm::utility::convertNumber<GeometryValueType>(storm::settings::getModule<storm::settings::modules::MultiObjectiveSettings>().getPrecision())) { | 
				
			|||
                        // Goal precision reached!
 | 
				
			|||
                        return; | 
				
			|||
                    } | 
				
			|||
                    STORM_LOG_DEBUG("Current precision of the approximation of the pareto curve is ~" << storm::utility::convertNumber<double>(farestDistance)); | 
				
			|||
                    WeightVector direction = underApproxHalfspaces[farestHalfspaceIndex].normalVector(); | 
				
			|||
                    this->performRefinementStep(std::move(direction)); | 
				
			|||
                } | 
				
			|||
                STORM_LOG_ERROR("Could not reach the desired precision: Exceeded maximum number of refinement steps"); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
             | 
				
			|||
 | 
				
			|||
             | 
				
			|||
#ifdef STORM_HAVE_CARL
 | 
				
			|||
            template class SparsePcaaParetoQuery<storm::models::sparse::Mdp<double>, storm::RationalNumber>; | 
				
			|||
            template class SparsePcaaParetoQuery<storm::models::sparse::MarkovAutomaton<double>, storm::RationalNumber>; | 
				
			|||
             | 
				
			|||
            template class SparsePcaaParetoQuery<storm::models::sparse::Mdp<storm::RationalNumber>, storm::RationalNumber>; | 
				
			|||
          //  template class SparsePcaaParetoQuery<storm::models::sparse::MarkovAutomaton<storm::RationalNumber>, storm::RationalNumber>;
 | 
				
			|||
#endif
 | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
@ -0,0 +1,47 @@ | 
				
			|||
#ifndef STORM_MODELCHECKER_MULTIOBJECTIVE_PCAA_SPARSEPCAAPARETOQUERY_H_ | 
				
			|||
#define STORM_MODELCHECKER_MULTIOBJECTIVE_PCAA_SPARSEPCAAPARETOQUERY_H_ | 
				
			|||
 | 
				
			|||
#include "src/modelchecker/multiobjective/pcaa/SparsePcaaQuery.h" | 
				
			|||
 | 
				
			|||
namespace storm { | 
				
			|||
    namespace modelchecker { | 
				
			|||
        namespace multiobjective { | 
				
			|||
             | 
				
			|||
            /* | 
				
			|||
             * This class represents a query for the Pareto curve approximation algorithm (Pcaa). | 
				
			|||
             * It implements the necessary computations for the different query types. | 
				
			|||
             */ | 
				
			|||
            template <class SparseModelType, typename GeometryValueType> | 
				
			|||
            class SparsePcaaParetoQuery : public SparsePcaaQuery<SparseModelType, GeometryValueType> { | 
				
			|||
            public: | 
				
			|||
                 | 
				
			|||
                // Typedefs for simple geometric objects | 
				
			|||
                typedef std::vector<GeometryValueType> Point; | 
				
			|||
                typedef std::vector<GeometryValueType> WeightVector; | 
				
			|||
                 | 
				
			|||
                /* | 
				
			|||
                 * Creates a new query for the Pareto curve approximation algorithm (Pcaa) | 
				
			|||
                 * @param preprocessorResult the result from preprocessing | 
				
			|||
                 */ | 
				
			|||
                SparsePcaaParetoQuery(SparsePcaaPreprocessorReturnType<SparseModelType>& preprocessorResult); | 
				
			|||
                 | 
				
			|||
                 | 
				
			|||
                /* | 
				
			|||
                 * Invokes the computation and retrieves the result | 
				
			|||
                 */ | 
				
			|||
                virtual std::unique_ptr<CheckResult> check() override; | 
				
			|||
                 | 
				
			|||
            private: | 
				
			|||
                 | 
				
			|||
                 | 
				
			|||
                /*  | 
				
			|||
                 * Performs refinement steps until the approximation is sufficiently precise | 
				
			|||
                 */ | 
				
			|||
                void exploreSetOfAchievablePoints(); | 
				
			|||
            }; | 
				
			|||
             | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
 | 
				
			|||
#endif /* STORM_MODELCHECKER_MULTIOBJECTIVE_PCAA_SPARSEPCAAPARETOQUERY_H_ */ | 
				
			|||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue