12template<
typename ValueType>
14 numberActionsPerObservation = std::vector<uint64_t>(pomdp.
getNrObservations(), 0);
15 statePerObservationAndOffset = std::vector<std::vector<uint64_t>>(pomdp.
getNrObservations(), std::vector<uint64_t>());
18 statePerObservationAndOffset[pomdp.
getObservation(state)].push_back(state);
19 observationOffsetId.push_back(statePerObservationAndOffset[pomdp.
getObservation(state)].size() - 1);
23template<
typename ValueType>
25 return pomdp.getObservation(state);
28template<
typename ValueType>
30 return pomdp.getNumberOfStates();
33template<
typename ValueType>
35 return numberActionsPerObservation[observation];
38template<
typename ValueType>
40 return riskPerState.at(state);
43template<
typename ValueType>
48template<
typename ValueType>
53template<
typename ValueType>
56 return beliefIdCounter;
59template<
typename ValueType>
61 STORM_LOG_ASSERT(state < observationOffsetId.size(),
"State " << state <<
" not a state id");
62 return observationOffsetId[state];
65template<
typename ValueType>
67 STORM_LOG_ASSERT(observation < observationOffsetId.size(),
"Observation " << observation <<
" not an observation id");
68 return statePerObservationAndOffset[observation].size();
71template<
typename ValueType>
73 STORM_LOG_ASSERT(obs < statePerObservationAndOffset.size(),
"Obs " << obs <<
" not a known observatoin");
74 STORM_LOG_ASSERT(offset < statePerObservationAndOffset[obs].size(),
"Offset " << offset <<
" too high for observation " << obs);
75 return statePerObservationAndOffset[obs][offset];
78template<
typename ValueType>
80 : manager(manager), belief(), id(0), prevId(0) {
81 id = manager->getFreshId();
82 belief[state] = storm::utility::one<ValueType>();
83 risk = manager->getRisk(state);
86template<
typename ValueType>
88 std::size_t hash, ValueType
const& risk, uint64_t prevId)
89 : manager(manager), belief(belief), prestoredhash(hash), risk(risk), id(0), prevId(prevId) {
90 id = manager->getFreshId();
93template<
typename ValueType>
95 return belief.at(state);
98template<
typename ValueType>
103template<
typename ValueType>
105 return prestoredhash;
108template<
typename ValueType>
110 return !belief.empty();
113template<
typename ValueType>
115 std::stringstream sstr;
116 sstr <<
"id: " <<
id <<
"; ";
118 for (
auto const& beliefentry : belief) {
124 sstr << beliefentry.first <<
" : " << beliefentry.second;
126 sstr <<
" (from " << prevId <<
")";
130template<
typename ValueType>
135 if (lhs.belief.size() != rhs.belief.size()) {
139 auto lhsIt = lhs.belief.begin();
140 auto rhsIt = rhs.belief.begin();
141 while (lhsIt != lhs.belief.end()) {
142 if (lhsIt->first != rhsIt->first || !cmp.
isEqual(lhsIt->second, rhsIt->second)) {
152template<
typename ValueType>
154 updateHelper({{}}, {storm::utility::zero<ValueType>()}, belief.begin(), newObservation, previousBeliefs);
157template<
typename ValueType>
159 return manager->getNumberOfStates();
162template<
typename ValueType>
167template<
typename ValueType>
169 for (
auto const& entry : belief) {
170 support.
set(entry.first,
true);
174template<
typename ValueType>
176 typename std::map<uint64_t, ValueType>::const_iterator nextStateIt, uint32_t newObservation,
178 if (nextStateIt == belief.end()) {
179 for (uint64_t i = 0; i < partialBeliefs.size(); ++i) {
180 auto const& partialBelief = partialBeliefs[i];
181 auto const& sum = sums[i];
185 std::size_t newHash = 0;
186 ValueType risk = storm::utility::zero<ValueType>();
187 std::map<uint64_t, ValueType> finalBelief;
188 for (
auto& entry : partialBelief) {
190 finalBelief[entry.first] = entry.second / sum;
192 boost::hash_combine(newHash, entry.first);
193 risk += entry.second / sum * manager->getRisk(entry.first);
195 previousBeliefs.insert(SparseBeliefState<ValueType>(manager, finalBelief, newHash, risk,
id));
198 uint64_t state = nextStateIt->first;
199 auto newNextStateIt = nextStateIt;
201 std::vector<std::map<uint64_t, ValueType>> newPartialBeliefs;
202 std::vector<ValueType> newSums;
203 for (uint64_t i = 0;
i < partialBeliefs.size(); ++
i) {
204 for (
auto row =
manager->getPomdp().getNondeterministicChoiceIndices()[state];
205 row <
manager->getPomdp().getNondeterministicChoiceIndices()[state + 1]; ++row) {
206 std::map<uint64_t, ValueType> newPartialBelief = partialBeliefs[
i];
208 for (
auto const& transition :
manager->getPomdp().getTransitionMatrix().getRow(row)) {
209 if (newObservation !=
manager->getPomdp().getObservation(transition.getColumn())) {
213 if (newPartialBelief.count(transition.getColumn()) == 0) {
214 newPartialBelief[transition.getColumn()] = transition.getValue() * nextStateIt->second;
216 newPartialBelief[transition.getColumn()] += transition.getValue() * nextStateIt->second;
218 newSum += transition.getValue() * nextStateIt->second;
220 newPartialBeliefs.push_back(newPartialBelief);
221 newSums.push_back(newSum);
224 updateHelper(newPartialBeliefs, newSums, newNextStateIt, newObservation, previousBeliefs);
228template<
typename ValueType>
233 if (lhs.observation != rhs.observation) {
237 auto lhsIt = lhs.belief.begin();
238 auto rhsIt = rhs.belief.begin();
239 while (lhsIt != lhs.belief.end()) {
240 if (!cmp.
isEqual(*lhsIt, *rhsIt)) {
250template<
typename ValueType>
252 : manager(manager), belief(manager->numberOfStatesPerObservation(manager->getObservation(state))) {
253 observation = manager->getObservation(state);
254 belief[manager->getObservationOffset(state)] = storm::utility::one<ValueType>();
257template<
typename ValueType>
259 std::vector<ValueType>
const& belief, std::size_t newHash, ValueType
const& risk,
261 : manager(manager), belief(belief), observation(observation), prestoredhash(newHash), risk(risk), id(manager->getFreshId()), prevId(prevId) {
265template<
typename ValueType>
267 updateHelper({{}}, {storm::utility::zero<ValueType>()}, 0, newObservation, previousBeliefs);
270template<
typename ValueType>
272 uint64_t currentEntry, uint32_t newObservation,
277 if (currentEntry == belief.size()) {
278 for (uint64_t i = 0; i < partialBeliefs.size(); ++i) {
279 auto const& partialBelief = partialBeliefs[i];
280 auto const& sum = sums[i];
284 std::size_t newHash = 0;
285 ValueType risk = storm::utility::zero<ValueType>();
286 std::vector<ValueType> finalBelief(manager->numberOfStatesPerObservation(observation), storm::utility::zero<ValueType>());
287 for (
auto& entry : partialBelief) {
289 finalBelief[manager->getObservationOffset(entry.first)] = (entry.second / sum);
291 boost::hash_combine(newHash, entry.first);
292 risk += entry.second / sum * manager->getRisk(entry.first);
294 previousBeliefs.insert(ObservationDenseBeliefState<ValueType>(manager, newObservation, finalBelief, newHash, risk,
id));
297 uint64_t state =
manager->getState(observation, currentEntry);
298 uint64_t nextEntry = currentEntry + 1;
299 std::vector<std::map<uint64_t, ValueType>> newPartialBeliefs;
300 std::vector<ValueType> newSums;
301 for (uint64_t i = 0;
i < partialBeliefs.size(); ++
i) {
302 for (
auto row =
manager->getPomdp().getNondeterministicChoiceIndices()[state];
303 row <
manager->getPomdp().getNondeterministicChoiceIndices()[state + 1]; ++row) {
304 std::map<uint64_t, ValueType> newPartialBelief = partialBeliefs[
i];
306 for (
auto const& transition :
manager->getPomdp().getTransitionMatrix().getRow(row)) {
307 if (newObservation !=
manager->getPomdp().getObservation(transition.getColumn())) {
311 if (newPartialBelief.count(transition.getColumn()) == 0) {
312 newPartialBelief[transition.getColumn()] = transition.getValue() * belief[currentEntry];
314 newPartialBelief[transition.getColumn()] += transition.getValue() * belief[currentEntry];
316 newSum += transition.getValue() * belief[currentEntry];
318 newPartialBeliefs.push_back(newPartialBelief);
319 newSums.push_back(newSum);
322 updateHelper(newPartialBeliefs, newSums, nextEntry, newObservation, previousBeliefs);
326template<
typename ValueType>
328 return prestoredhash;
331template<
typename ValueType>
333 if (manager->getObservation(state) != state) {
334 return storm::utility::zero<ValueType>();
336 return belief[manager->getObservationOffset(state)];
339template<
typename ValueType>
344template<
typename ValueType>
346 return belief.size();
349template<
typename ValueType>
354template<
typename ValueType>
356 std::stringstream sstr;
357 sstr <<
"id: " <<
id <<
"; ";
360 for (
auto const& beliefentry : belief) {
368 sstr << manager->getState(observation, i) <<
" : " << beliefentry;
372 sstr <<
" (from " << prevId <<
")";
376template<
typename ValueType,
typename BeliefState>
379 : pomdp(pomdp), manager(
std::make_shared<
BeliefStateManager<ValueType>>(pomdp)), beliefs(), options(options) {
383template<
typename ValueType,
typename BeliefState>
386 for (
auto state : pomdp.getInitialStates()) {
387 if (observation == pomdp.getObservation(state)) {
389 beliefs.emplace(manager, state);
392 lastObservation = observation;
396template<
typename ValueType,
typename BeliefState>
398 STORM_LOG_THROW(!beliefs.empty(), storm::exceptions::InvalidOperationException,
"Cannot track without a belief (need to reset).");
399 std::unordered_set<BeliefState> newBeliefs;
401 for (
auto const& belief : beliefs) {
402 belief.update(newObservation, newBeliefs);
403 if (options.trackTimeOut > 0 &&
static_cast<uint64_t
>(trackTimer.
getTimeInMilliseconds()) > options.trackTimeOut) {
407 beliefs = newBeliefs;
408 lastObservation = newObservation;
409 return !beliefs.empty();
412template<
typename ValueType,
typename BeliefState>
414 STORM_LOG_THROW(!beliefs.empty(), storm::exceptions::InvalidOperationException,
"Risk is only defined for beliefs (run reset() first).");
415 ValueType result = beliefs.begin()->getRisk();
417 for (
auto const& belief : beliefs) {
418 if (belief.getRisk() > result) {
419 result = belief.getRisk();
423 for (
auto const& belief : beliefs) {
424 if (belief.getRisk() < result) {
425 result = belief.getRisk();
432template<
typename ValueType,
typename BeliefState>
434 manager->setRiskPerState(risk);
437template<
typename ValueType,
typename BeliefState>
442template<
typename ValueType,
typename BeliefState>
444 return lastObservation;
447template<
typename ValueType,
typename BeliefState>
449 return beliefs.size();
452template<
typename ValueType,
typename BeliefState>
455 for (
auto const& belief : beliefs) {
456 belief.setSupport(support);
462template<
typename ValueType,
typename BeliefState>
464 reductionTimedOut =
false;
465 std::shared_ptr<storm::utility::solver::SmtSolverFactory> solverFactory = std::make_shared<storm::utility::solver::Z3SmtSolverFactory>();
467 std::vector<std::map<uint64_t, ValueType>> points;
468 std::vector<typename std::unordered_set<BeliefState>::iterator> iterators;
469 for (
auto it = beliefs.begin(); it != beliefs.end(); ++it) {
471 points.push_back(it->getBeliefMap());
472 iterators.push_back(it);
474 auto res = rvc.
eliminate(points, pomdp.getNumberOfStates());
477 reductionTimedOut =
true;
481 for (
auto iter : selectedIterators) {
487template<
typename ValueType,
typename BeliefState>
489 return reductionTimedOut;
This class keeps track of common information of a set of beliefs.
uint64_t getObservationOffset(uint64_t state) const
BeliefStateManager(storm::models::sparse::Pomdp< ValueType > const &pomdp)
uint64_t getNumberOfStates() const
ValueType getRisk(uint64_t) const
storm::models::sparse::Pomdp< ValueType > const & getPomdp() const
uint64_t getState(uint32_t obs, uint64_t offset) const
uint64_t numberOfStatesPerObservation(uint32_t observation) const
uint32_t getObservation(uint64_t state) const
void setRiskPerState(std::vector< ValueType > const &risk)
uint64_t getActionsForObservation(uint32_t observation) const
This tracker implements state estimation for POMDPs.
std::unordered_set< BeliefState > const & getCurrentBeliefs() const
Provides access to the current beliefs.
NondeterministicBeliefTracker(storm::models::sparse::Pomdp< ValueType > const &pomdp, typename NondeterministicBeliefTracker< ValueType, BeliefState >::Options options=Options())
uint64_t reduce()
Apply reductions to the belief state.
ValueType getCurrentRisk(bool max=true)
What is the (worst-case/best-case) risk over all beliefs.
void setRisk(std::vector< ValueType > const &risk)
Sets the state-risk to use for all beliefs.
uint64_t getCurrentDimension() const
What is the dimension of the current set of beliefs, i.e., what is the number of states we could poss...
uint32_t getCurrentObservation() const
What was the last obervation that we made?
bool hasTimedOut() const
Did we time out during the computation?
bool reset(uint32_t observation)
Start with a new trace.
uint64_t getNumberOfBeliefs() const
How many beliefs are we currently tracking?
bool track(uint64_t newObservation)
Extend the observed trace with the new observation.
ObservationDenseBeliefState stores beliefs in a dense format (per observation).
ValueType getRisk() const
ObservationDenseBeliefState(std::shared_ptr< BeliefStateManager< ValueType > > const &manager, uint64_t state)
ValueType get(uint64_t state) const
void setSupport(storm::storage::BitVector &) const
std::string toString() const
uint64_t getSupportSize() const
std::size_t hash() const noexcept
void update(uint32_t newObservation, std::unordered_set< ObservationDenseBeliefState > &previousBeliefs) const
SparseBeliefState stores beliefs in a sparse format.
void setSupport(storm::storage::BitVector &) const
void update(uint32_t newObservation, std::unordered_set< SparseBeliefState > &previousBeliefs) const
Update the belief using the new observation.
std::string toString() const
std::map< uint64_t, ValueType > const & getBeliefMap() const
ValueType get(uint64_t state) const
Get the estimate to be in the given state.
std::size_t hash() const noexcept
uint64_t getSupportSize() const
ValueType getRisk() const
Get the weighted risk.
SparseBeliefState(std::shared_ptr< BeliefStateManager< ValueType > > const &manager, uint64_t state)
virtual uint_fast64_t getNumberOfStates() const override
Returns the number of states of the model.
uint_fast64_t getNumberOfChoices(uint_fast64_t state) const
This class represents a partially observable Markov decision process.
uint64_t getNrObservations() const
uint32_t getObservation(uint64_t state) const
A bit vector that is internally represented as a vector of 64-bit values.
void set(uint_fast64_t index, bool value=true)
Sets the given truth value at the given index.
uint_fast64_t getNumberOfSetBits() const
Returns the number of bits that are set to true in this bit vector.
std::pair< storm::storage::BitVector, bool > eliminate(std::vector< std::map< uint64_t, ValueType > > const &input, uint64_t maxdimension)
bool isEqual(ValueType const &value1, ValueType const &value2) const
A class that provides convenience operations to display run times.
MilisecondType getTimeInMilliseconds() const
Gets the measured time in milliseconds.
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
SFTBDDChecker::ValueType ValueType
bool operator==(SparseBeliefState< ValueType > const &lhs, SparseBeliefState< ValueType > const &rhs)
SettingsManager const & manager()
Retrieves the settings manager.
void setNonzeroIndices(std::vector< T > const &vec, storm::storage::BitVector &bv)
std::vector< Type > filterVector(std::vector< Type > const &in, storm::storage::BitVector const &filter)
bool isZero(ValueType const &a)