Stefan Pranger
4 years ago
2 changed files with 154 additions and 0 deletions
@ -0,0 +1,112 @@ |
|||||
|
#include "storm/utility/vector.h"
|
||||
|
#include "storm/storage/OptimalScheduler.h"
|
||||
|
|
||||
|
#include "storm/utility/macros.h"
|
||||
|
#include "storm/exceptions/NotImplementedException.h"
|
||||
|
#include <boost/algorithm/string/join.hpp>
|
||||
|
|
||||
|
namespace storm { |
||||
|
namespace storage { |
||||
|
template <typename ValueType> |
||||
|
OptimalScheduler<ValueType>::OptimalScheduler(uint_fast64_t numberOfModelStates, boost::optional<storm::storage::MemoryStructure> const& memoryStructure) : Scheduler<ValueType>(numberOfModelStates, memoryStructure) { |
||||
|
} |
||||
|
|
||||
|
template <typename ValueType> |
||||
|
OptimalScheduler<ValueType>::OptimalScheduler(uint_fast64_t numberOfModelStates, boost::optional<storm::storage::MemoryStructure>&& memoryStructure) : Scheduler<ValueType>(numberOfModelStates, std::move(memoryStructure)) { |
||||
|
} |
||||
|
|
||||
|
template <typename ValueType> |
||||
|
void OptimalScheduler<ValueType>::printToStream(std::ostream& out, std::shared_ptr<storm::logic::ShieldExpression const> shieldingExpression, std::shared_ptr<storm::models::sparse::Model<ValueType>> model, bool skipUniqueChoices) const { |
||||
|
STORM_LOG_THROW(model == nullptr || model->getNumberOfStates() == this->schedulerChoices.front().size(), storm::exceptions::InvalidOperationException, "The given model is not compatible with this scheduler."); |
||||
|
STORM_LOG_THROW(this->isMemorylessScheduler(), storm::exceptions::InvalidOperationException, "The given scheduler is incompatible."); |
||||
|
|
||||
|
bool const stateValuationsGiven = model != nullptr && model->hasStateValuations(); |
||||
|
bool const choiceLabelsGiven = model != nullptr && model->hasChoiceLabeling(); |
||||
|
bool const choiceOriginsGiven = model != nullptr && model->hasChoiceOrigins(); |
||||
|
uint_fast64_t widthOfStates = std::to_string(this->schedulerChoices.front().size()).length(); |
||||
|
if (stateValuationsGiven) { |
||||
|
widthOfStates += model->getStateValuations().getStateInfo(this->schedulerChoices.front().size() - 1).length() + 5; |
||||
|
} |
||||
|
widthOfStates = std::max(widthOfStates, (uint_fast64_t)12); |
||||
|
uint_fast64_t numOfSkippedStatesWithUniqueChoice = 0; |
||||
|
|
||||
|
out << "___________________________________________________________________" << std::endl; |
||||
|
out << shieldingExpression->prettify() << std::endl; |
||||
|
STORM_LOG_WARN_COND(!(skipUniqueChoices && model == nullptr), "Can not skip unique choices if the model is not given."); |
||||
|
out << std::setw(widthOfStates) << "model state:" << " " << "choice"; |
||||
|
if(choiceLabelsGiven) { |
||||
|
out << " [<value>: (<action {action label})>]"; |
||||
|
} else { |
||||
|
out << " [<value>: (<action>)}"; |
||||
|
} |
||||
|
out << ":" << std::endl; |
||||
|
for (uint_fast64_t state = 0; state < this->schedulerChoices.front().size(); ++state) { |
||||
|
std::stringstream stateString; |
||||
|
// Check whether the state is skipped
|
||||
|
if (skipUniqueChoices && model != nullptr && model->getTransitionMatrix().getRowGroupSize(state) == 1) { |
||||
|
++numOfSkippedStatesWithUniqueChoice; |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
// Print the state info
|
||||
|
if (stateValuationsGiven) { |
||||
|
stateString << std::setw(widthOfStates) << (std::to_string(state) + ": " + model->getStateValuations().getStateInfo(state)); |
||||
|
} else { |
||||
|
stateString << std::setw(widthOfStates) << state; |
||||
|
} |
||||
|
stateString << " "; |
||||
|
|
||||
|
bool firstMemoryState = true; |
||||
|
for (uint_fast64_t memoryState = 0; memoryState < this->getNumberOfMemoryStates(); ++memoryState) { |
||||
|
// Indent if this is not the first memory state
|
||||
|
if (firstMemoryState) { |
||||
|
firstMemoryState = false; |
||||
|
} else { |
||||
|
stateString << std::setw(widthOfStates) << ""; |
||||
|
stateString << " "; |
||||
|
} |
||||
|
|
||||
|
// Print choice info
|
||||
|
SchedulerChoice<ValueType> const& choice = this->schedulerChoices[memoryState][state]; |
||||
|
if (choice.isDefined()) { |
||||
|
bool firstChoice = true; |
||||
|
for (auto const& choiceProbPair : choice.getChoiceAsDistribution()) { |
||||
|
if (firstChoice) { |
||||
|
firstChoice = false; |
||||
|
} else { |
||||
|
stateString << "; "; |
||||
|
} |
||||
|
stateString << choiceProbPair.second << ": ("; |
||||
|
if (choiceOriginsGiven) { |
||||
|
stateString << model->getChoiceOrigins()->getChoiceInfo(model->getTransitionMatrix().getRowGroupIndices()[state] + choiceProbPair.first); |
||||
|
} else { |
||||
|
stateString << choiceProbPair.first; |
||||
|
} |
||||
|
if (choiceLabelsGiven) { |
||||
|
auto choiceLabels = model->getChoiceLabeling().getLabelsOfChoice(model->getTransitionMatrix().getRowGroupIndices()[state] + choiceProbPair.first); |
||||
|
stateString << " {" << boost::join(choiceLabels, ", ") << "}"; |
||||
|
} |
||||
|
stateString << ")"; |
||||
|
} |
||||
|
} else { |
||||
|
if(!this->printUndefinedChoices) continue; |
||||
|
stateString << "undefined."; |
||||
|
} |
||||
|
|
||||
|
// Todo: print memory updates
|
||||
|
out << stateString.str(); |
||||
|
out << std::endl; |
||||
|
} |
||||
|
} |
||||
|
if (numOfSkippedStatesWithUniqueChoice > 0) { |
||||
|
out << "Skipped " << numOfSkippedStatesWithUniqueChoice << " deterministic states with unique choice." << std::endl; |
||||
|
} |
||||
|
out << "___________________________________________________________________" << std::endl; |
||||
|
} |
||||
|
|
||||
|
template class OptimalScheduler<double>; |
||||
|
#ifdef STORM_HAVE_CARL
|
||||
|
template class OptimalScheduler<storm::RationalNumber>; |
||||
|
#endif
|
||||
|
} |
||||
|
} |
@ -0,0 +1,42 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
#include <cstdint> |
||||
|
#include <map> |
||||
|
#include <memory> |
||||
|
#include "storm/storage/SchedulerChoice.h" |
||||
|
#include "storm/storage/Scheduler.h" |
||||
|
#include "storm/logic/ShieldExpression.h" |
||||
|
|
||||
|
namespace storm { |
||||
|
namespace storage { |
||||
|
|
||||
|
/* |
||||
|
* TODO needs obvious changes in all comment blocks |
||||
|
* This class defines which action is chosen in a particular state of a non-deterministic model. More concretely, a scheduler maps a state s to i |
||||
|
* if the scheduler takes the i-th action available in s (i.e. the choices are relative to the states). |
||||
|
* A Choice can be undefined, deterministic |
||||
|
*/ |
||||
|
template <typename ValueType> |
||||
|
class OptimalScheduler : public Scheduler<ValueType> { |
||||
|
public: |
||||
|
typedef uint_fast64_t OldChoice; |
||||
|
/*! |
||||
|
* Initializes a scheduler for the given number of model states. |
||||
|
* |
||||
|
* @param numberOfModelStates number of model states |
||||
|
* @param memoryStructure the considered memory structure. If not given, the scheduler is considered as memoryless. |
||||
|
*/ |
||||
|
OptimalScheduler(uint_fast64_t numberOfModelStates, boost::optional<storm::storage::MemoryStructure> const& memoryStructure = boost::none); |
||||
|
OptimalScheduler(uint_fast64_t numberOfModelStates, boost::optional<storm::storage::MemoryStructure>&& memoryStructure); |
||||
|
|
||||
|
/*! |
||||
|
* Prints the scheduler to the given output stream. |
||||
|
* @param out The output stream |
||||
|
* @param model If given, provides additional information for printing (e.g., displaying the state valuations instead of state indices) |
||||
|
* @param skipUniqueChoices If true, the (unique) choice for deterministic states (i.e., states with only one enabled choice) is not printed explicitly. |
||||
|
* Requires a model to be given. |
||||
|
*/ |
||||
|
void printToStream(std::ostream& out, std::shared_ptr<storm::logic::ShieldExpression const> shieldingExpression, std::shared_ptr<storm::models::sparse::Model<ValueType>> model = nullptr, bool skipUniqueChoices = false) const; |
||||
|
}; |
||||
|
} |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue