Browse Source
Merge branch 'future' of https://sselab.de/lab9/private/git/storm into future
Merge branch 'future' of https://sselab.de/lab9/private/git/storm into future
Former-commit-id: ed2036c1ae
tempestpy_adaptions
sjunges
10 years ago
15 changed files with 382 additions and 90 deletions
-
21src/parser/NondeterministicSparseTransitionParser.cpp
-
22src/solver/AbstractGameSolver.cpp
-
40src/solver/AbstractGameSolver.h
-
76src/solver/GameSolver.cpp
-
62src/solver/GameSolver.h
-
32src/solver/SymbolicGameSolver.cpp
-
34src/solver/SymbolicGameSolver.h
-
32src/storage/SparseMatrix.cpp
-
1src/storage/prism/Program.cpp
-
4src/utility/ConstantsComparator.cpp
-
42src/utility/constants.cpp
-
13src/utility/solver.cpp
-
16src/utility/solver.h
-
8test/functional/solver/FullySymbolicGameSolverTest.cpp
-
69test/functional/solver/GameSolverTest.cpp
@ -0,0 +1,22 @@ |
|||
#include "src/solver/AbstractGameSolver.h"
|
|||
|
|||
#include "src/settings/SettingsManager.h"
|
|||
#include "src/settings/modules/NativeEquationSolverSettings.h"
|
|||
|
|||
namespace storm { |
|||
namespace solver { |
|||
AbstractGameSolver::AbstractGameSolver() { |
|||
// Get the settings object to customize solving.
|
|||
storm::settings::modules::NativeEquationSolverSettings const& settings = storm::settings::nativeEquationSolverSettings(); |
|||
|
|||
// Get appropriate settings.
|
|||
maximalNumberOfIterations = settings.getMaximalIterationCount(); |
|||
precision = settings.getPrecision(); |
|||
relative = settings.getConvergenceCriterion() == storm::settings::modules::NativeEquationSolverSettings::ConvergenceCriterion::Relative; |
|||
} |
|||
|
|||
AbstractGameSolver::AbstractGameSolver(double precision, uint_fast64_t maximalNumberOfIterations, bool relative) : precision(precision), maximalNumberOfIterations(maximalNumberOfIterations), relative(relative) { |
|||
// Intentionally left empty.
|
|||
} |
|||
} |
|||
} |
@ -0,0 +1,40 @@ |
|||
#ifndef STORM_SOLVER_ABSTRACTGAMESOLVER_H_ |
|||
#define STORM_SOLVER_ABSTRACTGAMESOLVER_H_ |
|||
|
|||
#include <cstdint> |
|||
|
|||
namespace storm { |
|||
namespace solver { |
|||
/*! |
|||
* The abstract base class for the game solvers. |
|||
*/ |
|||
class AbstractGameSolver { |
|||
public: |
|||
/*! |
|||
* Creates a game solver with the default parameters. |
|||
*/ |
|||
AbstractGameSolver(); |
|||
|
|||
/*! |
|||
* Creates a game solver with the given parameters. |
|||
* |
|||
* @param precision The precision to achieve. |
|||
* @param maximalNumberOfIterations The maximal number of iterations to perform. |
|||
* @param relative A flag indicating whether a relative or an absolute stopping criterion is to be used. |
|||
*/ |
|||
AbstractGameSolver(double precision, uint_fast64_t maximalNumberOfIterations, bool relative); |
|||
|
|||
protected: |
|||
// The precision to achieve. |
|||
double precision; |
|||
|
|||
// The maximal number of iterations to perform. |
|||
uint_fast64_t maximalNumberOfIterations; |
|||
|
|||
// A flag indicating whether a relative or an absolute stopping criterion is to be used. |
|||
bool relative; |
|||
}; |
|||
} |
|||
} |
|||
|
|||
#endif /* STORM_SOLVER_ABSTRACTGAMESOLVER_H_ */ |
@ -0,0 +1,76 @@ |
|||
#include "src/solver/GameSolver.h"
|
|||
|
|||
#include "src/storage/SparseMatrix.h"
|
|||
|
|||
#include "src/utility/vector.h"
|
|||
|
|||
namespace storm { |
|||
namespace solver { |
|||
template <typename ValueType> |
|||
GameSolver<ValueType>::GameSolver(storm::storage::SparseMatrix<storm::storage::sparse::state_type> const& player1Matrix, storm::storage::SparseMatrix<ValueType> const& player2Matrix) : AbstractGameSolver(), player1Matrix(player1Matrix), player2Matrix(player2Matrix) { |
|||
// Intentionally left empty.
|
|||
} |
|||
|
|||
template <typename ValueType> |
|||
GameSolver<ValueType>::GameSolver(storm::storage::SparseMatrix<storm::storage::sparse::state_type> const& player1Matrix, storm::storage::SparseMatrix<ValueType> const& player2Matrix, double precision, uint_fast64_t maximalNumberOfIterations, bool relative) : AbstractGameSolver(precision, maximalNumberOfIterations, relative), player1Matrix(player1Matrix), player2Matrix(player2Matrix) { |
|||
// Intentionally left empty.
|
|||
} |
|||
|
|||
template <typename ValueType> |
|||
void GameSolver<ValueType>::solveGame(OptimizationDirection player1Goal, OptimizationDirection player2Goal, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { |
|||
// Set up the environment for value iteration.
|
|||
uint_fast64_t numberOfPlayer1States = x.size(); |
|||
|
|||
bool converged = false; |
|||
std::vector<ValueType> tmpResult(numberOfPlayer1States); |
|||
std::vector<ValueType> nondetResult(player2Matrix.getRowCount()); |
|||
std::vector<ValueType> player2Result(player2Matrix.getRowGroupCount()); |
|||
|
|||
// Now perform the actual value iteration.
|
|||
uint_fast64_t iterations = 0; |
|||
do { |
|||
player2Matrix.multiplyWithVector(x, nondetResult); |
|||
storm::utility::vector::addVectors(b, nondetResult, nondetResult); |
|||
|
|||
if (player2Goal == OptimizationDirection::Minimize) { |
|||
storm::utility::vector::reduceVectorMin(nondetResult, player2Result, player2Matrix.getRowGroupIndices()); |
|||
} else { |
|||
storm::utility::vector::reduceVectorMax(nondetResult, player2Result, player2Matrix.getRowGroupIndices()); |
|||
} |
|||
|
|||
for (uint_fast64_t pl1State = 0; pl1State < numberOfPlayer1States; ++pl1State) { |
|||
storm::storage::SparseMatrix<storm::storage::sparse::state_type>::const_rows relevantRows = player1Matrix.getRowGroup(pl1State); |
|||
if (relevantRows.getNumberOfEntries() > 0) { |
|||
storm::storage::SparseMatrix<storm::storage::sparse::state_type>::const_iterator it = relevantRows.begin(); |
|||
storm::storage::SparseMatrix<storm::storage::sparse::state_type>::const_iterator ite = relevantRows.end(); |
|||
|
|||
// Set the first value.
|
|||
tmpResult[pl1State] = player2Result[it->getColumn()]; |
|||
++it; |
|||
|
|||
// Now iterate through the different values and pick the extremal one.
|
|||
if (player1Goal == OptimizationDirection::Minimize) { |
|||
for (; it != ite; ++it) { |
|||
tmpResult[pl1State] = std::min(tmpResult[pl1State], player2Result[it->getColumn()]); |
|||
} |
|||
} else { |
|||
for (; it != ite; ++it) { |
|||
tmpResult[pl1State] = std::max(tmpResult[pl1State], player2Result[it->getColumn()]); |
|||
} |
|||
} |
|||
} else { |
|||
tmpResult[pl1State] = storm::utility::zero<ValueType>(); |
|||
} |
|||
} |
|||
|
|||
// Check if the process converged and set up the new iteration in case we are not done.
|
|||
converged = storm::utility::vector::equalModuloPrecision(x, tmpResult, precision, relative); |
|||
std::swap(x, tmpResult); |
|||
|
|||
++iterations; |
|||
} while (!converged && iterations < maximalNumberOfIterations); |
|||
} |
|||
|
|||
template class GameSolver<double>; |
|||
} |
|||
} |
@ -0,0 +1,62 @@ |
|||
#ifndef STORM_SOLVER_GAMESOLVER_H_ |
|||
#define STORM_SOLVER_GAMESOLVER_H_ |
|||
|
|||
#include <vector> |
|||
|
|||
#include "src/solver/AbstractGameSolver.h" |
|||
#include "src/solver/OptimizationDirection.h" |
|||
|
|||
#include "src/storage/sparse/StateType.h" |
|||
|
|||
namespace storm { |
|||
namespace storage { |
|||
template<typename ValueType> |
|||
class SparseMatrix; |
|||
} |
|||
|
|||
namespace solver { |
|||
template<typename ValueType> |
|||
class GameSolver : public AbstractGameSolver { |
|||
public: |
|||
/* |
|||
* Constructs a game solver with the given player 1 and player 2 matrices. |
|||
* |
|||
* @param player1Matrix The matrix defining the choices of player 1. |
|||
* @param player2Matrix The matrix defining the choices of player 2. |
|||
*/ |
|||
GameSolver(storm::storage::SparseMatrix<storm::storage::sparse::state_type> const& player1Matrix, storm::storage::SparseMatrix<ValueType> const& player2Matrix); |
|||
|
|||
/* |
|||
* Constructs a game solver with the given player 1 and player 2 matrices and options. |
|||
* |
|||
* @param player1Matrix The matrix defining the choices of player 1. |
|||
* @param player2Matrix The matrix defining the choices of player 2. |
|||
* @param precision The precision that is used to detect convergence. |
|||
* @param maximalNumberOfIterations The maximal number of iterations. |
|||
* @param relative Sets whether or not to detect convergence with a relative or absolute criterion. |
|||
*/ |
|||
GameSolver(storm::storage::SparseMatrix<storm::storage::sparse::state_type> const& player1Matrix, storm::storage::SparseMatrix<ValueType> const& player2Matrix, double precision, uint_fast64_t maximalNumberOfIterations, bool relative); |
|||
|
|||
/*! |
|||
* Solves the equation system defined by the game matrix. Note that the game matrix has to be given upon |
|||
* construction time of the solver object. |
|||
* |
|||
* @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. |
|||
* @return The solution vector in the for of the vector x. |
|||
*/ |
|||
virtual void solveGame(OptimizationDirection player1Goal, OptimizationDirection player2Goal, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; |
|||
|
|||
private: |
|||
// The matrix defining the choices of player 1. |
|||
storm::storage::SparseMatrix<storm::storage::sparse::state_type> const& player1Matrix; |
|||
|
|||
// The matrix defining the choices of player 2. |
|||
storm::storage::SparseMatrix<ValueType> const& player2Matrix; |
|||
}; |
|||
} |
|||
} |
|||
|
|||
#endif /* STORM_SOLVER_GAMESOLVER_H_ */ |
@ -0,0 +1,69 @@ |
|||
#include "gtest/gtest.h"
|
|||
#include "storm-config.h"
|
|||
|
|||
#include "src/storage/SparseMatrix.h"
|
|||
|
|||
#include "src/utility/solver.h"
|
|||
#include "src/settings/SettingsManager.h"
|
|||
|
|||
#include "src/solver/GameSolver.h"
|
|||
#include "src/settings/modules/NativeEquationSolverSettings.h"
|
|||
|
|||
TEST(GameSolverTest, Solve) { |
|||
// Construct simple game. Start with player 2 matrix.
|
|||
storm::storage::SparseMatrixBuilder<double> player2MatrixBuilder(0, 0, 0, false, true); |
|||
player2MatrixBuilder.newRowGroup(0); |
|||
player2MatrixBuilder.addNextValue(0, 0, 0.4); |
|||
player2MatrixBuilder.addNextValue(0, 1, 0.6); |
|||
player2MatrixBuilder.addNextValue(1, 1, 0.2); |
|||
player2MatrixBuilder.addNextValue(1, 2, 0.8); |
|||
player2MatrixBuilder.newRowGroup(2); |
|||
player2MatrixBuilder.addNextValue(2, 2, 0.5); |
|||
player2MatrixBuilder.addNextValue(2, 3, 0.5); |
|||
player2MatrixBuilder.addNextValue(3, 0, 1); |
|||
player2MatrixBuilder.newRowGroup(4); |
|||
player2MatrixBuilder.newRowGroup(5); |
|||
player2MatrixBuilder.newRowGroup(6); |
|||
storm::storage::SparseMatrix<double> player2Matrix = player2MatrixBuilder.build(); |
|||
|
|||
// Now build player 1 matrix.
|
|||
storm::storage::SparseMatrixBuilder<storm::storage::sparse::state_type> player1MatrixBuilder(0, 0, 0, false, true); |
|||
player1MatrixBuilder.newRowGroup(0); |
|||
player1MatrixBuilder.addNextValue(0, 0, 1); |
|||
player1MatrixBuilder.addNextValue(1, 1, 1); |
|||
player1MatrixBuilder.newRowGroup(2); |
|||
player1MatrixBuilder.addNextValue(2, 2, 1); |
|||
player1MatrixBuilder.newRowGroup(3); |
|||
player1MatrixBuilder.addNextValue(3, 3, 1); |
|||
player1MatrixBuilder.newRowGroup(4); |
|||
player1MatrixBuilder.addNextValue(4, 4, 1); |
|||
storm::storage::SparseMatrix<storm::storage::sparse::state_type> player1Matrix = player1MatrixBuilder.build(); |
|||
|
|||
std::unique_ptr<storm::utility::solver::GameSolverFactory<double>> solverFactory(new storm::utility::solver::GameSolverFactory<double>()); |
|||
std::unique_ptr<storm::solver::GameSolver<double>> solver = solverFactory->create(player1Matrix, player2Matrix); |
|||
|
|||
// Create solution and target state vector.
|
|||
std::vector<double> result(4); |
|||
std::vector<double> b(7); |
|||
b[4] = 1; |
|||
b[6] = 1; |
|||
|
|||
// Now solve the game with different strategies for the players.
|
|||
solver->solveGame(storm::OptimizationDirection::Minimize, storm::OptimizationDirection::Minimize, result, b); |
|||
EXPECT_NEAR(0, result[0], storm::settings::nativeEquationSolverSettings().getPrecision()); |
|||
|
|||
result = std::vector<double>(4); |
|||
|
|||
solver->solveGame(storm::OptimizationDirection::Minimize, storm::OptimizationDirection::Maximize, result, b); |
|||
EXPECT_NEAR(0.5, result[0], storm::settings::nativeEquationSolverSettings().getPrecision()); |
|||
|
|||
result = std::vector<double>(4); |
|||
|
|||
solver->solveGame(storm::OptimizationDirection::Maximize, storm::OptimizationDirection::Minimize, result, b); |
|||
EXPECT_NEAR(0.2, result[0], storm::settings::nativeEquationSolverSettings().getPrecision()); |
|||
|
|||
result = std::vector<double>(4); |
|||
|
|||
solver->solveGame(storm::OptimizationDirection::Maximize, storm::OptimizationDirection::Maximize, result, b); |
|||
EXPECT_NEAR(0.99999892625817599, result[0], storm::settings::nativeEquationSolverSettings().getPrecision()); |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue