@ -201,6 +201,7 @@ namespace storm { 
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                 
			
		
	
		
			
				
					                swAux . start ( ) ;  
			
		
	
		
			
				
					                // compute the solution for the stepChoices
  
			
		
	
		
			
				
					                epochModel . stepSolutions . resize ( epochModel . stepChoices . getNumberOfSetBits ( ) ) ;  
			
		
	
		
			
				
					                auto  stepSolIt  =  epochModel . stepSolutions . begin ( ) ;  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -208,23 +209,30 @@ namespace storm { 
			
		
	
		
			
				
					                    uint64_t  productChoice  =  ecElimResult . newToOldRowMapping [ reducedChoice ] ;  
			
		
	
		
			
				
					                    uint64_t  productState  =  memoryProduct . getProductStateFromChoice ( productChoice ) ;  
			
		
	
		
			
				
					                    auto  relevantDimensions  =  memoryProduct . convertMemoryState ( memoryProduct . getMemoryState ( productState ) ) ;  
			
		
	
		
			
				
					                    SolutionType  choiceSolution  =  getZeroSolution ( ) ;  
			
		
	
		
			
				
					                    Epoch  successorEpoch  =  getSuccessorEpoch ( epoch ,  memoryProduct . getSteps ( ) [ productChoice ] . get ( ) ) ;  
			
		
	
		
			
				
					                    storm : : storage : : BitVector  successorRelevantDimensions ( successorEpoch . size ( ) ,  true ) ;  
			
		
	
		
			
				
					                    for  ( auto  const &  dim  :  relevantDimensions )  {  
			
		
	
		
			
				
					                        if  ( successorEpoch [ dim ]  <  0 )  {  
			
		
	
		
			
				
					                            successorRelevantDimensions  & =  ~ objectiveDimensions [ subObjectives [ dim ] . second ] ;  
			
		
	
		
			
				
					                    SolutionType  choiceSolution  =  getZeroSolution ( ) ;  
			
		
	
		
			
				
					                    if  ( getClassOfEpoch ( epoch )  = =  getClassOfEpoch ( successorEpoch ) )  {  
			
		
	
		
			
				
					                        for  ( auto  const &  successor  :  memoryProduct . getProduct ( ) . getTransitionMatrix ( ) . getRow ( productChoice ) )  {  
			
		
	
		
			
				
					                            addScaledSolution ( choiceSolution ,  getStateSolution ( successorEpoch ,  successor . getColumn ( ) ) ,  successor . getValue ( ) ) ;  
			
		
	
		
			
				
					                        }  
			
		
	
		
			
				
					                    }  else  {  
			
		
	
		
			
				
					                        storm : : storage : : BitVector  successorRelevantDimensions ( successorEpoch . size ( ) ,  true ) ;  
			
		
	
		
			
				
					                        for  ( auto  const &  dim  :  relevantDimensions )  {  
			
		
	
		
			
				
					                            if  ( successorEpoch [ dim ]  <  0 )  {  
			
		
	
		
			
				
					                                successorRelevantDimensions  & =  ~ objectiveDimensions [ subObjectives [ dim ] . second ] ;  
			
		
	
		
			
				
					                            }  
			
		
	
		
			
				
					                        }  
			
		
	
		
			
				
					                        for  ( auto  const &  successor  :  memoryProduct . getProduct ( ) . getTransitionMatrix ( ) . getRow ( productChoice ) )  {  
			
		
	
		
			
				
					                            storm : : storage : : BitVector  successorMemoryState  =  memoryProduct . convertMemoryState ( memoryProduct . getMemoryState ( successor . getColumn ( ) ) )  &  successorRelevantDimensions ;  
			
		
	
		
			
				
					                            uint64_t  successorProductState  =  memoryProduct . getProductState ( memoryProduct . getModelState ( successor . getColumn ( ) ) ,  memoryProduct . convertMemoryState ( successorMemoryState ) ) ;  
			
		
	
		
			
				
					                            SolutionType  const &  successorSolution  =  getStateSolution ( successorEpoch ,  successorProductState ) ;  
			
		
	
		
			
				
					                            addScaledSolution ( choiceSolution ,  successorSolution ,  successor . getValue ( ) ) ;  
			
		
	
		
			
				
					                        }  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                    for  ( auto  const &  successor  :  memoryProduct . getProduct ( ) . getTransitionMatrix ( ) . getRow ( productChoice ) )  {  
			
		
	
		
			
				
					                        storm : : storage : : BitVector  successorMemoryState  =  memoryProduct . convertMemoryState ( memoryProduct . getMemoryState ( successor . getColumn ( ) ) )  &  successorRelevantDimensions ;  
			
		
	
		
			
				
					                        uint64_t  successorProductState  =  memoryProduct . getProductState ( memoryProduct . getModelState ( successor . getColumn ( ) ) ,  memoryProduct . convertMemoryState ( successorMemoryState ) ) ;  
			
		
	
		
			
				
					                        SolutionType  const &  successorSolution  =  getStateSolution ( successorEpoch ,  successorProductState ) ;  
			
		
	
		
			
				
					                        addScaledSolution ( choiceSolution ,  successorSolution ,  successor . getValue ( ) ) ;  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                    * stepSolIt  =  std : : move ( choiceSolution ) ;  
			
		
	
		
			
				
					                    + + stepSolIt ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                swAux . stop ( ) ;  
			
		
	
		
			
				
					                 
			
		
	
		
			
				
					                assert ( epochModel . objectiveRewards . size ( )  = =  objectives . size ( ) ) ;  
			
		
	
		
			
				
					                assert ( epochModel . objectiveRewardFilter . size ( )  = =  objectives . size ( ) ) ;  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -254,6 +262,7 @@ namespace storm { 
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            template < typename  ValueType >  
			
		
	
		
			
				
					            void  MultiDimensionalRewardUnfolding < ValueType > : : setCurrentEpochClass ( Epoch  const &  epoch )  {  
			
		
	
		
			
				
					                // std::cout << "Setting epoch class for epoch " << storm::utility::vector::toString(epoch) << std::endl;
  
			
		
	
		
			
				
					                swSetEpochClass . start ( ) ;  
			
		
	
		
			
				
					                auto  productObjectiveRewards  =  computeObjectiveRewardsForProduct ( epoch ) ;  
			
		
	
		
			
				
					                 
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -282,9 +291,11 @@ namespace storm { 
			
		
	
		
			
				
					                storm : : storage : : BitVector  allProductStates ( memoryProduct . getProduct ( ) . getNumberOfStates ( ) ,  true ) ;  
			
		
	
		
			
				
					                 
			
		
	
		
			
				
					                // Get the relevant states for this epoch. These are all states
  
			
		
	
		
			
				
					                storm : : storage : : BitVector  productRelevant States  =  computeRelevant ProductStatesForEpochClass ( epoch ) ;  
			
		
	
		
			
				
					                storm : : storage : : BitVector  productIn States  =  computeProductIn StatesForEpochClass ( epoch ) ;  
			
		
	
		
			
				
					                // The epoch model only needs to consider the states that are reachable from a relevant state
  
			
		
	
		
			
				
					                storm : : storage : : BitVector  consideredStates  =  storm : : utility : : graph : : getReachableStates ( epochModel . epochMatrix ,  productRelevantStates ,  allProductStates ,  ~ allProductStates ) ;  
			
		
	
		
			
				
					                storm : : storage : : BitVector  consideredStates  =  storm : : utility : : graph : : getReachableStates ( epochModel . epochMatrix ,  productInStates ,  allProductStates ,  ~ allProductStates ) ;  
			
		
	
		
			
				
					                // std::cout << "numInStates = " << productInStates.getNumberOfSetBits() << std::endl;
  
			
		
	
		
			
				
					                // std::cout << "numConsideredStates = " << consideredStates.getNumberOfSetBits() << std::endl;
  
			
		
	
		
			
				
					                 
			
		
	
		
			
				
					                // We assume that there is no end component in which objective reward is earned
  
			
		
	
		
			
				
					                STORM_LOG_ASSERT ( ! storm : : utility : : graph : : checkIfECWithChoiceExists ( epochModel . epochMatrix ,  epochModel . epochMatrix . transpose ( true ) ,  allProductStates ,  ~ zeroObjRewardChoices  &  ~ stepChoices ) ,  " There is a scheduler that yields infinite reward for one objective. This case should be excluded " ) ;  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -309,9 +320,9 @@ namespace storm { 
			
		
	
		
			
				
					                    epochModel . objectiveRewards . push_back ( std : : move ( reducedModelObjRewards ) ) ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                 
			
		
	
		
			
				
					                epochModel . relevant States=  storm : : storage : : BitVector ( epochModel . epochMatrix . getRowGroupCount ( ) ,  false ) ;  
			
		
	
		
			
				
					                for  ( auto  const &  productState  :  productRelevant States )  {  
			
		
	
		
			
				
					                    epochModel . relevant States. set ( ecElimResult . oldToNewStateMapping [ productState ] ,  true ) ;  
			
		
	
		
			
				
					                epochModel . in States=  storm : : storage : : BitVector ( epochModel . epochMatrix . getRowGroupCount ( ) ,  false ) ;  
			
		
	
		
			
				
					                for  ( auto  const &  productState  :  productIn States )  {  
			
		
	
		
			
				
					                    epochModel . in States. set ( ecElimResult . oldToNewStateMapping [ productState ] ,  true ) ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                 
			
		
	
		
			
				
					                swSetEpochClass . stop ( ) ;  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -319,47 +330,72 @@ namespace storm { 
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            template < typename  ValueType >  
			
		
	
		
			
				
					            storm : : storage : : BitVector  MultiDimensionalRewardUnfolding < ValueType > : : computeRelevantProductStatesForEpochClass ( Epoch  const &  epoch )  {  
			
		
	
		
			
				
					                storm : : storage : : BitVector  result ( memoryProduct . getProduct ( ) . getNumberOfStates ( ) ,  false ) ;  
			
		
	
		
			
				
					                result . set ( * memoryProduct . getProduct ( ) . getInitialStates ( ) . begin ( ) ,  true ) ;  
			
		
	
		
			
				
					            storm : : storage : : BitVector  MultiDimensionalRewardUnfolding < ValueType > : : computeProductInStatesForEpochClass ( Epoch  const &  epoch )  {  
			
		
	
		
			
				
					                storm : : storage : : SparseMatrix < ValueType >  const &  productMatrix  =  memoryProduct . getProduct ( ) . getTransitionMatrix ( ) ;  
			
		
	
		
			
				
					                 
			
		
	
		
			
				
					                for  ( uint64_t  choice  =  0 ;  choice  <  memoryProduct . getProduct ( ) . getNumberOfChoices ( ) ;  + + choice )  {  
			
		
	
		
			
				
					                    auto  const &  choiceStep  =  memoryProduct . getSteps ( ) [ choice ] ;  
			
		
	
		
			
				
					                    if  ( choiceStep )  {  
			
		
	
		
			
				
					                        storm : : storage : : BitVector  objectiveSet ( objectives . size ( ) ,  false ) ;  
			
		
	
		
			
				
					                        for  ( uint64_t  dim  =  0 ;  dim  <  epoch . size ( ) ;  + + dim )  {  
			
		
	
		
			
				
					                            if  ( epoch [ dim ]  <  0  & &  choiceStep . get ( ) [ dim ]  >  0 )  {  
			
		
	
		
			
				
					                                objectiveSet . set ( subObjectives [ dim ] . second ) ;  
			
		
	
		
			
				
					                            }  
			
		
	
		
			
				
					                        }  
			
		
	
		
			
				
					                         
			
		
	
		
			
				
					                        if  ( objectiveSet . empty ( ) )  {  
			
		
	
		
			
				
					                            for  ( auto  const &  choiceSuccessor  :  memoryProduct . getProduct ( ) . getTransitionMatrix ( ) . getRow ( choice ) )  {  
			
		
	
		
			
				
					                                result . set ( choiceSuccessor . getColumn ( ) ,  true ) ;  
			
		
	
		
			
				
					                storm : : storage : : BitVector  result ( productMatrix . getRowGroupCount ( ) ,  false ) ;  
			
		
	
		
			
				
					                result . set ( * memoryProduct . getProduct ( ) . getInitialStates ( ) . begin ( ) ,  true ) ;  
			
		
	
		
			
				
					                // Perform DFS
  
			
		
	
		
			
				
					                storm : : storage : : BitVector  reachableStates  =  result ;  
			
		
	
		
			
				
					                std : : vector < uint_fast64_t >  stack ( reachableStates . begin ( ) ,  reachableStates . end ( ) ) ;  
			
		
	
		
			
				
					                 
			
		
	
		
			
				
					                while  ( ! stack . empty ( ) )  {  
			
		
	
		
			
				
					                    uint64_t  state  =  stack . back ( ) ;  
			
		
	
		
			
				
					                    stack . pop_back ( ) ;  
			
		
	
		
			
				
					                 
			
		
	
		
			
				
					                    for  ( uint64_t  choice  =  productMatrix . getRowGroupIndices ( ) [ state ] ;  choice  <  productMatrix . getRowGroupIndices ( ) [ state  +  1 ] ;  + + choice )  {  
			
		
	
		
			
				
					                        auto  const &  choiceStep  =  memoryProduct . getSteps ( ) [ choice ] ;  
			
		
	
		
			
				
					                        if  ( choiceStep )  {  
			
		
	
		
			
				
					                            storm : : storage : : BitVector  objectiveSet ( objectives . size ( ) ,  false ) ;  
			
		
	
		
			
				
					                            for  ( uint64_t  dim  =  0 ;  dim  <  epoch . size ( ) ;  + + dim )  {  
			
		
	
		
			
				
					                                if  ( epoch [ dim ]  <  0  & &  choiceStep . get ( ) [ dim ]  >  0 )  {  
			
		
	
		
			
				
					                                    objectiveSet . set ( subObjectives [ dim ] . second ) ;  
			
		
	
		
			
				
					                                }  
			
		
	
		
			
				
					                            }  
			
		
	
		
			
				
					                        }  else  {  
			
		
	
		
			
				
					                            storm : : storage : : BitVector  objectiveSubSet ( objectiveSet . getNumberOfSetBits ( ) ,  false ) ;  
			
		
	
		
			
				
					                            do  {  
			
		
	
		
			
				
					                                for  ( auto  const &  choiceSuccessor  :  memoryProduct . getProduct ( ) . getTransitionMatrix ( ) . getRow ( choice ) )  {  
			
		
	
		
			
				
					                                    uint64_t  modelState  =  memoryProduct . getModelState ( choiceSuccessor . getColumn ( ) ) ;  
			
		
	
		
			
				
					                                    uint64_t  memoryState  =  memoryProduct . getMemoryState ( choiceSuccessor . getColumn ( ) ) ;  
			
		
	
		
			
				
					                                    storm : : storage : : BitVector  memoryStatePrimeBv  =  memoryProduct . convertMemoryState ( memoryState ) ;  
			
		
	
		
			
				
					                                    uint64_t  i  =  0 ;  
			
		
	
		
			
				
					                                    for  ( auto  const &  objIndex  :  objectiveSet )  {  
			
		
	
		
			
				
					                                        if  ( objectiveSubSet . get ( i ) )  {  
			
		
	
		
			
				
					                                            memoryStatePrimeBv  & =  ~ objectiveDimensions [ objIndex ] ;  
			
		
	
		
			
				
					                             
			
		
	
		
			
				
					                            if  ( objectiveSet . empty ( ) )  {  
			
		
	
		
			
				
					                                for  ( auto  const &  choiceSuccessor  :  productMatrix . getRow ( choice ) )  {  
			
		
	
		
			
				
					                                    result . set ( choiceSuccessor . getColumn ( ) ,  true ) ;  
			
		
	
		
			
				
					                                    if  ( ! reachableStates . get ( choiceSuccessor . getColumn ( ) ) )  {  
			
		
	
		
			
				
					                                        reachableStates . set ( choiceSuccessor . getColumn ( ) ) ;  
			
		
	
		
			
				
					                                        stack . push_back ( choiceSuccessor . getColumn ( ) ) ;  
			
		
	
		
			
				
					                                    }  
			
		
	
		
			
				
					                                }  
			
		
	
		
			
				
					                            }  else  {  
			
		
	
		
			
				
					                                storm : : storage : : BitVector  objectiveSubSet ( objectiveSet . getNumberOfSetBits ( ) ,  false ) ;  
			
		
	
		
			
				
					                                do  {  
			
		
	
		
			
				
					                                    for  ( auto  const &  choiceSuccessor  :  productMatrix . getRow ( choice ) )  {  
			
		
	
		
			
				
					                                        uint64_t  modelState  =  memoryProduct . getModelState ( choiceSuccessor . getColumn ( ) ) ;  
			
		
	
		
			
				
					                                        uint64_t  memoryState  =  memoryProduct . getMemoryState ( choiceSuccessor . getColumn ( ) ) ;  
			
		
	
		
			
				
					                                        storm : : storage : : BitVector  memoryStatePrimeBv  =  memoryProduct . convertMemoryState ( memoryState ) ;  
			
		
	
		
			
				
					                                        uint64_t  i  =  0 ;  
			
		
	
		
			
				
					                                        for  ( auto  const &  objIndex  :  objectiveSet )  {  
			
		
	
		
			
				
					                                            if  ( objectiveSubSet . get ( i ) )  {  
			
		
	
		
			
				
					                                                memoryStatePrimeBv  & =  ~ objectiveDimensions [ objIndex ] ;  
			
		
	
		
			
				
					                                            }  
			
		
	
		
			
				
					                                            + + i ;  
			
		
	
		
			
				
					                                        }  
			
		
	
		
			
				
					                                        uint64_t  successorState  =  memoryProduct . getProductState ( modelState ,  memoryProduct . convertMemoryState ( memoryStatePrimeBv ) ) ;  
			
		
	
		
			
				
					                                        result . set ( successorState ,  true ) ;  
			
		
	
		
			
				
					                                        if  ( ! reachableStates . get ( successorState ) )  {  
			
		
	
		
			
				
					                                            reachableStates . set ( successorState ) ;  
			
		
	
		
			
				
					                                            stack . push_back ( successorState ) ;  
			
		
	
		
			
				
					                                        }  
			
		
	
		
			
				
					                                        + + i ;  
			
		
	
		
			
				
					                                    }  
			
		
	
		
			
				
					                                    result . set ( memoryProduct . getProductState ( modelState ,  memoryProduct . convertMemoryState ( memoryStatePrimeBv ) ) ,  true ) ;  
			
		
	
		
			
				
					                                     
			
		
	
		
			
				
					                                    objectiveSubSet . increment ( ) ;  
			
		
	
		
			
				
					                                }  while  ( ! objectiveSubSet . empty ( ) ) ;  
			
		
	
		
			
				
					                            }  
			
		
	
		
			
				
					                        }  else  {  
			
		
	
		
			
				
					                            for  ( auto  const &  choiceSuccessor  :  productMatrix . getRow ( choice ) )  {  
			
		
	
		
			
				
					                                if  ( ! reachableStates . get ( choiceSuccessor . getColumn ( ) ) )  {  
			
		
	
		
			
				
					                                    reachableStates . set ( choiceSuccessor . getColumn ( ) ) ;  
			
		
	
		
			
				
					                                    stack . push_back ( choiceSuccessor . getColumn ( ) ) ;  
			
		
	
		
			
				
					                                }  
			
		
	
		
			
				
					                                 
			
		
	
		
			
				
					                                objectiveSubSet . increment ( ) ;  
			
		
	
		
			
				
					                            }  while  ( ! objectiveSubSet . empty ( ) ) ;  
			
		
	
		
			
				
					                            }  
			
		
	
		
			
				
					                        }  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                 
			
		
	
		
			
				
					                return  result ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					             
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -378,12 +414,12 @@ namespace storm { 
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            template < typename  ValueType >  
			
		
	
		
			
				
					            void  MultiDimensionalRewardUnfolding < ValueType > : : setSolutionForCurrentEpoch ( std : : vector < SolutionType >  const &  relevant StateSolutions)  {  
			
		
	
		
			
				
					            void  MultiDimensionalRewardUnfolding < ValueType > : : setSolutionForCurrentEpoch ( std : : vector < SolutionType >  const &  in StateSolutions)  {  
			
		
	
		
			
				
					                swInsertSol . start ( ) ;  
			
		
	
		
			
				
					                for  ( uint64_t  productState  =  0 ;  productState  <  memoryProduct . getProduct ( ) . getNumberOfStates ( ) ;  + + productState )  {  
			
		
	
		
			
				
					                    uint64_t  reducedModelState  =  ecElimResult . oldToNewStateMapping [ productState ] ;  
			
		
	
		
			
				
					                    if  ( reducedModelState  <  epochModel . epochMatrix . getRowGroupCount ( )  & &  epochModel . relevant States. get ( reducedModelState ) )  {  
			
		
	
		
			
				
					                        setSolutionForCurrentEpoch ( productState ,  relevant StateSolutions[ epochModel . relevant States. getNumberOfSetBitsBeforeIndex ( reducedModelState ) ] ) ;  
			
		
	
		
			
				
					                    if  ( reducedModelState  <  epochModel . epochMatrix . getRowGroupCount ( )  & &  epochModel . in States. get ( reducedModelState ) )  {  
			
		
	
		
			
				
					                        setSolutionForCurrentEpoch ( productState ,  in StateSolutions[ epochModel . in States. getNumberOfSetBitsBeforeIndex ( reducedModelState ) ] ) ;  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                swInsertSol . stop ( ) ;