@ -1,7 +1,8 @@ 
			
		 
		
	
		
			
				 
				 
				# include  "src/solver/GameSolver.h" 
  
				 
				 
				# include  "src/solver/GameSolver.h" 
  
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				# include  "src/solver/LinearEquationSolver.h" 
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				# include  "src/utility/solver.h" 
  
			
		 
		
	
		
			
				 
				 
				# include  "src/storage/SparseMatrix.h" 
  
				 
				 
				# include  "src/storage/SparseMatrix.h" 
  
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				# include  "src/utility/vector.h" 
  
				 
				 
				# include  "src/utility/vector.h" 
  
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				namespace  storm  {  
				 
				 
				namespace  storm  {  
			
		 
		
	
	
		
			
				
					
					
					
						
							 
						 
					
				 
				@ -17,10 +18,30 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				        }  
				 
				 
				        }  
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				        template  < typename  ValueType >  
				 
				 
				        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.
  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				        void  GameSolver < ValueType > : : solveGame ( OptimizationDirection  player1Goal ,  OptimizationDirection  player2Goal ,  std : : vector < ValueType > &  x ,  std : : vector < ValueType >  const &  b ,  std : : vector < storm : : storage : : sparse : : state_type > *  initialPlayer1Policy ,  std : : vector < storm : : storage : : sparse : : state_type > *  initialPlayer2Policy )  const  {  
			
		 
		
	
		
			
				 
				 
				            uint_fast64_t  numberOfPlayer1States  =  x . size ( ) ;  
				 
				 
				            uint_fast64_t  numberOfPlayer1States  =  x . size ( ) ;  
			
		 
		
	
		
			
				 
				 
				             
				 
				 
				             
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				            if ( initialPlayer1Policy  ! =  nullptr  | |  initialPlayer2Policy  ! =  nullptr ) {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                //Either we work with both policies or none of them
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                assert ( initialPlayer1Policy  ! =  nullptr  & &  initialPlayer2Policy  ! =  nullptr ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                //The policies select certain rows in the matrix of player2.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                //However, 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 &  pl1Choice  =  player1Matrix . getRow ( player1Matrix . getRowGroupIndices ( ) [ pl1State ]  +  ( * initialPlayer1Policy ) [ pl1State ] ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    assert ( pl1Choice . getNumberOfEntries ( ) = = 1 ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    uint_fast64_t  pl2State  =  pl1Choice . begin ( ) - > getColumn ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    selectedRows [ pl1State ]  =  player2Matrix . getRowGroupIndices ( ) [ pl2State ]  +  ( * initialPlayer2Policy ) [ pl2State ] ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                storm : : storage : : SparseMatrix < ValueType >  eqSysMatrix  =  player2Matrix . selectRowsFromRowIndexSequence ( selectedRows ,  true ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                eqSysMatrix . convertToEquationSystem ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                std : : unique_ptr < storm : : solver : : LinearEquationSolver < ValueType > >  solver  =  storm : : utility : : solver : : LinearEquationSolverFactory < ValueType > ( ) . create ( eqSysMatrix ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                std : : vector < ValueType >  subB ( numberOfPlayer1States ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                storm : : utility : : vector : : selectVectorValues < ValueType > ( subB ,  selectedRows ,  b ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                solver - > solveEquationSystem ( x ,  subB ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				            }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				             
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				            // Set up the environment for value iteration.
  
			
		 
		
	
		
			
				 
				 
				            bool  converged  =  false ;  
				 
				 
				            bool  converged  =  false ;  
			
		 
		
	
		
			
				 
				 
				            std : : vector < ValueType >  tmpResult ( numberOfPlayer1States ) ;  
				 
				 
				            std : : vector < ValueType >  tmpResult ( numberOfPlayer1States ) ;  
			
		 
		
	
		
			
				 
				 
				            std : : vector < ValueType >  nondetResult ( player2Matrix . getRowCount ( ) ) ;  
				 
				 
				            std : : vector < ValueType >  nondetResult ( player2Matrix . getRowCount ( ) ) ;  
			
		 
		
	
	
		
			
				
					
						
							 
						 
					
					
						
							 
						 
					
					
				 
				@ -69,6 +90,44 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				                + + iterations ;  
				 
				 
				                + + iterations ;  
			
		 
		
	
		
			
				 
				 
				            }  while  ( ! converged  & &  iterations  <  maximalNumberOfIterations ) ;  
				 
				 
				            }  while  ( ! converged  & &  iterations  <  maximalNumberOfIterations ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				             
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				            STORM_LOG_WARN_COND ( converged ,  " Iterative solver for stochastic two player games did not converge after  "  < <  iterations  < <  " iterations. " ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				             
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				            if ( this - > trackPolicies ) {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                this - > player2Policy  =  std : : vector < storm : : storage : : sparse : : state_type > ( player2Matrix . getRowGroupCount ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                storm : : utility : : vector : : reduceVectorMinOrMax ( player2Goal ,  nondetResult ,  player2Result ,  player2Matrix . getRowGroupIndices ( ) ,  & this - > player2Policy ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                this - > player1Policy  =  std : : vector < storm : : storage : : sparse : : state_type > ( numberOfPlayer1States ,  0 ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                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 ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        storm : : storage : : sparse : : state_type  localChoice  =  1 ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        // Now iterate through the different values and pick the extremal one.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        if  ( player1Goal  = =  OptimizationDirection : : Minimize )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            for  ( ;  it  ! =  ite ;  + + it ,  + + localChoice )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                if ( player2Result [ it - > getColumn ( ) ]  <  tmpResult [ pl1State ] ) {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                    tmpResult [ pl1State ]  =  player2Result [ it - > getColumn ( ) ] ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                    this - > player1Policy [ pl1State ]  =  localChoice ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        }  else  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            for  ( ;  it  ! =  ite ;  + + it ,  + + localChoice )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                if ( player2Result [ it - > getColumn ( ) ]  >  tmpResult [ pl1State ] ) {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                    tmpResult [ pl1State ]  =  player2Result [ it - > getColumn ( ) ] ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                    this - > player1Policy [ pl1State ]  =  localChoice ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    }  else  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        STORM_LOG_ERROR ( " There is no choice for Player 1 at state  "  < <  pl1State  < <  "  in the stochastic two player game. This is not expected! " ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				            }  
			
		 
		
	
		
			
				 
				 
				        }  
				 
				 
				        }  
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				        template  class  GameSolver < double > ;  
				 
				 
				        template  class  GameSolver < double > ;