|  |  | @ -14,7 +14,7 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  |             namespace internal { | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 template <typename ValueType> | 
			
		
	
		
			
				
					|  |  |  |                 SoundGameViHelper<ValueType>::SoundGameViHelper(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector statesOfCoalition, storm::storage::BitVector psiStates, OptimizationDirection const& optimizationDirection) : _transitionMatrix(transitionMatrix), _backwardTransitions(backwardTransitions), _statesOfCoalition(statesOfCoalition), _psiStates(psiStates), _optimizationDirection(optimizationDirection) { | 
			
		
	
		
			
				
					|  |  |  |                 SoundGameViHelper<ValueType>::SoundGameViHelper(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> b, storm::storage::BitVector statesOfCoalition, storm::storage::BitVector psiStates, OptimizationDirection const& optimizationDirection) : _transitionMatrix(transitionMatrix), _backwardTransitions(backwardTransitions), _statesOfCoalition(statesOfCoalition), _psiStates(psiStates), _optimizationDirection(optimizationDirection), _b(b) { | 
			
		
	
		
			
				
					|  |  |  |                     // Intentionally left empty.
 | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -24,6 +24,8 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  |                     _multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, _transitionMatrix); | 
			
		
	
		
			
				
					|  |  |  |                     _x1IsCurrent = false; | 
			
		
	
		
			
				
					|  |  |  |                     _minimizerStates = _optimizationDirection == OptimizationDirection::Maximize ? _statesOfCoalition : ~_statesOfCoalition; | 
			
		
	
		
			
				
					|  |  |  |                     _oldPolicy = storm::storage::BitVector(_transitionMatrix.getRowCount(), false); | 
			
		
	
		
			
				
					|  |  |  |                     _timing = std::vector<double>(5, 0); | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 template <typename ValueType> | 
			
		
	
	
		
			
				
					|  |  | @ -37,6 +39,8 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  |                     //_x1.assign(_transitionMatrix.getRowGroupCount(), storm::utility::zero<ValueType>());
 | 
			
		
	
		
			
				
					|  |  |  |                     _x1L = xL; | 
			
		
	
		
			
				
					|  |  |  |                     _x2L = _x1L; | 
			
		
	
		
			
				
					|  |  |  |                     _x1Test = _x1L; | 
			
		
	
		
			
				
					|  |  |  |                     _x2Test = _x1L; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                     _x1U = xU; | 
			
		
	
		
			
				
					|  |  |  |                     _x2U = _x1U; | 
			
		
	
	
		
			
				
					|  |  | @ -65,8 +69,8 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  |                     xL = xNewL(); | 
			
		
	
		
			
				
					|  |  |  |                     xU = xNewU(); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                     STORM_LOG_DEBUG("result xL: " << xL); | 
			
		
	
		
			
				
					|  |  |  |                     STORM_LOG_DEBUG("result xU: " << xU); | 
			
		
	
		
			
				
					|  |  |  |                     // for profiling
 | 
			
		
	
		
			
				
					|  |  |  |                     STORM_PRINT(_timing[0] << ", " << _timing[1] << ", " << _timing[2] << ", " << _timing[3] << ", " << _timing[4] << std::endl); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                     if (isProduceSchedulerSet()) { | 
			
		
	
		
			
				
					|  |  |  |                         // We will be doing one more iteration step and track scheduler choices this time.
 | 
			
		
	
	
		
			
				
					|  |  | @ -79,7 +83,7 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  |                     storm::storage::BitVector reducedMinimizerActions = {storm::storage::BitVector(this->_transitionMatrix.getRowCount(), true)}; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                     // under approximation
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                     auto start = std::chrono::steady_clock::now(); | 
			
		
	
		
			
				
					|  |  |  |                     if (!_multiplier) { | 
			
		
	
		
			
				
					|  |  |  |                         prepareSolversAndMultipliers(env); | 
			
		
	
		
			
				
					|  |  |  |                     } | 
			
		
	
	
		
			
				
					|  |  | @ -89,23 +93,42 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  |                     _multiplier->multiply(env, xOldL(), nullptr, choiceValuesL); | 
			
		
	
		
			
				
					|  |  |  |                     reduceChoiceValues(choiceValuesL, &reducedMinimizerActions, xNewL()); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                     // over_approximation
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                     // just for debugging
 | 
			
		
	
		
			
				
					|  |  |  |                     _multiplier->multiplyAndReduce(env, _optimizationDirection, xOldTest(), nullptr, xNewTest(), nullptr, &_statesOfCoalition); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                     // over_approximation
 | 
			
		
	
		
			
				
					|  |  |  |                     std::vector<ValueType> choiceValuesU = std::vector<ValueType>(this->_transitionMatrix.getRowCount(), storm::utility::zero<ValueType>()); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                     _multiplier->multiply(env, xOldU(), nullptr, choiceValuesU); | 
			
		
	
		
			
				
					|  |  |  |                     reduceChoiceValues(choiceValuesU, nullptr, xNewU()); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                     auto finish = std::chrono::steady_clock::now(); | 
			
		
	
		
			
				
					|  |  |  |                     double elapsed_seconds = std::chrono::duration_cast< | 
			
		
	
		
			
				
					|  |  |  |                                                  std::chrono::duration<double>>(finish - start).count(); | 
			
		
	
		
			
				
					|  |  |  |                     _timing[0] += elapsed_seconds; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                     if (reducedMinimizerActions != _oldPolicy) { // new MECs only if Policy changed
 | 
			
		
	
		
			
				
					|  |  |  |                         start = std::chrono::steady_clock::now(); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                         // restricting the none optimal minimizer choices
 | 
			
		
	
		
			
				
					|  |  |  |                     storage::SparseMatrix<ValueType> restrictedTransMatrix = this->_transitionMatrix.restrictRows(reducedMinimizerActions); | 
			
		
	
		
			
				
					|  |  |  |                         _restrictedTransitions = this->_transitionMatrix.restrictRows(reducedMinimizerActions); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                     // STORM_LOG_DEBUG("restricted Transition: \n" << restrictedTransMatrix);
 | 
			
		
	
		
			
				
					|  |  |  |                         finish = std::chrono::steady_clock::now(); | 
			
		
	
		
			
				
					|  |  |  |                         elapsed_seconds = std::chrono::duration_cast<std::chrono::duration<double>>(finish - start).count(); | 
			
		
	
		
			
				
					|  |  |  |                         _timing[1] += elapsed_seconds; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                         // STORM_LOG_DEBUG("restricted Transition: \n" << restrictedTransMatrix);
 | 
			
		
	
		
			
				
					|  |  |  |                         start = std::chrono::steady_clock::now(); | 
			
		
	
		
			
				
					|  |  |  |                         // find_MSECs()
 | 
			
		
	
		
			
				
					|  |  |  |                     storm::storage::MaximalEndComponentDecomposition<ValueType> MSEC = storm::storage::MaximalEndComponentDecomposition<ValueType>(restrictedTransMatrix, _backwardTransitions); | 
			
		
	
		
			
				
					|  |  |  |                         _MSECs = storm::storage::MaximalEndComponentDecomposition<ValueType>(_restrictedTransitions, _restrictedTransitions.transpose(true)); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                     // STORM_LOG_DEBUG("MECD: \n" << MSEC);
 | 
			
		
	
		
			
				
					|  |  |  |                         finish = std::chrono::steady_clock::now(); | 
			
		
	
		
			
				
					|  |  |  |                         elapsed_seconds = std::chrono::duration_cast<std::chrono::duration<double>>(finish - start).count(); | 
			
		
	
		
			
				
					|  |  |  |                         _timing[2] += elapsed_seconds; | 
			
		
	
		
			
				
					|  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                     start = std::chrono::steady_clock::now(); | 
			
		
	
		
			
				
					|  |  |  |                     // reducing the choiceValuesU
 | 
			
		
	
		
			
				
					|  |  |  |                     size_t i = 0; | 
			
		
	
		
			
				
					|  |  |  |                     auto new_end = std::remove_if(choiceValuesU.begin(), choiceValuesU.end(), [&reducedMinimizerActions, &i](const auto& item) { | 
			
		
	
	
		
			
				
					|  |  | @ -114,9 +137,19 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  |                         return ret; | 
			
		
	
		
			
				
					|  |  |  |                     }); | 
			
		
	
		
			
				
					|  |  |  |                     choiceValuesU.erase(new_end, choiceValuesU.end()); | 
			
		
	
		
			
				
					|  |  |  |                     finish = std::chrono::steady_clock::now(); | 
			
		
	
		
			
				
					|  |  |  |                     elapsed_seconds = std::chrono::duration_cast< | 
			
		
	
		
			
				
					|  |  |  |                                           std::chrono::duration<double>>(finish - start).count(); | 
			
		
	
		
			
				
					|  |  |  |                     _timing[3] += elapsed_seconds; | 
			
		
	
		
			
				
					|  |  |  |                     _oldPolicy = reducedMinimizerActions; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                     // deflating the MSECs
 | 
			
		
	
		
			
				
					|  |  |  |                     deflate(MSEC, restrictedTransMatrix, xNewU(), choiceValuesU); | 
			
		
	
		
			
				
					|  |  |  |                     start = std::chrono::steady_clock::now(); | 
			
		
	
		
			
				
					|  |  |  |                     deflate(_MSECs, _restrictedTransitions, xNewU(), choiceValuesU); | 
			
		
	
		
			
				
					|  |  |  |                     finish = std::chrono::steady_clock::now(); | 
			
		
	
		
			
				
					|  |  |  |                     elapsed_seconds = std::chrono::duration_cast< | 
			
		
	
		
			
				
					|  |  |  |                                           std::chrono::duration<double>>(finish - start).count(); | 
			
		
	
		
			
				
					|  |  |  |                     _timing[4] += elapsed_seconds; | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 template <typename ValueType> | 
			
		
	
	
		
			
				
					|  |  | @ -177,8 +210,9 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  |                                     } | 
			
		
	
		
			
				
					|  |  |  |                                 } | 
			
		
	
		
			
				
					|  |  |  |                             } | 
			
		
	
		
			
				
					|  |  |  |                             else | 
			
		
	
		
			
				
					|  |  |  |                             else { | 
			
		
	
		
			
				
					|  |  |  |                                 choice_it += rowGroupSize; | 
			
		
	
		
			
				
					|  |  |  |                             } | 
			
		
	
		
			
				
					|  |  |  |                             // reducing the xNew() vector for minimizer states
 | 
			
		
	
		
			
				
					|  |  |  |                             x[state] = optChoice; | 
			
		
	
		
			
				
					|  |  |  |                         } | 
			
		
	
	
		
			
				
					|  |  | @ -201,22 +235,11 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  |                     auto x1It = xNewL().begin(); | 
			
		
	
		
			
				
					|  |  |  |                     auto x1Ite = xNewL().end(); | 
			
		
	
		
			
				
					|  |  |  |                     auto x2It = xNewU().begin(); | 
			
		
	
		
			
				
					|  |  |  |                     ValueType maxDiff = (*x2It - *x1It); | 
			
		
	
		
			
				
					|  |  |  |                     ValueType minDiff = maxDiff; | 
			
		
	
		
			
				
					|  |  |  |                     // The difference between maxDiff and minDiff is zero at this point. Thus, it doesn't make sense to check the threshold now.
 | 
			
		
	
		
			
				
					|  |  |  |                     for (++x1It, ++x2It; x1It != x1Ite; ++x1It, ++x2It) { | 
			
		
	
		
			
				
					|  |  |  |                     for (; x1It != x1Ite; x1It++, x2It++) { | 
			
		
	
		
			
				
					|  |  |  |                         ValueType diff = (*x2It - *x1It); | 
			
		
	
		
			
				
					|  |  |  |                         // Potentially update maxDiff or minDiff
 | 
			
		
	
		
			
				
					|  |  |  |                         bool skipCheck = false; | 
			
		
	
		
			
				
					|  |  |  |                         if (maxDiff < diff) { | 
			
		
	
		
			
				
					|  |  |  |                             maxDiff = diff; | 
			
		
	
		
			
				
					|  |  |  |                         } else if (minDiff > diff) { | 
			
		
	
		
			
				
					|  |  |  |                             minDiff = diff; | 
			
		
	
		
			
				
					|  |  |  |                         } else { | 
			
		
	
		
			
				
					|  |  |  |                             skipCheck = true; | 
			
		
	
		
			
				
					|  |  |  |                         } | 
			
		
	
		
			
				
					|  |  |  |                         // Check convergence
 | 
			
		
	
		
			
				
					|  |  |  |                         if (!skipCheck && (maxDiff - minDiff) > threshold) { | 
			
		
	
		
			
				
					|  |  |  |                         if (diff > threshold) { | 
			
		
	
		
			
				
					|  |  |  |                             return false; | 
			
		
	
		
			
				
					|  |  |  |                         } | 
			
		
	
		
			
				
					|  |  |  |                     } | 
			
		
	
	
		
			
				
					|  |  | @ -338,6 +361,16 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  |                     return _x1IsCurrent ? _x2U : _x1U; | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 template <typename ValueType> | 
			
		
	
		
			
				
					|  |  |  |                 std::vector<ValueType>& SoundGameViHelper<ValueType>::xOldTest() { | 
			
		
	
		
			
				
					|  |  |  |                     return _x1IsCurrent ? _x2Test : _x1Test; | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 template <typename ValueType> | 
			
		
	
		
			
				
					|  |  |  |                 std::vector<ValueType>& SoundGameViHelper<ValueType>::xNewTest() { | 
			
		
	
		
			
				
					|  |  |  |                     return _x1IsCurrent ? _x1Test : _x2Test; | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 template class SoundGameViHelper<double>; | 
			
		
	
		
			
				
					|  |  |  | #ifdef STORM_HAVE_CARL
 | 
			
		
	
		
			
				
					|  |  |  |                 template class SoundGameViHelper<storm::RationalNumber>; | 
			
		
	
	
		
			
				
					|  |  | 
 |