| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -20,12 +20,34 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        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.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            bool converged = false; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            uint_fast64_t numberOfPlayer1States = x.size(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            std::vector<ValueType> tmpResult(numberOfPlayer1States); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            std::vector<ValueType> nondetResult(player2Matrix.getRowCount()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            std::vector<ValueType> player2Result(player2Matrix.getRowGroupCount()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // check if we have a scheduler hint to apply
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if(this->hasSchedulerHints()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                //Get the rows of the player2matrix that are selected by the schedulers
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                //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 = player1Matrix.getRow(pl1State, this->player1SchedulerHint->getChoice(pl1State)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    STORM_LOG_ASSERT(pl1Row.getNumberOfEntries()==1, "We assume that rows of player one have one entry."); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    uint_fast64_t pl2State = pl1Row.begin()->getColumn(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    selectedRows[pl1State] = player2Matrix.getRowGroupIndices()[pl2State] + this->player2SchedulerHint->getChoice(pl1State); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                //Get the matrix and the vector induced by this selection
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                auto inducedMatrix = player2Matrix.selectRowsFromRowIndexSequence(selectedRows, true); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                inducedMatrix.convertToEquationSystem(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                storm::utility::vector::selectVectorValues<ValueType>(tmpResult, selectedRows, b); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                auto submatrixSolver = storm::solver::GeneralLinearEquationSolverFactory<ValueType>().create(std::move(inducedMatrix)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (this->lowerBound) { submatrixSolver->setLowerBound(this->lowerBound.get()); } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (this->upperBound) { submatrixSolver->setUpperBound(this->upperBound.get()); } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                submatrixSolver->solveEquations(x, tmpResult); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // Now perform the actual value iteration.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            uint_fast64_t iterations = 0; | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -111,6 +133,51 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                this->player1Scheduler = std::make_unique<storm::storage::TotalScheduler>(std::move(player1Choices)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					     | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        template <typename ValueType> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        void GameSolver<ValueType>::repeatedMultiply(OptimizationDirection player1Goal, OptimizationDirection player2Goal, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // Set up the environment for iterations
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            uint_fast64_t numberOfPlayer1States = x.size(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            std::vector<ValueType> tmpResult(numberOfPlayer1States); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            std::vector<ValueType> nondetResult(player2Matrix.getRowCount()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            std::vector<ValueType> player2Result(player2Matrix.getRowGroupCount()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            for (uint_fast64_t iteration = 0; iteration < n; ++iteration) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                player2Matrix.multiplyWithVector(x, nondetResult); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if(b != nullptr) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    storm::utility::vector::addVectors(*b, nondetResult, nondetResult); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                storm::utility::vector::reduceVectorMinOrMax(player2Goal, 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>(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                std::swap(x, tmpResult); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        template <typename ValueType> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        storm::storage::SparseMatrix<storm::storage::sparse::state_type> const& GameSolver<ValueType>::getPlayer1Matrix() const { | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -121,7 +188,7 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        storm::storage::SparseMatrix<ValueType> const& GameSolver<ValueType>::getPlayer2Matrix() const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            return player2Matrix; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					     | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        template class GameSolver<double>; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} |