You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							108 lines
						
					
					
						
							6.7 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							108 lines
						
					
					
						
							6.7 KiB
						
					
					
				| #include "src/models/sparse/Mdp.h" | |
|  | |
| #include "src/exceptions/InvalidArgumentException.h" | |
| #include "src/utility/constants.h" | |
| #include "src/utility/vector.h" | |
| #include "src/adapters/CarlAdapter.h" | |
|  | |
| #include "src/models/sparse/StandardRewardModel.h" | |
|  | |
| namespace storm { | |
|     namespace models { | |
|         namespace sparse { | |
| 
 | |
|             template <typename ValueType, typename RewardModelType> | |
|             Mdp<ValueType, RewardModelType>::Mdp(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, | |
|                                 storm::models::sparse::StateLabeling const& stateLabeling, | |
|                                 std::unordered_map<std::string, RewardModelType> const& rewardModels, | |
|                                 boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling) | |
|             : NondeterministicModel<ValueType, RewardModelType>(storm::models::ModelType::Mdp, transitionMatrix, stateLabeling, rewardModels, optionalChoiceLabeling) { | |
|                 STORM_LOG_THROW(transitionMatrix.isProbabilistic(), storm::exceptions::InvalidArgumentException, "The probability matrix is invalid."); | |
|             } | |
| 
 | |
| 
 | |
|             template <typename ValueType, typename RewardModelType> | |
|             Mdp<ValueType, RewardModelType>::Mdp(storm::storage::SparseMatrix<ValueType>&& transitionMatrix, | |
|                                 storm::models::sparse::StateLabeling&& stateLabeling, | |
|                                 std::unordered_map<std::string, RewardModelType>&& rewardModels, | |
|                                 boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling) | |
|             : NondeterministicModel<ValueType, RewardModelType>(storm::models::ModelType::Mdp, std::move(transitionMatrix), std::move(stateLabeling), std::move(rewardModels), std::move(optionalChoiceLabeling)) { | |
|                 STORM_LOG_THROW(transitionMatrix.isProbabilistic(), storm::exceptions::InvalidArgumentException, "The probability matrix is invalid."); | |
|             } | |
| 
 | |
|             template <typename ValueType, typename RewardModelType> | |
|             Mdp<ValueType, RewardModelType> Mdp<ValueType, RewardModelType>::restrictChoiceLabels(LabelSet const& enabledChoiceLabels) const { | |
|                 STORM_LOG_THROW(this->hasChoiceLabeling(), storm::exceptions::InvalidArgumentException, "Restriction to label set is impossible for unlabeled model."); | |
| 
 | |
|                 std::vector<LabelSet> const& choiceLabeling = this->getChoiceLabeling(); | |
| 
 | |
|                 storm::storage::SparseMatrixBuilder<ValueType> transitionMatrixBuilder(0, this->getTransitionMatrix().getColumnCount(), 0, true, true); | |
|                 std::vector<LabelSet> newChoiceLabeling; | |
| 
 | |
|                 // Check for each choice of each state, whether the choice labels are fully contained in the given label set. | |
|                 uint_fast64_t currentRow = 0; | |
|                 for(uint_fast64_t state = 0; state < this->getNumberOfStates(); ++state) { | |
|                     bool stateHasValidChoice = false; | |
|                     for (uint_fast64_t choice = this->getTransitionMatrix().getRowGroupIndices()[state]; choice < this->getTransitionMatrix().getRowGroupIndices()[state + 1]; ++choice) { | |
|                         bool choiceValid = std::includes(enabledChoiceLabels.begin(), enabledChoiceLabels.end(), choiceLabeling[choice].begin(), choiceLabeling[choice].end()); | |
| 
 | |
|                         // If the choice is valid, copy over all its elements. | |
|                         if (choiceValid) { | |
|                             if (!stateHasValidChoice) { | |
|                                 transitionMatrixBuilder.newRowGroup(currentRow); | |
|                             } | |
|                             stateHasValidChoice = true; | |
|                             for (auto const& entry : this->getTransitionMatrix().getRow(choice)) { | |
|                                 transitionMatrixBuilder.addNextValue(currentRow, entry.getColumn(), entry.getValue()); | |
|                             } | |
|                             newChoiceLabeling.emplace_back(choiceLabeling[choice]); | |
|                             ++currentRow; | |
|                         } | |
|                     } | |
| 
 | |
|                     // If no choice of the current state may be taken, we insert a self-loop to the state instead. | |
|                     if (!stateHasValidChoice) { | |
|                         transitionMatrixBuilder.newRowGroup(currentRow); | |
|                         transitionMatrixBuilder.addNextValue(currentRow, state, storm::utility::one<ValueType>()); | |
|                         newChoiceLabeling.emplace_back(); | |
|                         ++currentRow; | |
|                     } | |
|                 } | |
| 
 | |
|                 Mdp<ValueType, RewardModelType> restrictedMdp(transitionMatrixBuilder.build(), storm::models::sparse::StateLabeling(this->getStateLabeling()), | |
|                                                               std::unordered_map<std::string, RewardModelType>(this->getRewardModels()), boost::optional<std::vector<LabelSet>>(newChoiceLabeling)); | |
| 
 | |
|                 return restrictedMdp; | |
|             } | |
| 
 | |
|             template <typename ValueType, typename RewardModelType> | |
|             Mdp<ValueType, RewardModelType> Mdp<ValueType, RewardModelType>::restrictChoices(storm::storage::BitVector const& enabledChoices) const { | |
|                 storm::storage::SparseMatrix<ValueType> restrictedTransitions = this->getTransitionMatrix().restrictRows(enabledChoices); | |
|                 std::unordered_map<std::string, RewardModelType> newRewardModels; | |
|                 for (auto const& rewardModel : this->getRewardModels()) { | |
|                     newRewardModels.emplace(rewardModel.first, rewardModel.second.restrictActions(enabledChoices)); | |
|                 } | |
|                 if(this->hasChoiceLabeling()) { | |
|                     return Mdp<ValueType, RewardModelType>(restrictedTransitions, this->getStateLabeling(), newRewardModels, boost::optional<std::vector<LabelSet>>(storm::utility::vector::filterVector(this->getChoiceLabeling(), enabledChoices))); | |
|                 } else { | |
|                     return Mdp<ValueType, RewardModelType>(restrictedTransitions, this->getStateLabeling(), newRewardModels, boost::optional<std::vector<LabelSet>>()); | |
|                 } | |
| 
 | |
| 
 | |
|             } | |
| 
 | |
|             template<typename ValueType, typename RewardModelType> | |
|             uint_least64_t Mdp<ValueType, RewardModelType>::getChoiceIndex(storm::storage::StateActionPair const& stateactPair) const { | |
|                 return this->getNondeterministicChoiceIndices()[stateactPair.getState()]+stateactPair.getAction(); | |
|             } | |
| 
 | |
|             template class Mdp<double>; | |
|             template class Mdp<float>; | |
|             template class Mdp<storm::RationalNumber>; | |
| 
 | |
|             template class Mdp<double, storm::models::sparse::StandardRewardModel<storm::Interval>>; | |
|             template class Mdp<storm::RationalFunction>; | |
| 
 | |
|         } // namespace sparse | |
|     } // namespace models | |
| } // namespace storm
 |