23template<
typename ValueType>
27 : linearEquationSolverFactory(
std::move(linearEquationSolverFactory)),
28 localPlayer1Grouping(nullptr),
29 localPlayer1Matrix(nullptr),
30 localPlayer2Matrix(nullptr),
31 player1Grouping(nullptr),
32 player1Matrix(&player1Matrix),
33 player2Matrix(player2Matrix),
34 linearEquationSolverIsExact(false) {
39template<
typename ValueType>
43 : linearEquationSolverFactory(
std::move(linearEquationSolverFactory)),
44 localPlayer1Grouping(nullptr),
45 localPlayer1Matrix(
std::make_unique<
storm::storage::SparseMatrix<
storm::storage::sparse::state_type>>(
std::move(player1Matrix))),
46 localPlayer2Matrix(
std::make_unique<
storm::storage::SparseMatrix<ValueType>>(
std::move(player2Matrix))),
47 player1Grouping(nullptr),
48 player1Matrix(localPlayer1Matrix.get()),
49 player2Matrix(*localPlayer2Matrix),
50 linearEquationSolverIsExact(false) {
55template<
typename ValueType>
58 : linearEquationSolverFactory(
std::move(linearEquationSolverFactory)),
59 localPlayer1Grouping(nullptr),
60 localPlayer1Matrix(nullptr),
61 localPlayer2Matrix(nullptr),
62 player1Grouping(&player1Grouping),
63 player1Matrix(nullptr),
64 player2Matrix(player2Matrix),
65 linearEquationSolverIsExact(false) {
70template<
typename ValueType>
73 : linearEquationSolverFactory(
std::move(linearEquationSolverFactory)),
74 localPlayer1Grouping(
std::make_unique<
std::vector<uint64_t>>(
std::move(player1Grouping))),
75 localPlayer1Matrix(nullptr),
76 localPlayer2Matrix(
std::make_unique<
storm::storage::SparseMatrix<ValueType>>(
std::move(player2Matrix))),
77 player1Grouping(localPlayer1Grouping.get()),
78 player1Matrix(nullptr),
79 player2Matrix(*localPlayer2Matrix),
80 linearEquationSolverIsExact(false) {
85template<
typename ValueType>
88 if (isExactMode && method != GameMethod::PolicyIteration) {
90 method = GameMethod::PolicyIteration;
91 STORM_LOG_INFO(
"Changing game method to policy-iteration to guarantee exact results. If you want to override this, specify another method.");
93 STORM_LOG_WARN(
"The selected game method does not guarantee exact results.");
97 method = GameMethod::PolicyIteration;
98 STORM_LOG_INFO(
"Changing game method to policy-iteration to guarantee sound results. If you want to override this, specify another method.");
100 STORM_LOG_WARN(
"The selected game method does not guarantee sound results.");
106template<
typename ValueType>
108 std::vector<ValueType>& x, std::vector<ValueType>
const& b, std::vector<uint64_t>* player1Choices,
109 std::vector<uint64_t>* player2Choices)
const {
110 auto method = getMethod(env, std::is_same<ValueType, storm::RationalNumber>::value || env.
solver().
isForceExact());
111 STORM_LOG_INFO(
"Solving stochastic two player game over " << x.size() <<
" states using " <<
toString(method) <<
".");
113 case GameMethod::ValueIteration:
114 return solveGameValueIteration(env, player1Dir, player2Dir, x, b, player1Choices, player2Choices);
115 case GameMethod::PolicyIteration:
116 return solveGamePolicyIteration(env, player1Dir, player2Dir, x, b, player1Choices, player2Choices);
118 STORM_LOG_THROW(
false, storm::exceptions::InvalidEnvironmentException,
"This solver does not implement the selected solution method");
123template<
typename ValueType>
125 std::vector<ValueType>& x, std::vector<ValueType>
const& b,
126 std::vector<uint64_t>* providedPlayer1Choices,
127 std::vector<uint64_t>* providedPlayer2Choices)
const {
129 std::vector<storm::storage::sparse::state_type>* player1Choices;
130 std::unique_ptr<std::vector<storm::storage::sparse::state_type>> localPlayer1Choices;
131 std::vector<storm::storage::sparse::state_type>* player2Choices;
132 std::unique_ptr<std::vector<storm::storage::sparse::state_type>> localPlayer2Choices;
134 if (providedPlayer1Choices && providedPlayer2Choices) {
135 player1Choices = providedPlayer1Choices;
136 player2Choices = providedPlayer2Choices;
138 localPlayer1Choices = std::make_unique<std::vector<uint64_t>>();
139 player1Choices = localPlayer1Choices.get();
140 localPlayer2Choices = std::make_unique<std::vector<uint64_t>>();
141 player2Choices = localPlayer2Choices.get();
144 if (this->hasSchedulerHints()) {
145 *player1Choices = this->player1ChoicesHint.get();
146 }
else if (this->player1RepresentedByMatrix()) {
148 *player1Choices = std::vector<storm::storage::sparse::state_type>(this->getPlayer1Matrix().getRowGroupCount(), 0);
151 player1Choices->resize(player1Choices->size() - 1);
153 if (this->hasSchedulerHints()) {
154 *player2Choices = this->player2ChoicesHint.get();
155 }
else if (!(providedPlayer1Choices && providedPlayer2Choices)) {
156 player2Choices->resize(this->player2Matrix.getRowGroupCount());
159 if (!auxiliaryP2RowGroupVector) {
160 auxiliaryP2RowGroupVector = std::make_unique<std::vector<ValueType>>(this->player2Matrix.getRowGroupCount());
162 if (!auxiliaryP1RowGroupVector) {
163 auxiliaryP1RowGroupVector = std::make_unique<std::vector<ValueType>>(this->player1RepresentedByMatrix() ? this->player1Matrix->getRowGroupCount()
164 : this->player1Grouping->size() - 1);
166 std::vector<ValueType>& subB = *auxiliaryP1RowGroupVector;
171 std::unique_ptr<storm::Environment> environmentOfSolverStorage;
174 bool changePrecision = precOfSolver.first && precOfSolver.first.get() > env.
solver().
game().
getPrecision();
176 if (changePrecision || changeRelative) {
177 environmentOfSolverStorage = std::make_unique<storm::Environment>(env);
178 boost::optional<storm::RationalNumber> newPrecision;
179 boost::optional<bool> newRelative;
180 if (changePrecision) {
183 if (changeRelative) {
186 environmentOfSolverStorage->solver().setLinearEquationSolverPrecision(newPrecision, newRelative);
189 storm::Environment const& environmentOfSolver = environmentOfSolverStorage ? *environmentOfSolverStorage : env;
193 getInducedMatrixVector(x, b, *player1Choices, *player2Choices, submatrix, subB);
197 if (!this->hasUniqueSolution()) {
202 bool asEquationSystem =
false;
205 asEquationSystem =
true;
207 if (!this->hasUniqueSolution()) {
208 for (
auto state : zeroStates) {
209 for (
auto& element : submatrix.getRow(state)) {
210 if (element.getColumn() == state) {
211 element.setValue(asEquationSystem ? storm::utility::one<ValueType>() :
storm::utility::
zero<
ValueType>());
213 element.setValue(storm::utility::zero<ValueType>());
216 subB[state] = storm::utility::zero<ValueType>();
219 auto submatrixSolver = linearEquationSolverFactory->create(environmentOfSolver, std::move(submatrix));
220 if (this->lowerBound) {
221 submatrixSolver->setLowerBound(this->lowerBound.get());
223 if (this->upperBound) {
224 submatrixSolver->setUpperBound(this->upperBound.get());
226 submatrixSolver->setCachingEnabled(
true);
229 uint64_t iterations = 0;
231 submatrixSolver->solveEquations(environmentOfSolver, x, subB);
234 bool schedulerImproved =
235 extractChoices(environmentOfSolver, player1Dir, player2Dir, x, b, *auxiliaryP2RowGroupVector, *player1Choices, *player2Choices);
238 if (!schedulerImproved) {
242 getInducedMatrixVector(x, b, *player1Choices, *player2Choices, submatrix, subB);
244 if (!this->hasUniqueSolution()) {
253 if (!this->hasUniqueSolution()) {
254 for (
auto state : zeroStates) {
255 for (
auto& element : submatrix.getRow(state)) {
256 if (element.getColumn() == state) {
257 element.setValue(asEquationSystem ? storm::utility::one<ValueType>() :
storm::utility::
zero<
ValueType>());
259 element.setValue(storm::utility::zero<ValueType>());
262 subB[state] = storm::utility::zero<ValueType>();
266 submatrixSolver->setMatrix(std::move(submatrix));
274 this->reportStatus(status, iterations);
277 if (this->isTrackSchedulersSet() && !(providedPlayer1Choices && providedPlayer2Choices)) {
278 this->player1SchedulerChoices = std::move(*player1Choices);
279 this->player2SchedulerChoices = std::move(*player2Choices);
282 if (!this->isCachingEnabled()) {
289template<
typename ValueType>
291 ValueType
const& value1, ValueType
const& value2)
const {
292 if (dir == OptimizationDirection::Minimize) {
293 return comparator.
isLess(value2, value1);
295 return comparator.
isLess(value1, value2);
299template<
typename ValueType>
301 std::vector<ValueType>& x, std::vector<ValueType>
const& b, std::vector<uint64_t>* player1Choices,
302 std::vector<uint64_t>* player2Choices)
const {
303 if (!multiplierPlayer2Matrix) {
307 if (!auxiliaryP2RowGroupVector) {
308 auxiliaryP2RowGroupVector = std::make_unique<std::vector<ValueType>>(player2Matrix.getRowGroupCount());
311 if (!auxiliaryP1RowGroupVector) {
312 auxiliaryP1RowGroupVector = std::make_unique<std::vector<ValueType>>(this->getNumberOfPlayer1States());
315 ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().game().getPrecision());
316 bool relative = env.solver().game().getRelativeTerminationCriterion();
317 uint64_t maxIter = env.solver().game().getMaximalNumberOfIterations();
319 std::vector<ValueType>& reducedPlayer2Result = *auxiliaryP2RowGroupVector;
321 bool trackingSchedulersInProvidedStorage = player1Choices && player2Choices;
322 bool trackSchedulers = this->isTrackSchedulersSet() || trackingSchedulersInProvidedStorage;
323 bool trackSchedulersInValueIteration = trackSchedulers && !this->hasUniqueSolution();
324 if (this->hasSchedulerHints()) {
327 getInducedMatrixVector(x, b, this->player1ChoicesHint.get(), this->player2ChoicesHint.get(), submatrix, *auxiliaryP1RowGroupVector);
331 auto submatrixSolver = linearEquationSolverFactory->create(env, std::move(submatrix));
332 if (this->lowerBound) {
333 submatrixSolver->setLowerBound(this->lowerBound.get());
335 if (this->upperBound) {
336 submatrixSolver->setUpperBound(this->upperBound.get());
338 submatrixSolver->solveEquations(env, x, *auxiliaryP1RowGroupVector);
341 if (trackSchedulersInValueIteration && !trackingSchedulersInProvidedStorage) {
342 this->player1SchedulerChoices = this->player1ChoicesHint.get();
343 this->player2SchedulerChoices = this->player2ChoicesHint.get();
345 }
else if (trackSchedulersInValueIteration && !trackingSchedulersInProvidedStorage) {
348 this->player1SchedulerChoices = std::vector<uint_fast64_t>(this->getNumberOfPlayer1States(), 0);
349 this->player2SchedulerChoices = std::vector<uint_fast64_t>(this->getNumberOfPlayer2States(), 0);
352 std::vector<ValueType>* newX = auxiliaryP1RowGroupVector.get();
353 std::vector<ValueType>* currentX = &x;
356 uint64_t iterations = 0;
361 env, player1Dir, player2Dir, *currentX, &b, *multiplierPlayer2Matrix, reducedPlayer2Result, *newX,
362 trackSchedulersInValueIteration ? (trackingSchedulersInProvidedStorage ? player1Choices : &this->player1SchedulerChoices.get()) : nullptr,
363 trackSchedulersInValueIteration ? (trackingSchedulersInProvidedStorage ? player2Choices : &this->player2SchedulerChoices.get()) : nullptr);
366 if (storm::utility::vector::equalModuloPrecision<ValueType>(*currentX, *newX, precision, relative)) {
371 std::swap(currentX, newX);
376 this->reportStatus(status, iterations);
380 if (currentX == auxiliaryP1RowGroupVector.get()) {
381 std::swap(x, *currentX);
385 if (trackSchedulers && this->hasUniqueSolution()) {
386 if (trackingSchedulersInProvidedStorage) {
387 extractChoices(env, player1Dir, player2Dir, x, b, *auxiliaryP2RowGroupVector, *player1Choices, *player2Choices);
389 this->player1SchedulerChoices = std::vector<uint_fast64_t>(this->getNumberOfPlayer1States(), 0);
390 this->player2SchedulerChoices = std::vector<uint_fast64_t>(this->getNumberOfPlayer2States(), 0);
391 extractChoices(env, player1Dir, player2Dir, x, b, *auxiliaryP2RowGroupVector, this->player1SchedulerChoices.get(),
392 this->player2SchedulerChoices.get());
396 if (!this->isCachingEnabled()) {
403template<
typename ValueType>
405 std::vector<ValueType>& x, std::vector<ValueType>
const* b, uint_fast64_t n)
const {
406 if (!multiplierPlayer2Matrix) {
410 if (!auxiliaryP2RowGroupVector) {
411 auxiliaryP2RowGroupVector = std::make_unique<std::vector<ValueType>>(player2Matrix.getRowGroupCount());
413 std::vector<ValueType>& reducedPlayer2Result = *auxiliaryP2RowGroupVector;
415 for (uint_fast64_t iteration = 0; iteration < n; ++iteration) {
416 multiplyAndReduce(env, player1Dir, player2Dir, x, b, *multiplierPlayer2Matrix, reducedPlayer2Result, x);
419 if (!this->isCachingEnabled()) {
424template<
typename ValueType>
426 std::vector<ValueType>& x, std::vector<ValueType>
const* b,
428 std::vector<ValueType>& player1ReducedResult, std::vector<uint64_t>* player1SchedulerChoices,
429 std::vector<uint64_t>* player2SchedulerChoices)
const {
430 multiplier.
multiplyAndReduce(env, player2Dir, x, b, player2ReducedResult, player2SchedulerChoices);
432 if (this->player1RepresentedByMatrix()) {
434 uint_fast64_t player1State = 0;
435 for (
auto& result : player1ReducedResult) {
438 auto it = relevantRows.
begin();
439 auto ite = relevantRows.
end();
442 result = player2ReducedResult[it->getColumn()];
446 if (player1Dir == OptimizationDirection::Minimize) {
447 for (; it != ite; ++it) {
448 result = std::min(result, player2ReducedResult[it->getColumn()]);
451 for (; it != ite; ++it) {
452 result = std::max(result, player2ReducedResult[it->getColumn()]);
460 player1SchedulerChoices);
464template<
typename ValueType>
466 std::vector<ValueType>
const& x, std::vector<ValueType>
const& b,
467 std::vector<ValueType>& player2ChoiceValues, std::vector<uint_fast64_t>& player1Choices,
468 std::vector<uint_fast64_t>& player2Choices)
const {
470 linearEquationSolverIsExact
471 ? storm::utility::zero<ValueType>()
472 :
storm::utility::
convertNumber<
ValueType>(env.solver().getPrecisionOfLinearEquationSolver(env.solver().getLinearEquationSolverType()).first.get()),
476 bool schedulerImproved =
false;
477 auto currentValueIt = player2ChoiceValues.begin();
478 for (uint_fast64_t p2Group = 0; p2Group < this->player2Matrix.getRowGroupCount(); ++p2Group, ++currentValueIt) {
479 uint_fast64_t firstRowInGroup = this->player2Matrix.getRowGroupIndices()[p2Group];
480 uint_fast64_t rowGroupSize = this->player2Matrix.getRowGroupIndices()[p2Group + 1] - firstRowInGroup;
483 uint_fast64_t currentP2Choice = player2Choices[p2Group];
484 *currentValueIt = storm::utility::zero<ValueType>();
485 for (
auto const& entry : this->player2Matrix.getRow(firstRowInGroup + currentP2Choice)) {
486 *currentValueIt += entry.getValue() * x[entry.getColumn()];
488 *currentValueIt += b[firstRowInGroup + currentP2Choice];
491 for (uint_fast64_t p2Choice = 0; p2Choice < rowGroupSize; ++p2Choice) {
492 if (p2Choice == currentP2Choice) {
495 ValueType choiceValue = storm::utility::zero<ValueType>();
496 for (
auto const& entry : this->player2Matrix.getRow(firstRowInGroup + p2Choice)) {
497 choiceValue += entry.getValue() * x[entry.getColumn()];
499 choiceValue += b[firstRowInGroup + p2Choice];
501 if (valueImproved(player2Dir, comparator, *currentValueIt, choiceValue)) {
502 schedulerImproved =
true;
503 player2Choices[p2Group] = p2Choice;
504 *currentValueIt = std::move(choiceValue);
510 if (this->player1RepresentedByMatrix()) {
512 for (uint_fast64_t p1Group = 0; p1Group < this->getPlayer1Matrix().getRowGroupCount(); ++p1Group) {
513 uint_fast64_t firstRowInGroup = this->getPlayer1Matrix().getRowGroupIndices()[p1Group];
514 uint_fast64_t rowGroupSize = this->getPlayer1Matrix().getRowGroupIndices()[p1Group + 1] - firstRowInGroup;
515 uint_fast64_t currentChoice = player1Choices[p1Group];
516 ValueType currentValue = player2ChoiceValues[this->getPlayer1Matrix().getRow(firstRowInGroup + currentChoice).begin()->getColumn()];
517 for (uint_fast64_t p1Choice = 0; p1Choice < rowGroupSize; ++p1Choice) {
519 if (p1Choice == currentChoice) {
522 ValueType const& choiceValue = player2ChoiceValues[this->getPlayer1Matrix().getRow(firstRowInGroup + p1Choice).begin()->getColumn()];
523 if (valueImproved(player1Dir, comparator, currentValue, choiceValue)) {
524 schedulerImproved =
true;
525 player1Choices[p1Group] = p1Choice;
526 currentValue = choiceValue;
532 for (uint64_t player1State = 0; player1State < this->getPlayer1Grouping().size() - 1; ++player1State) {
533 uint64_t currentChoice = player1Choices[player1State];
534 ValueType currentValue = player2ChoiceValues[this->getPlayer1Grouping()[player1State] + currentChoice];
535 uint64_t numberOfPlayer2Successors = this->getPlayer1Grouping()[player1State + 1] - this->getPlayer1Grouping()[player1State];
536 for (uint64_t player2State = 0; player2State < numberOfPlayer2Successors; ++player2State) {
538 if (currentChoice == player2State) {
542 ValueType const& choiceValue = player2ChoiceValues[this->getPlayer1Grouping()[player1State] + player2State];
543 if (valueImproved(player1Dir, comparator, currentValue, choiceValue)) {
544 schedulerImproved =
true;
545 player1Choices[player1State] = player2State;
546 currentValue = choiceValue;
552 return schedulerImproved;
555template<
typename ValueType>
556void StandardGameSolver<ValueType>::getInducedMatrixVector(std::vector<ValueType>&, std::vector<ValueType>
const& b,
557 std::vector<uint_fast64_t>
const& player1Choices, std::vector<uint_fast64_t>
const& player2Choices,
559 std::vector<ValueType>& inducedVector)
const {
562 std::vector<storm::storage::sparse::state_type> selectedRows;
563 if (this->player1RepresentedByMatrix()) {
565 selectedRows.reserve(this->getPlayer1Matrix().getRowGroupCount());
566 uint_fast64_t player1State = 0;
567 for (
auto const& player1Choice : player1Choices) {
568 auto const& player1Row = this->getPlayer1Matrix().getRow(player1State, player1Choice);
569 STORM_LOG_ASSERT(player1Row.getNumberOfEntries() == 1,
"It is assumed that rows of player one have one entry, but this is not the case.");
570 uint_fast64_t player2State = player1Row.begin()->getColumn();
571 selectedRows.push_back(player2Matrix.getRowGroupIndices()[player2State] + player2Choices[player2State]);
576 selectedRows.reserve(this->player2Matrix.getRowGroupCount());
577 for (uint64_t player1State = 0; player1State < this->getPlayer1Grouping().size() - 1; ++player1State) {
578 uint64_t player2State = this->getPlayer1Grouping()[player1State] + player1Choices[player1State];
579 selectedRows.emplace_back(player2Matrix.getRowGroupIndices()[player2State] + player2Choices[player2State]);
586 storm::utility::vector::selectVectorValues<ValueType>(inducedVector, selectedRows, b);
589template<
typename ValueType>
590bool StandardGameSolver<ValueType>::player1RepresentedByMatrix()
const {
591 return player1Matrix !=
nullptr;
594template<
typename ValueType>
596 STORM_LOG_ASSERT(player1RepresentedByMatrix(),
"Player 1 is represented by a matrix.");
597 return *player1Matrix;
600template<
typename ValueType>
601std::vector<uint64_t>
const& StandardGameSolver<ValueType>::getPlayer1Grouping()
const {
602 STORM_LOG_ASSERT(!player1RepresentedByMatrix(),
"Player 1 is represented by a matrix.");
603 return *player1Grouping;
606template<
typename ValueType>
607uint64_t StandardGameSolver<ValueType>::getNumberOfPlayer1States()
const {
608 if (this->player1RepresentedByMatrix()) {
609 return this->getPlayer1Matrix().getRowGroupCount();
611 return this->getPlayer1Grouping().size() - 1;
615template<
typename ValueType>
616uint64_t StandardGameSolver<ValueType>::getNumberOfPlayer2States()
const {
617 return this->player2Matrix.getRowGroupCount();
620template<
typename ValueType>
622 multiplierPlayer2Matrix.reset();
623 auxiliaryP2RowVector.reset();
624 auxiliaryP2RowGroupVector.reset();
625 auxiliaryP1RowGroupVector.reset();
SolverEnvironment & solver()
storm::RationalNumber const & getPrecision() const
uint64_t const & getMaximalNumberOfIterations() const
bool const & isMethodSetFromDefault() const
bool const & getRelativeTerminationCriterion() const
storm::solver::GameMethod const & getMethod() const
storm::solver::EquationSolverType const & getLinearEquationSolverType() const
GameSolverEnvironment & game()
bool isForceExact() const
bool isForceSoundness() const
std::pair< boost::optional< storm::RationalNumber >, boost::optional< bool > > getPrecisionOfLinearEquationSolver(storm::solver::EquationSolverType const &solverType) const
virtual void clearCache() const
std::unique_ptr< Multiplier< ValueType > > create(Environment const &env, storm::storage::SparseMatrix< ValueType > const &matrix)
void multiplyAndReduce(Environment const &env, OptimizationDirection const &dir, std::vector< ValueType > const &x, std::vector< ValueType > const *b, std::vector< ValueType > &result, std::vector< uint_fast64_t > *choices=nullptr) const
Performs a matrix-vector multiplication x' = A*x + b and then minimizes/maximizes over the row groups...
virtual void clearCache() const override
virtual bool solveGame(Environment const &env, OptimizationDirection player1Dir, OptimizationDirection player2Dir, std::vector< ValueType > &x, std::vector< ValueType > const &b, std::vector< uint64_t > *player1Choices=nullptr, std::vector< uint64_t > *player2Choices=nullptr) const override
Solves the equation system defined by the game matrices.
virtual void repeatedMultiply(Environment const &env, OptimizationDirection player1Dir, OptimizationDirection player2Dir, std::vector< ValueType > &x, std::vector< ValueType > const *b, uint_fast64_t n=1) const override
Performs (repeated) matrix-vector multiplication with the given parameters, i.e.
StandardGameSolver(storm::storage::SparseMatrix< storm::storage::sparse::state_type > const &player1Matrix, storm::storage::SparseMatrix< ValueType > const &player2Matrix, std::unique_ptr< LinearEquationSolverFactory< ValueType > > &&linearEquationSolverFactory)
A bit vector that is internally represented as a vector of 64-bit values.
size_t size() const
Retrieves the number of bits this bit vector can store.
This class represents a number of consecutive rows of the matrix.
const_iterator end() const
Retrieves an iterator that points past the last entry of the rows.
index_type getNumberOfEntries() const
Retrieves the number of entries in the rows.
const_iterator begin() const
Retrieves an iterator that points to the beginning of the rows.
A class that holds a possibly non-square matrix in the compressed row storage format.
void convertToEquationSystem()
Transforms the matrix into an equation system.
SparseMatrix selectRowsFromRowIndexSequence(std::vector< index_type > const &rowIndexSequence, bool insertDiagonalEntries=true) const
Selects the rows that are given by the sequence of row indices, allowing to select rows arbitrarily o...
storm::storage::SparseMatrix< value_type > transpose(bool joinGroups=false, bool keepZeros=false) const
Transposes the matrix.
index_type getRowCount() const
Returns the number of rows of the matrix.
bool isLess(ValueType const &value1, ValueType const &value2) const
#define STORM_LOG_INFO(message)
#define STORM_LOG_WARN(message)
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
SFTBDDChecker::ValueType ValueType
SettingsType const & getModule()
Get module.
std::string toString(GurobiSolverMethod const &method)
Yields a string representation of the GurobiSolverMethod.
storm::storage::BitVector performProbGreater0(storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, bool useStepBound, uint_fast64_t maximalSteps)
Performs a backward depth-first search trough the underlying graph structure of the given model to de...
void reduceVectorMinOrMax(storm::solver::OptimizationDirection dir, std::vector< T > const &source, std::vector< T > &target, std::vector< uint_fast64_t > const &rowGrouping, std::vector< uint_fast64_t > *choices=nullptr)
Reduces the given source vector by selecting either the smallest or the largest out of each row group...
storm::storage::BitVector filterGreaterZero(std::vector< T > const &values)
Retrieves a bit vector containing all the indices for which the value at this position is greater tha...
TargetType convertNumber(SourceType const &number)