@ -280,10 +280,15 @@ namespace storm {
}
storm : : storage : : BitVector allProductStates ( memoryProduct . getProduct ( ) . getNumberOfStates ( ) , true ) ;
// We assume that there is no end component in which reward is earned
// Get the relevant states for this epoch. These are all states
storm : : storage : : BitVector productRelevantStates = computeRelevantProductStatesForEpochClass ( 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 ) ;
// 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 " ) ;
// TODO: unselect unreachable states
ecElimResult = storm : : transformer : : EndComponentEliminator < ValueType > : : transform ( epochModel . epochMatrix , allProductStates , zeroObjRewardChoices & ~ stepChoices , allProductStates ) ;
ecElimResult = storm : : transformer : : EndComponentEliminator < ValueType > : : transform ( epochModel . epochMatrix , consideredStates , zeroObjRewardChoices & ~ stepChoices , consideredStates ) ;
epochModel . epochMatrix = std : : move ( ecElimResult . matrix ) ;
epochModel . stepChoices = storm : : storage : : BitVector ( epochModel . epochMatrix . getRowCount ( ) , false ) ;
@ -292,7 +297,7 @@ namespace storm {
epochModel . stepChoices . set ( choice , true ) ;
}
}
STORM_LOG_ASSERT ( epochModel . stepChoices . getNumberOfSetBits ( ) = = stepChoices . getNumberOfSetBits ( ) , " The number of choices leading outside of the epoch does not match for the reduced and unreduced epochMatrix " ) ;
//STORM_LOG_ASSERT(epochModel.stepChoices.getNumberOfSetBits() == stepChoices.getNumberOfSetBits(), " The number of choices leading outside of the epoch does not match for the reduced and unreduced epochMatrix");
epochModel . objectiveRewards . clear ( ) ;
for ( auto const & productObjRew : productObjectiveRewards ) {
@ -303,9 +308,60 @@ namespace storm {
}
epochModel . objectiveRewards . push_back ( std : : move ( reducedModelObjRewards ) ) ;
}
epochModel . relevantStates = storm : : storage : : BitVector ( epochModel . epochMatrix . getRowGroupCount ( ) , false ) ;
for ( auto const & productState : productRelevantStates ) {
epochModel . relevantStates . set ( ecElimResult . oldToNewStateMapping [ productState ] , true ) ;
}
swSetEpochClass . stop ( ) ;
}
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 ) ;
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 ) ;
}
} 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 ] ;
}
+ + i ;
}
result . set ( memoryProduct . getProductState ( modelState , memoryProduct . convertMemoryState ( memoryStatePrimeBv ) ) , true ) ;
}
objectiveSubSet . increment ( ) ;
} while ( ! objectiveSubSet . empty ( ) ) ;
}
}
}
return result ;
}
template < typename ValueType >
typename MultiDimensionalRewardUnfolding < ValueType > : : SolutionType MultiDimensionalRewardUnfolding < ValueType > : : getZeroSolution ( ) const {
SolutionType res ;
@ -470,9 +526,7 @@ namespace storm {
storm : : storage : : SparseModelMemoryProduct < ValueType > productBuilder ( memory . product ( model ) ) ;
setReachableStates ( productBuilder , originalModelSteps , objectiveDimensions ) ;
sw1 . stop ( ) ;
product = productBuilder . build ( ) - > template as < storm : : models : : sparse : : Mdp < ValueType > > ( ) ;
sw2 . stop ( ) ;
uint64_t numModelStates = productBuilder . getOriginalModel ( ) . getNumberOfStates ( ) ;
uint64_t numMemoryStates = productBuilder . getMemory ( ) . getNumberOfStates ( ) ;