Browse Source
refactored the quick implementation of the recent bugfix
refactored the quick implementation of the recent bugfix
Former-commit-id: 5c0d1fa3b9
main
15 changed files with 415 additions and 117 deletions
-
40src/modelchecker/region/ApproximationModel.cpp
-
1src/modelchecker/region/ApproximationModel.h
-
15src/modelchecker/region/SamplingModel.cpp
-
1src/modelchecker/region/SamplingModel.h
-
49src/solver/GameSolver.cpp
-
12src/solver/GameSolver.h
-
32src/solver/GmmxxMinMaxLinearEquationSolver.cpp
-
2src/solver/GmmxxMinMaxLinearEquationSolver.h
-
6src/solver/MinMaxLinearEquationSolver.h
-
18src/solver/NativeMinMaxLinearEquationSolver.cpp
-
2src/solver/NativeMinMaxLinearEquationSolver.h
-
2src/solver/TopologicalMinMaxLinearEquationSolver.cpp
-
2src/solver/TopologicalMinMaxLinearEquationSolver.h
-
190src/utility/policyguessing.cpp
-
154src/utility/policyguessing.h
@ -0,0 +1,190 @@ |
|||||
|
/*
|
||||
|
* File: Regions.cpp |
||||
|
* Author: Tim Quatmann |
||||
|
* |
||||
|
* Created on November 16, 2015, |
||||
|
*/ |
||||
|
#include <stdint.h>
|
||||
|
|
||||
|
#include "src/utility/policyguessing.h"
|
||||
|
|
||||
|
#include "src/storage/SparseMatrix.h"
|
||||
|
#include "src/utility/macros.h"
|
||||
|
#include "src/utility/solver.h"
|
||||
|
#include "src/solver/LinearEquationSolver.h"
|
||||
|
#include "src/solver/GameSolver.h"
|
||||
|
#include "graph.h"
|
||||
|
|
||||
|
namespace storm { |
||||
|
namespace utility{ |
||||
|
namespace policyguessing { |
||||
|
|
||||
|
template <typename ValueType> |
||||
|
void solveGame( storm::solver::GameSolver<ValueType>& solver, |
||||
|
std::vector<ValueType>& x, |
||||
|
std::vector<ValueType> const& b, |
||||
|
OptimizationDirection player1Goal, |
||||
|
OptimizationDirection player2Goal, |
||||
|
std::vector<storm::storage::sparse::state_type>& player1Policy, |
||||
|
std::vector<storm::storage::sparse::state_type>& player2Policy, |
||||
|
storm::storage::BitVector const& targetChoices, |
||||
|
ValueType const& prob0Value |
||||
|
){ |
||||
|
|
||||
|
solveInducedEquationSystem(solver, x, b, player1Policy, player2Policy, targetChoices, prob0Value); |
||||
|
solver.setPolicyTracking(); |
||||
|
solver.solveGame(player1Goal, player2Goal, x, b); |
||||
|
player1Policy = solver.getPlayer1Policy(); |
||||
|
player2Policy = solver.getPlayer2Policy(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
template <typename ValueType> |
||||
|
void solveInducedEquationSystem(storm::solver::GameSolver<ValueType> const& solver, |
||||
|
std::vector<ValueType>& x, |
||||
|
std::vector<ValueType> const& b, |
||||
|
std::vector<storm::storage::sparse::state_type> const& player1Policy, |
||||
|
std::vector<storm::storage::sparse::state_type> const& player2Policy, |
||||
|
storm::storage::BitVector const& targetChoices, |
||||
|
ValueType const& prob0Value){ |
||||
|
uint_fast64_t numberOfPlayer1States = x.size(); |
||||
|
|
||||
|
//Get the rows of the player2matrix that are selected by the policies
|
||||
|
//Note that rows can be selected more then once and in an arbitrary order.
|
||||
|
std::vector<storm::storage::sparse::state_type> selectedRows(numberOfPlayer1States); |
||||
|
for (uint_fast64_t pl1State = 0; pl1State < numberOfPlayer1States; ++pl1State){ |
||||
|
auto const& pl1Row = solver.getPlayer1Matrix().getRow(solver.getPlayer1Matrix().getRowGroupIndices()[pl1State] + player1Policy[pl1State]); |
||||
|
STORM_LOG_ASSERT(pl1Row.getNumberOfEntries()==1, ""); |
||||
|
uint_fast64_t pl2State = pl1Row.begin()->getColumn(); |
||||
|
selectedRows[pl1State] = solver.getPlayer2Matrix().getRowGroupIndices()[pl2State] + player2Policy[pl2State]; |
||||
|
} |
||||
|
|
||||
|
//Get the matrix A, vector b, and the targetStates induced by this selection
|
||||
|
storm::storage::SparseMatrix<ValueType> inducedA = solver.getPlayer2Matrix().selectRowsFromRowIndexSequence(selectedRows, false); |
||||
|
std::vector<ValueType> inducedB(numberOfPlayer1States); |
||||
|
storm::utility::vector::selectVectorValues<ValueType>(inducedB, selectedRows, b); |
||||
|
storm::storage::BitVector inducedTarget(numberOfPlayer1States, false); |
||||
|
for (uint_fast64_t pl1State = 0; pl1State < numberOfPlayer1States; ++pl1State){ |
||||
|
if(targetChoices.get(selectedRows[pl1State])){ |
||||
|
inducedTarget.set(pl1State); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
//Find the states from which no target state is reachable.
|
||||
|
//Note that depending on the policies, qualitative properties might have changed which makes this step necessary.
|
||||
|
storm::storage::BitVector probGreater0States = storm::utility::graph::performProbGreater0(inducedA.transpose(), storm::storage::BitVector(numberOfPlayer1States, true), inducedTarget); |
||||
|
|
||||
|
//Get the final A,x, and b and invoke linear equation solver
|
||||
|
storm::storage::SparseMatrix<ValueType> subA = inducedA.getSubmatrix(true, probGreater0States, probGreater0States, true); |
||||
|
subA.convertToEquationSystem(); |
||||
|
std::vector<ValueType> subX(probGreater0States.getNumberOfSetBits()); |
||||
|
storm::utility::vector::selectVectorValues(subX, probGreater0States, x); |
||||
|
std::vector<ValueType> subB(probGreater0States.getNumberOfSetBits()); |
||||
|
storm::utility::vector::selectVectorValues(subB, probGreater0States, inducedB); |
||||
|
std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> linEqSysSolver = storm::utility::solver::LinearEquationSolverFactory<ValueType>().create(subA); |
||||
|
linEqSysSolver->solveEquationSystem(subX, subB); |
||||
|
|
||||
|
//fill in the result
|
||||
|
storm::utility::vector::setVectorValues(x, probGreater0States, subX); |
||||
|
storm::utility::vector::setVectorValues(x, (~probGreater0States), prob0Value); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
template <typename ValueType> |
||||
|
void solveMinMaxLinearEquationSystem( storm::solver::MinMaxLinearEquationSolver<ValueType>& solver, |
||||
|
std::vector<ValueType>& x, |
||||
|
std::vector<ValueType> const& b, |
||||
|
OptimizationDirection goal, |
||||
|
std::vector<storm::storage::sparse::state_type>& policy, |
||||
|
storm::storage::BitVector const& targetChoices, |
||||
|
ValueType const& prob0Value |
||||
|
){ |
||||
|
|
||||
|
solveInducedEquationSystem(solver, x, b, policy, targetChoices, prob0Value); |
||||
|
solver.setPolicyTracking(); |
||||
|
solver.solveEquationSystem(goal, x, b); |
||||
|
policy = solver.getPolicy(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
template <typename ValueType> |
||||
|
void solveInducedEquationSystem(storm::solver::MinMaxLinearEquationSolver<ValueType> const& solver, |
||||
|
std::vector<ValueType>& x, |
||||
|
std::vector<ValueType> const& b, |
||||
|
std::vector<storm::storage::sparse::state_type> const& policy, |
||||
|
storm::storage::BitVector const& targetChoices, |
||||
|
ValueType const& prob0Value |
||||
|
){ |
||||
|
uint_fast64_t numberOfStates = x.size(); |
||||
|
|
||||
|
//Get the matrix A, vector b, and the targetStates induced by the policy
|
||||
|
storm::storage::SparseMatrix<ValueType> inducedA = solver.getMatrix().selectRowsFromRowGroups(policy, false); |
||||
|
std::vector<ValueType> inducedB(numberOfStates); |
||||
|
storm::utility::vector::selectVectorValues<ValueType>(inducedB, policy, solver.getMatrix().getRowGroupIndices(), b); |
||||
|
storm::storage::BitVector inducedTarget(numberOfStates, false); |
||||
|
for (uint_fast64_t state = 0; state < numberOfStates; ++state){ |
||||
|
if(targetChoices.get(solver.getMatrix().getRowGroupIndices()[state] + policy[state])){ |
||||
|
inducedTarget.set(state); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
//Find the states from which no target state is reachable.
|
||||
|
//Note that depending on the policies, qualitative properties might have changed which makes this step necessary.
|
||||
|
storm::storage::BitVector probGreater0States = storm::utility::graph::performProbGreater0(inducedA.transpose(), storm::storage::BitVector(numberOfStates, true), inducedTarget); |
||||
|
|
||||
|
//Get the final A,x, and b and invoke linear equation solver
|
||||
|
storm::storage::SparseMatrix<ValueType> subA = inducedA.getSubmatrix(true, probGreater0States, probGreater0States, true); |
||||
|
subA.convertToEquationSystem(); |
||||
|
std::vector<ValueType> subX(probGreater0States.getNumberOfSetBits()); |
||||
|
storm::utility::vector::selectVectorValues(subX, probGreater0States, x); |
||||
|
std::vector<ValueType> subB(probGreater0States.getNumberOfSetBits()); |
||||
|
storm::utility::vector::selectVectorValues(subB, probGreater0States, inducedB); |
||||
|
std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> linEqSysSolver = storm::utility::solver::LinearEquationSolverFactory<ValueType>().create(subA); |
||||
|
linEqSysSolver->solveEquationSystem(subX, subB); |
||||
|
|
||||
|
//fill in the result
|
||||
|
storm::utility::vector::setVectorValues(x, probGreater0States, subX); |
||||
|
storm::utility::vector::setVectorValues(x, (~probGreater0States), prob0Value); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
template void solveGame<double>( storm::solver::GameSolver<double>& solver, |
||||
|
std::vector<double>& x, |
||||
|
std::vector<double> const& b, |
||||
|
OptimizationDirection player1Goal, |
||||
|
OptimizationDirection player2Goal, |
||||
|
std::vector<storm::storage::sparse::state_type>& player1Policy, |
||||
|
std::vector<storm::storage::sparse::state_type>& player2Policy, |
||||
|
storm::storage::BitVector const& targetChoices, |
||||
|
double const& prob0Value |
||||
|
); |
||||
|
|
||||
|
template void solveInducedEquationSystem<double>(storm::solver::GameSolver<double> const& solver, |
||||
|
std::vector<double>& x, |
||||
|
std::vector<double> const& b, |
||||
|
std::vector<storm::storage::sparse::state_type> const& player1Policy, |
||||
|
std::vector<storm::storage::sparse::state_type> const& player2Policy, |
||||
|
storm::storage::BitVector const& targetChoices, |
||||
|
double const& prob0Value |
||||
|
); |
||||
|
|
||||
|
template void solveMinMaxLinearEquationSystem<double>( storm::solver::MinMaxLinearEquationSolver<double>& solver, |
||||
|
std::vector<double>& x, |
||||
|
std::vector<double> const& b, |
||||
|
OptimizationDirection goal, |
||||
|
std::vector<storm::storage::sparse::state_type>& policy, |
||||
|
storm::storage::BitVector const& targetChoices, |
||||
|
double const& prob0Value |
||||
|
); |
||||
|
|
||||
|
template void solveInducedEquationSystem<double>(storm::solver::MinMaxLinearEquationSolver<double> const& solver, |
||||
|
std::vector<double>& x, |
||||
|
std::vector<double> const& b, |
||||
|
std::vector<storm::storage::sparse::state_type> const& policy, |
||||
|
storm::storage::BitVector const& targetChoices, |
||||
|
double const& prob0Value |
||||
|
); |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,154 @@ |
|||||
|
/* |
||||
|
* File: Regions.h |
||||
|
* Author: Tim Quatmann |
||||
|
* |
||||
|
* Created on November 16, 2015, |
||||
|
* |
||||
|
* This file provides functions to apply a solver on a nondeterministic model or a two player game. |
||||
|
* However, policies are used to compute an initial guess which will (hopefully) speed up the value iteration techniques. |
||||
|
*/ |
||||
|
|
||||
|
|
||||
|
#ifndef STORM_UTILITY_POLICYGUESSING_H |
||||
|
#define STORM_UTILITY_POLICYGUESSING_H |
||||
|
|
||||
|
#include "src/solver/GameSolver.h" |
||||
|
#include "src/solver/MinMaxLinearEquationSolver.h" |
||||
|
#include "src/solver/OptimizationDirection.h" |
||||
|
#include "src/utility/vector.h" |
||||
|
#include "src/storage/BitVector.h" |
||||
|
#include "src/storage/sparse/StateType.h" |
||||
|
|
||||
|
namespace storm { |
||||
|
namespace utility{ |
||||
|
namespace policyguessing { |
||||
|
|
||||
|
/*! |
||||
|
* invokes the given game solver. |
||||
|
* |
||||
|
* The given policies for player 1 and player 2 will serve as initial guess. |
||||
|
* A linear equation system defined by the induced Matrix A and vector b is solved before |
||||
|
* solving the actual game. |
||||
|
* Note that, depending on the policies, the qualitative properties of the graph defined by A |
||||
|
* might be different to the original graph of the game. |
||||
|
* To ensure a unique solution, we need to filter out the "prob0"-states. |
||||
|
* To identify these states and set the result for them correctly, it is necessary to know whether rewards or probabilities are to be computed |
||||
|
* |
||||
|
* @param solver the solver to be invoked |
||||
|
* @param player1Goal Sets whether player 1 wants to minimize or maximize. |
||||
|
* @param player2Goal Sets whether player 2 wants to minimize or maximize. |
||||
|
* @param x The initial guess of the solution. |
||||
|
* @param b The vector to add after matrix-vector multiplication. |
||||
|
* @param player1Policy A policy that selects rows in every rowgroup of player1. This will be used as an initial guess |
||||
|
* @param player2Policy A policy that selects rows in every rowgroup of player2. This will be used as an initial guess |
||||
|
* @param targetChoices marks the choices in the player2 matrix that have a positive probability to lead to a target state |
||||
|
* @param prob0Value the value that, after policy instantiation, is assigned to the states that have probability zero to reach a target |
||||
|
* @return The solution vector in the form of the vector x as well as the two policies. |
||||
|
*/ |
||||
|
template<typename ValueType> |
||||
|
void solveGame( storm::solver::GameSolver<ValueType>& solver, |
||||
|
std::vector<ValueType>& x, |
||||
|
std::vector<ValueType> const& b, |
||||
|
OptimizationDirection player1Goal, |
||||
|
OptimizationDirection player2Goal, |
||||
|
std::vector<storm::storage::sparse::state_type>& player1Policy, |
||||
|
std::vector<storm::storage::sparse::state_type>& player2Policy, |
||||
|
storm::storage::BitVector const& targetChoices, |
||||
|
ValueType const& prob0Value |
||||
|
); |
||||
|
|
||||
|
|
||||
|
/*! |
||||
|
* Solves the equation system defined by the matrix A and vector b' that result from applying |
||||
|
* the given policies to the matrices of the two players and the given b. |
||||
|
* |
||||
|
* Note that, depending on the policies, the qualitative properties of the graph defined by A |
||||
|
* might be different to the original graph of the game. |
||||
|
* To ensure a unique solution, we need to filter out the "prob0"-states. |
||||
|
* (Notice that new "prob1"-states do not harm as actual target states are always excluded, independent of the choice) |
||||
|
* |
||||
|
* @param solver the solver that contains the two player matrices |
||||
|
* @param x The initial guess of the solution. |
||||
|
* @param b The vector in which to select the entries of the right hand side |
||||
|
* @param player1Policy A policy that selects rows in every rowgroup of player1. |
||||
|
* @param player2Policy A policy that selects rows in every rowgroup of player2. |
||||
|
* @param targetChoices marks the choices in the player2 matrix that have a positive probability to lead to a target state |
||||
|
* @param prob0Value the value that is assigned to the states that have probability zero to reach a target |
||||
|
* @return The solution vector in the form of the vector x. |
||||
|
*/ |
||||
|
template<typename ValueType> |
||||
|
void solveInducedEquationSystem(storm::solver::GameSolver<ValueType> const& solver, |
||||
|
std::vector<ValueType>& x, |
||||
|
std::vector<ValueType> const& b, |
||||
|
std::vector<storm::storage::sparse::state_type> const& player1Policy, |
||||
|
std::vector<storm::storage::sparse::state_type> const& player2Policy, |
||||
|
storm::storage::BitVector const& targetChoices, |
||||
|
ValueType const& prob0Value |
||||
|
); |
||||
|
|
||||
|
|
||||
|
|
||||
|
/*! |
||||
|
* invokes the given MinMaxLinearEquationSolver. |
||||
|
* |
||||
|
* The given policy will serve as an initial guess. |
||||
|
* A linear equation system defined by the induced Matrix A and vector b is solved before |
||||
|
* solving the actual MinMax equation system. |
||||
|
* Note that, depending on the policy, the qualitative properties of the graph defined by A |
||||
|
* might be different to the original graph. |
||||
|
* To ensure a unique solution, we need to filter out the "prob0"-states. |
||||
|
* To identify these states and set the result for them correctly, it is necessary to know whether rewards or probabilities are to be computed |
||||
|
* |
||||
|
|
||||
|
* @param solver the solver that contains the two player matrices |
||||
|
* @param x The initial guess of the solution. |
||||
|
* @param b The vector to add after matrix-vector multiplication. |
||||
|
* @param goal Sets whether we want to minimize or maximize. |
||||
|
* @param policy A policy that selects rows in every rowgroup. |
||||
|
* @param targetChoices marks the rows in the matrix that have a positive probability to lead to a target state |
||||
|
* @param prob0Value the value that is assigned to the states that have probability zero to reach a target |
||||
|
* @return The solution vector in the form of the vector x. |
||||
|
*/ |
||||
|
template<typename ValueType> |
||||
|
void solveMinMaxLinearEquationSystem( storm::solver::MinMaxLinearEquationSolver<ValueType>& solver, |
||||
|
std::vector<ValueType>& x, |
||||
|
std::vector<ValueType> const& b, |
||||
|
OptimizationDirection goal, |
||||
|
std::vector<storm::storage::sparse::state_type>& policy, |
||||
|
storm::storage::BitVector const& targetChoices, |
||||
|
ValueType const& prob0Value |
||||
|
); |
||||
|
|
||||
|
/*! |
||||
|
* Solves the equation system defined by the matrix A and vector b' that result from applying |
||||
|
* the given policy to the matrices of the two players and the given b. |
||||
|
* |
||||
|
* Note that, depending on the policy, the qualitative properties of the graph defined by A |
||||
|
* might be different to the original graph |
||||
|
* To ensure a unique solution, we need to filter out the "prob0"-states. |
||||
|
* (Notice that new "prob1"-states do not harm as actual target states are always excluded, independent of the choice) |
||||
|
* |
||||
|
* @param solverthe solver that contains the two player matrices |
||||
|
* @param x The initial guess of the solution. |
||||
|
* @param b The vector in which to select the entries of the right hand side |
||||
|
* @param policy A policy that selects rows in every rowgroup. |
||||
|
* @param targetChoices marks the rows in the matrix that have a positive probability to lead to a target state |
||||
|
* @param prob0Value the value that is assigned to the states that have probability zero to reach a target |
||||
|
* @return The solution vector in the form of the vector x. |
||||
|
*/ |
||||
|
template<typename ValueType> |
||||
|
void solveInducedEquationSystem(storm::solver::MinMaxLinearEquationSolver<ValueType> const& solver, |
||||
|
std::vector<ValueType>& x, |
||||
|
std::vector<ValueType> const& b, |
||||
|
std::vector<storm::storage::sparse::state_type> const& policy, |
||||
|
storm::storage::BitVector const& targetChoices, |
||||
|
ValueType const& prob0Value |
||||
|
); |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
#endif /* STORM_UTILITY_REGIONS_H */ |
||||
|
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue