#include "storm/modelchecker/multiobjective/pcaa/SparsePcaaParetoQuery.h" #include "storm/adapters/RationalFunctionAdapter.h" #include "storm/models/sparse/Mdp.h" #include "storm/models/sparse/MarkovAutomaton.h" #include "storm/models/sparse/StandardRewardModel.h" #include "storm/modelchecker/results/ExplicitParetoCurveCheckResult.h" #include "storm/utility/constants.h" #include "storm/utility/vector.h" #include "storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h" namespace storm { namespace modelchecker { namespace multiobjective { template SparsePcaaParetoQuery::SparsePcaaParetoQuery(SparseMultiObjectivePreprocessorResult& preprocessorResult) : SparsePcaaQuery(preprocessorResult) { STORM_LOG_ASSERT(preprocessorResult.queryType==SparseMultiObjectivePreprocessorResult::QueryType::Pareto, "Invalid query Type"); } template std::unique_ptr SparsePcaaParetoQuery::check(Environment const& env) { // Set the precision of the weight vector checker typename SparseModelType::ValueType weightedPrecision = storm::utility::convertNumber(env.modelchecker().multi().getPrecision()); weightedPrecision /= storm::utility::sqrt(storm::utility::convertNumber(this->objectives.size())); // multiobjPrecision / sqrt(numObjectives) is the largest possible value for which termination is guaranteed. // Lets be a little bit more precise to reduce the number of required iterations. weightedPrecision *= storm::utility::convertNumber(0.9); this->weightVectorChecker->setWeightedPrecision(weightedPrecision); // refine the approximation exploreSetOfAchievablePoints(env); // obtain the data for the checkresult std::vector> paretoOptimalPoints; std::vector vertices = this->underApproximation->getVertices(); paretoOptimalPoints.reserve(vertices.size()); for(auto const& vertex : vertices) { paretoOptimalPoints.push_back(storm::utility::vector::convertNumericVector(this->transformPointToOriginalModel(vertex))); } return std::unique_ptr(new ExplicitParetoCurveCheckResult(this->originalModel.getInitialStates().getNextSetIndex(0), std::move(paretoOptimalPoints), this->transformPolytopeToOriginalModel(this->underApproximation)->template convertNumberRepresentation(), this->transformPolytopeToOriginalModel(this->overApproximation)->template convertNumberRepresentation())); } template void SparsePcaaParetoQuery::exploreSetOfAchievablePoints(Environment const& env) { //First consider the objectives individually for(uint_fast64_t objIndex = 0; objIndexobjectives.size() && !this->maxStepsPerformed(env); ++objIndex) { WeightVector direction(this->objectives.size(), storm::utility::zero()); direction[objIndex] = storm::utility::one(); this->performRefinementStep(env, std::move(direction)); } while(!this->maxStepsPerformed(env)) { // Get the halfspace of the underApproximation with maximal distance to a vertex of the overApproximation std::vector> underApproxHalfspaces = this->underApproximation->getHalfspaces(); std::vector overApproxVertices = this->overApproximation->getVertices(); uint_fast64_t farestHalfspaceIndex = underApproxHalfspaces.size(); GeometryValueType farestDistance = storm::utility::zero(); 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(env.modelchecker().multi().getPrecision())) { // Goal precision reached! return; } STORM_LOG_INFO("Current precision of the approximation of the pareto curve is ~" << storm::utility::convertNumber(farestDistance)); WeightVector direction = underApproxHalfspaces[farestHalfspaceIndex].normalVector(); this->performRefinementStep(env, 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::RationalNumber>; template class SparsePcaaParetoQuery, storm::RationalNumber>; template class SparsePcaaParetoQuery, storm::RationalNumber>; template class SparsePcaaParetoQuery, storm::RationalNumber>; #endif } } }