13template<
typename ValueType>
15 numberActionsPerObservation = std::vector<uint64_t>(pomdp.getNrObservations(), 0);
16 statePerObservationAndOffset = std::vector<std::vector<uint64_t>>(pomdp.getNrObservations(), std::vector<uint64_t>());
17 for (uint64_t state = 0; state < pomdp.getNumberOfStates(); ++state) {
18 numberActionsPerObservation[pomdp.getObservation(state)] = pomdp.getNumberOfChoices(state);
19 statePerObservationAndOffset[pomdp.getObservation(state)].push_back(state);
20 observationOffsetId.push_back(statePerObservationAndOffset[pomdp.getObservation(state)].size() - 1);
24template<
typename ValueType>
26 return pomdp.getObservation(state);
29template<
typename ValueType>
31 return pomdp.getNumberOfStates();
34template<
typename ValueType>
36 return numberActionsPerObservation[observation];
39template<
typename ValueType>
41 return riskPerState.at(state);
44template<
typename ValueType>
49template<
typename ValueType>
54template<
typename ValueType>
57 return beliefIdCounter;
60template<
typename ValueType>
62 STORM_LOG_ASSERT(state < observationOffsetId.size(),
"State " << state <<
" not a state id");
63 return observationOffsetId[state];
66template<
typename ValueType>
68 STORM_LOG_ASSERT(observation < observationOffsetId.size(),
"Observation " << observation <<
" not an observation id");
69 return statePerObservationAndOffset[observation].size();
72template<
typename ValueType>
74 STORM_LOG_ASSERT(obs < statePerObservationAndOffset.size(),
"Obs " << obs <<
" not a known observatoin");
75 STORM_LOG_ASSERT(offset < statePerObservationAndOffset[obs].size(),
"Offset " << offset <<
" too high for observation " << obs);
76 return statePerObservationAndOffset[obs][offset];
79template<
typename ValueType>
81 : manager(manager), belief(), id(0), prevId(0) {
82 id = manager->getFreshId();
84 risk = manager->getRisk(state);
87template<
typename ValueType>
89 std::size_t hash, ValueType
const& risk, uint64_t prevId)
90 : manager(manager), belief(belief), prestoredhash(hash), risk(risk), id(0), prevId(prevId) {
91 id = manager->getFreshId();
94template<
typename ValueType>
96 return belief.at(state);
99template<
typename ValueType>
104template<
typename ValueType>
106 return prestoredhash;
109template<
typename ValueType>
111 return !belief.empty();
114template<
typename ValueType>
116 std::stringstream sstr;
117 sstr <<
"id: " <<
id <<
"; ";
119 for (
auto const& beliefentry : belief) {
125 sstr << beliefentry.first <<
" : " << beliefentry.second;
127 sstr <<
" (from " << prevId <<
")";
131template<
typename ValueType>
136 if (lhs.belief.size() != rhs.belief.size()) {
140 auto lhsIt = lhs.belief.begin();
141 auto rhsIt = rhs.belief.begin();
142 while (lhsIt != lhs.belief.end()) {
143 if (lhsIt->first != rhsIt->first || !cmp.
isEqual(lhsIt->second, rhsIt->second)) {
153template<
typename ValueType>
158template<
typename ValueType>
160 return manager->getNumberOfStates();
163template<
typename ValueType>
168template<
typename ValueType>
170 for (
auto const& entry : belief) {
171 support.
set(entry.first,
true);
175template<
typename ValueType>
176void SparseBeliefState<ValueType>::updateHelper(std::vector<std::map<uint64_t, ValueType>>
const& partialBeliefs, std::vector<ValueType>
const& sums,
177 typename std::map<uint64_t, ValueType>::const_iterator nextStateIt, uint32_t newObservation,
179 if (nextStateIt == belief.end()) {
180 for (uint64_t i = 0; i < partialBeliefs.size(); ++i) {
181 auto const& partialBelief = partialBeliefs[i];
182 auto const& sum = sums[i];
186 std::size_t newHash = 0;
188 std::map<uint64_t, ValueType> finalBelief;
189 for (
auto& entry : partialBelief) {
191 finalBelief[entry.first] = entry.second / sum;
193 boost::hash_combine(newHash, entry.first);
194 risk += entry.second / sum * manager->getRisk(entry.first);
196 previousBeliefs.insert(SparseBeliefState<ValueType>(manager, finalBelief, newHash, risk,
id));
199 uint64_t state = nextStateIt->first;
200 auto newNextStateIt = nextStateIt;
202 std::vector<std::map<uint64_t, ValueType>> newPartialBeliefs;
203 std::vector<ValueType> newSums;
204 for (uint64_t i = 0;
i < partialBeliefs.size(); ++
i) {
205 for (
auto row =
manager->getPomdp().getNondeterministicChoiceIndices()[state];
206 row < manager->getPomdp().getNondeterministicChoiceIndices()[state + 1]; ++row) {
207 std::map<uint64_t, ValueType> newPartialBelief = partialBeliefs[
i];
209 for (
auto const& transition :
manager->getPomdp().getTransitionMatrix().getRow(row)) {
210 if (newObservation !=
manager->getPomdp().getObservation(transition.getColumn())) {
214 if (newPartialBelief.count(transition.getColumn()) == 0) {
215 newPartialBelief[transition.getColumn()] = transition.getValue() * nextStateIt->second;
217 newPartialBelief[transition.getColumn()] += transition.getValue() * nextStateIt->second;
219 newSum += transition.getValue() * nextStateIt->second;
221 newPartialBeliefs.push_back(newPartialBelief);
222 newSums.push_back(newSum);
225 updateHelper(newPartialBeliefs, newSums, newNextStateIt, newObservation, previousBeliefs);
229template<
typename ValueType,
typename BeliefState>
232 : pomdp(pomdp), manager(
std::make_shared<
BeliefStateManager<ValueType>>(pomdp)), beliefs(), options(options) {
236template<
typename ValueType,
typename BeliefState>
238 beliefs = std::unordered_set<BeliefState>();
240 for (
auto state : pomdp.getInitialStates()) {
241 if (observation == pomdp.getObservation(state)) {
243 beliefs.emplace(manager, state);
246 lastObservation = observation;
250template<
typename ValueType,
typename BeliefState>
252 STORM_LOG_THROW(!beliefs.empty(), storm::exceptions::InvalidOperationException,
"Cannot track without a belief (need to reset).");
253 std::unordered_set<BeliefState> newBeliefs;
255 for (
auto const& belief : beliefs) {
256 belief.update(newObservation, newBeliefs);
257 if (options.trackTimeOut > 0 &&
static_cast<uint64_t
>(trackTimer.
getTimeInMilliseconds()) > options.trackTimeOut) {
261 beliefs = newBeliefs;
262 lastObservation = newObservation;
263 return !beliefs.empty();
266template<
typename ValueType,
typename BeliefState>
268 STORM_LOG_THROW(!beliefs.empty(), storm::exceptions::InvalidOperationException,
"Risk is only defined for beliefs (run reset() first).");
269 ValueType result = beliefs.begin()->getRisk();
271 for (
auto const& belief : beliefs) {
272 if (belief.getRisk() > result) {
273 result = belief.getRisk();
277 for (
auto const& belief : beliefs) {
278 if (belief.getRisk() < result) {
279 result = belief.getRisk();
286template<
typename ValueType,
typename BeliefState>
288 manager->setRiskPerState(risk);
291template<
typename ValueType,
typename BeliefState>
296template<
typename ValueType,
typename BeliefState>
298 return lastObservation;
301template<
typename ValueType,
typename BeliefState>
303 return beliefs.size();
306template<
typename ValueType,
typename BeliefState>
309 for (
auto const& belief : beliefs) {
310 belief.setSupport(support);
316template<
typename ValueType,
typename BeliefState>
318 reductionTimedOut =
false;
319 std::shared_ptr<storm::utility::solver::SmtSolverFactory> solverFactory = std::make_shared<storm::utility::solver::Z3SmtSolverFactory>();
321 std::vector<std::map<uint64_t, ValueType>> points;
322 std::vector<typename std::unordered_set<BeliefState>::iterator> iterators;
323 for (
auto it = beliefs.begin(); it != beliefs.end(); ++it) {
325 points.push_back(it->getBeliefMap());
326 iterators.push_back(it);
328 auto res = rvc.
eliminate(points, pomdp.getNumberOfStates());
331 reductionTimedOut =
true;
335 for (
auto iter : selectedIterators) {
341template<
typename ValueType,
typename BeliefState>
343 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.
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)
This class represents a partially observable Markov decision process.
A bit vector that is internally represented as a vector of 64-bit values.
uint64_t getNumberOfSetBits() const
Returns the number of bits that are set to true in this bit vector.
void set(uint64_t index, bool value=true)
Sets the given truth value at the given index.
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.
std::vector< Type > filterVector(std::vector< Type > const &in, storm::storage::BitVector const &filter)
bool isZero(ValueType const &a)
TargetType convertNumber(SourceType const &number)