#include "src/solver/SymbolicGameSolver.h" #include "src/storage/dd/Bdd.h" #include "src/storage/dd/Add.h" #include "src/settings/SettingsManager.h" #include "src/settings/modules/NativeEquationSolverSettings.h" namespace storm { namespace solver { template SymbolicGameSolver::SymbolicGameSolver(storm::dd::Add const& gameMatrix, storm::dd::Bdd const& allRows, std::set const& rowMetaVariables, std::set const& columnMetaVariables, std::vector> const& rowColumnMetaVariablePairs, std::set const& player1Variables, std::set const& player2Variables) : gameMatrix(gameMatrix), allRows(allRows), rowMetaVariables(rowMetaVariables), columnMetaVariables(columnMetaVariables), rowColumnMetaVariablePairs(rowColumnMetaVariablePairs), player1Variables(player1Variables), player2Variables(player2Variables) { // Intentionally left empty. } template SymbolicGameSolver::SymbolicGameSolver(storm::dd::Add const& gameMatrix, storm::dd::Bdd const& allRows, std::set const& rowMetaVariables, std::set const& columnMetaVariables, std::vector> const& rowColumnMetaVariablePairs, std::set const& player1Variables, std::set const& player2Variables, double precision, uint_fast64_t maximalNumberOfIterations, bool relative) : AbstractGameSolver(precision, maximalNumberOfIterations, relative), gameMatrix(gameMatrix), allRows(allRows), rowMetaVariables(rowMetaVariables), columnMetaVariables(columnMetaVariables), rowColumnMetaVariablePairs(rowColumnMetaVariablePairs), player1Variables(player1Variables), player2Variables(player2Variables) { // Intentionally left empty. } template storm::dd::Add SymbolicGameSolver::solveGame(OptimizationDirection player1Goal, OptimizationDirection player2Goal, storm::dd::Add const& x, storm::dd::Add const& b) const { // Set up the environment. storm::dd::Add xCopy = x; uint_fast64_t iterations = 0; bool converged = false; do { // Compute tmp = A * x + b storm::dd::Add xCopyAsColumn = xCopy.swapVariables(this->rowColumnMetaVariablePairs); storm::dd::Add tmp = this->gameMatrix.multiplyMatrix(xCopyAsColumn, this->columnMetaVariables); tmp += b; // Now abstract from player 2 and player 1 variables. switch (player2Goal) { case OptimizationDirection::Minimize: tmp = tmp.minAbstract(this->player2Variables); break; case OptimizationDirection::Maximize: tmp = tmp.maxAbstract(this->player2Variables); break; } switch (player1Goal) { case OptimizationDirection::Minimize: tmp = tmp.minAbstract(this->player1Variables); break; case OptimizationDirection::Maximize: tmp = tmp.maxAbstract(this->player1Variables); break; } // Now check if the process already converged within our precision. converged = xCopy.equalModuloPrecision(tmp, precision, relative); // If the method did not converge yet, we prepare the x vector for the next iteration. if (!converged) { xCopy = tmp; } ++iterations; } while (!converged && iterations < maximalNumberOfIterations); return xCopy; } template class SymbolicGameSolver; template class SymbolicGameSolver; } }