13template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
18template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
20 : dimension(dimension), diff(
std::move(diff)) {
24template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
26 if (diff != other.diff) {
27 return diff > other.diff;
29 return dimension < other.dimension;
33template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
34bool BeliefManager<PomdpType, BeliefValueType, StateType>::Belief_equal_to::operator()(
const BeliefType &lhBelief,
const BeliefType &rhBelief)
const {
35 return lhBelief == rhBelief;
39bool BeliefManager<storm::models::sparse::Pomdp<double>, double, uint64_t>::Belief_equal_to::operator()(
const BeliefType &lhBelief,
42 if (lhBelief.size() != rhBelief.size()) {
46 auto lhIt = lhBelief.begin();
47 auto rhIt = rhBelief.begin();
48 while (lhIt != lhBelief.end() || rhIt != rhBelief.end()) {
50 if (lhIt->first != rhIt->first || std::fabs(lhIt->second - rhIt->second) > 1e-15) {
56 return lhIt == lhBelief.end() && rhIt == rhBelief.end();
59template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
60std::size_t BeliefManager<PomdpType, BeliefValueType, StateType>::BeliefHash::operator()(
const BeliefType &belief)
const {
63 for (
auto const &entry : belief) {
64 boost::hash_combine(seed, entry.first);
65 boost::hash_combine(seed, entry.second);
71std::size_t BeliefManager<storm::models::sparse::Pomdp<double>, double, uint64_t>::BeliefHash::operator()(
const BeliefType &belief)
const {
74 for (
auto const &entry : belief) {
75 boost::hash_combine(seed, entry.first);
76 boost::hash_combine(seed,
round(storm::utility::convertNumber<double>(entry.second) * 1e15));
81template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
84 : pomdp(pomdp), triangulationMode(triangulationMode) {
86 beliefToIdMap.resize(pomdp.getNrObservations());
87 initialBeliefId = computeInitialBelief();
90template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
92 if (rewardModelName) {
93 auto const &rewardModel = pomdp.getRewardModel(rewardModelName.value());
94 pomdpActionRewardVector = rewardModel.getTotalRewardVector(pomdp.getTransitionMatrix());
96 setRewardModel(pomdp.getUniqueRewardModelName());
100template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
102 pomdpActionRewardVector.clear();
105template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
107 return std::numeric_limits<BeliefId>::max();
110template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
112 return isEqual(getBelief(first), getBelief(second));
115template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
117 return toString(getBelief(beliefId));
120template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
122 std::stringstream str;
124 for (uint64_t
i = 0;
i < t.
size(); ++
i) {
131template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
133 BeliefId const &beliefId, std::vector<ValueType>
const &summands) {
134 auto result = storm::utility::zero<ValueType>();
135 for (
auto const &entry : getBelief(beliefId)) {
136 result += storm::utility::convertNumber<ValueType>(entry.second) * storm::utility::convertNumber<ValueType>(summands.at(entry.first));
141template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
143 BeliefId const &beliefId, std::unordered_map<StateType, ValueType>
const &summands) {
144 bool successful =
true;
145 auto result = storm::utility::zero<ValueType>();
146 for (
auto const &entry : getBelief(beliefId)) {
147 auto probIter = summands.find(entry.first);
148 if (probIter != summands.end()) {
149 result += storm::utility::convertNumber<ValueType>(entry.second) * storm::utility::convertNumber<ValueType>(summands.at(entry.first));
155 return {successful, result};
158template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
160 return initialBeliefId;
163template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
165 BeliefId const &beliefId, uint64_t
const &localActionIndex)
const {
166 auto const &belief = getBelief(beliefId);
167 STORM_LOG_ASSERT(!pomdpActionRewardVector.empty(),
"Requested a reward although no reward model was specified.");
168 auto result = storm::utility::zero<ValueType>();
169 auto const &choiceIndices = pomdp.getTransitionMatrix().getRowGroupIndices();
170 for (
auto const &entry : belief) {
171 uint64_t choiceIndex = choiceIndices[entry.first] + localActionIndex;
172 STORM_LOG_ASSERT(choiceIndex < choiceIndices[entry.first + 1],
"Invalid local action index.");
173 STORM_LOG_ASSERT(choiceIndex < pomdpActionRewardVector.size(),
"Invalid choice index.");
174 result += storm::utility::convertNumber<ValueType>(entry.second) * pomdpActionRewardVector[choiceIndex];
179template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
181 return getBeliefObservation(getBelief(beliefId));
184template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
186 auto const &belief = getBelief(beliefId);
187 return pomdp.getNumberOfChoices(belief.begin()->first);
190template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
192 BeliefId beliefId, BeliefValueType resolution) {
193 return triangulateBelief(getBelief(beliefId), resolution);
196template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
197template<
typename DistributionType>
199 auto insertionRes = distr.emplace(state, value);
200 if (!insertionRes.second) {
201 insertionRes.first->second += value;
205template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
206template<
typename DistributionType>
208 if (distr.size() == 1 && cc.isEqual(distr.begin()->second, storm::utility::one<BeliefValueType>())) {
210 distr.begin()->second = storm::utility::one<BeliefValueType>();
214template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
216 auto const &belief = getBelief(beliefId);
217 for (
auto const &entry : belief) {
218 support.insert(entry.first);
222template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
224 return beliefs.size();
227template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
228std::vector<std::pair<typename BeliefManager<PomdpType, BeliefValueType, StateType>::BeliefId,
231 std::vector<BeliefValueType>
const &observationResolutions) {
232 return expandInternal(beliefId, actionIndex, observationResolutions);
235template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
236std::vector<std::pair<typename BeliefManager<PomdpType, BeliefValueType, StateType>::BeliefId,
239 std::vector<uint64_t>
const &observationResolutions) {
240 return expandInternal(beliefId, actionIndex, std::nullopt, observationResolutions);
243template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
244std::vector<std::pair<typename BeliefManager<PomdpType, BeliefValueType, StateType>::BeliefId,
247 return expandInternal(beliefId, actionIndex);
250template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
252 BeliefId
const &
id)
const {
254 STORM_LOG_ASSERT(
id < getNumberOfBeliefIds(),
"Belief index " <<
id <<
" is out of range.");
258template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
260 BeliefType
const &belief)
const {
261 uint32_t obs = getBeliefObservation(belief);
262 STORM_LOG_ASSERT(obs < beliefToIdMap.size(),
"Belief has unknown observation.");
263 auto idIt = beliefToIdMap[obs].find(belief);
268template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
270 std::stringstream str;
273 for (
auto const &entry : belief) {
279 str << entry.first <<
": " << std::setprecision(std::numeric_limits<double>::max_digits10 + 1) << entry.second;
285template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
287 if (first.size() != second.size()) {
290 auto secondIt = second.begin();
291 for (
auto const &firstEntry : first) {
292 if (firstEntry.first != secondIt->first) {
295 if (!cc.isEqual(firstEntry.second, secondIt->second)) {
303template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
304bool BeliefManager<PomdpType, BeliefValueType, StateType>::assertBelief(BeliefType
const &belief)
const {
305 auto sum = storm::utility::zero<BeliefValueType>();
306 std::optional<uint32_t> observation;
307 for (
auto const &entry : belief) {
308 if (entry.first >= pomdp.getNumberOfStates()) {
309 STORM_LOG_ERROR(
"Belief does refer to non-existing pomdp state " << entry.first <<
".");
312 uint64_t entryObservation = pomdp.getObservation(entry.first);
314 if (observation.value() != entryObservation) {
319 observation = entryObservation;
327 if (entry.second < storm::utility::zero<BeliefValueType>()) {
331 if (cc.isLess(storm::utility::one<BeliefValueType>(), entry.second)) {
337 if (!cc.isOne(sum)) {
338 STORM_LOG_ERROR(
"Belief does not sum up to one. (" << sum <<
" instead).");
344template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
345bool BeliefManager<PomdpType, BeliefValueType, StateType>::assertTriangulation(BeliefType
const &belief, Triangulation
const &triangulation)
const {
346 if (triangulation.weights.size() != triangulation.gridPoints.size()) {
347 STORM_LOG_ERROR(
"Number of weights and points in triangulation does not match.");
350 if (triangulation.size() == 0) {
354 BeliefType triangulatedBelief;
355 auto weightSum = storm::utility::zero<BeliefValueType>();
356 for (uint64_t
i = 0;
i < triangulation.weights.size(); ++
i) {
357 if (cc.isZero(triangulation.weights[
i])) {
361 if (cc.isLess(triangulation.weights[
i], storm::utility::zero<BeliefValueType>())) {
365 if (cc.isLess(storm::utility::one<BeliefValueType>(), triangulation.weights[
i])) {
368 weightSum += triangulation.weights[
i];
369 BeliefType
const &gridPoint = getBelief(triangulation.gridPoints[
i]);
370 for (
auto const &pointEntry : gridPoint) {
371 BeliefValueType &triangulatedValue = triangulatedBelief.emplace(pointEntry.first, storm::utility::zero<BeliefValueType>()).first->second;
372 triangulatedValue += triangulation.weights[
i] * pointEntry.second;
375 if (!cc.isOne(weightSum)) {
379 if (!assertBelief(triangulatedBelief)) {
382 if (!isEqual(belief, triangulatedBelief)) {
389template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
392 return pomdp.getObservation(belief.begin()->first);
395template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
396void BeliefManager<PomdpType, BeliefValueType, StateType>::triangulateBeliefFreudenthal(BeliefType
const &belief, BeliefValueType
const &resolution,
397 Triangulation &result) {
400 StateType numEntries = belief.size();
406 std::set<FreudenthalDiff, std::greater<>> sorted_diffs;
407 std::vector<BeliefValueType> qsRow;
408 qsRow.reserve(numEntries);
409 std::vector<StateType> toOriginalIndicesMap;
410 toOriginalIndicesMap.reserve(numEntries);
411 BeliefValueType x = resolution;
412 for (
auto const &entry : belief) {
414 sorted_diffs.emplace(toOriginalIndicesMap.size(), x - qsRow.back());
415 toOriginalIndicesMap.push_back(entry.first);
416 x -= entry.second * resolution;
419 qsRow.push_back(storm::utility::zero<BeliefValueType>());
421 result.weights.reserve(numEntries);
422 result.gridPoints.reserve(numEntries);
423 auto currentSortedDiff = sorted_diffs.begin();
424 auto previousSortedDiff = sorted_diffs.end();
425 --previousSortedDiff;
426 for (StateType
i = 0;
i < numEntries; ++
i) {
428 BeliefValueType weight = previousSortedDiff->diff - currentSortedDiff->diff;
431 weight += storm::utility::one<BeliefValueType>();
434 qsRow[previousSortedDiff->dimension] += storm::utility::one<BeliefValueType>();
436 if (!cc.isZero(weight)) {
437 result.weights.push_back(weight);
439 BeliefType gridPoint;
440 for (StateType j = 0; j < numEntries; ++j) {
441 BeliefValueType gridPointEntry = qsRow[j] - qsRow[j + 1];
442 if (!cc.isZero(gridPointEntry)) {
443 gridPoint[toOriginalIndicesMap[j]] = gridPointEntry / resolution;
446 result.gridPoints.push_back(getOrAddBeliefId(gridPoint));
448 previousSortedDiff = currentSortedDiff++;
452template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
453void BeliefManager<PomdpType, BeliefValueType, StateType>::triangulateBeliefDynamic(BeliefType
const &belief, BeliefValueType
const &resolution,
454 Triangulation &result) {
458 BeliefValueType finalResolution = resolution;
459 uint64_t finalResolutionMisses = belief.size() + 1;
461 for (BeliefValueType currResolution = resolution; currResolution > resolution / 2; --currResolution) {
462 uint64_t currResMisses = 0;
463 bool continueWithNextResolution =
false;
464 for (
auto const &belEntry : belief) {
465 BeliefValueType product = belEntry.second * currResolution;
468 if (currResMisses >= finalResolutionMisses) {
470 continueWithNextResolution =
true;
475 if (!continueWithNextResolution) {
476 STORM_LOG_ASSERT(currResMisses < finalResolutionMisses,
"Distance for this resolution should not be larger than a previously checked one.");
477 finalResolution = currResolution;
478 finalResolutionMisses = currResMisses;
479 if (currResMisses == 0) {
488 triangulateBeliefFreudenthal(belief, finalResolution, result);
491template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
493 BeliefType
const &belief, BeliefValueType
const &resolution) {
494 STORM_LOG_ASSERT(assertBelief(belief),
"Input belief for triangulation is not valid.");
495 Triangulation result;
497 if (belief.size() == 1u) {
498 result.weights.push_back(storm::utility::one<BeliefValueType>());
499 result.gridPoints.push_back(getOrAddBeliefId(belief));
501 auto ceiledResolution = storm::utility::ceil<BeliefValueType>(resolution);
502 switch (triangulationMode) {
503 case TriangulationMode::Static:
504 triangulateBeliefFreudenthal(belief, ceiledResolution, result);
506 case TriangulationMode::Dynamic:
507 triangulateBeliefDynamic(belief, ceiledResolution, result);
517template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
518std::vector<std::pair<typename BeliefManager<PomdpType, BeliefValueType, StateType>::BeliefId,
520BeliefManager<PomdpType, BeliefValueType, StateType>::expandInternal(BeliefId
const &beliefId, uint64_t actionIndex,
521 std::optional<std::vector<BeliefValueType>>
const &observationTriangulationResolutions,
522 std::optional<std::vector<uint64_t>>
const &observationGridClippingResolutions) {
523 std::vector<std::pair<BeliefId, ValueType>> destinations;
525 BeliefType belief = getBelief(beliefId);
528 BeliefType successorObs;
529 for (
auto const &pointEntry : belief) {
530 uint64_t state = pointEntry.first;
531 for (
auto const &pomdpTransition : pomdp.getTransitionMatrix().getRow(state, actionIndex)) {
533 auto obs = pomdp.getObservation(pomdpTransition.getColumn());
534 addToDistribution(successorObs, obs, pointEntry.second * storm::utility::convertNumber<BeliefValueType>(pomdpTransition.getValue()));
538 adjustDistribution(successorObs);
541 for (
auto const &successor : successorObs) {
542 BeliefType successorBelief;
543 for (
auto const &pointEntry : belief) {
544 uint64_t state = pointEntry.first;
545 for (
auto const &pomdpTransition : pomdp.getTransitionMatrix().getRow(state, actionIndex)) {
546 if (pomdp.getObservation(pomdpTransition.getColumn()) == successor.first) {
547 BeliefValueType prob = pointEntry.second * storm::utility::convertNumber<BeliefValueType>(pomdpTransition.getValue()) / successor.second;
548 addToDistribution(successorBelief, pomdpTransition.getColumn(), prob);
552 adjustDistribution(successorBelief);
553 STORM_LOG_ASSERT(assertBelief(successorBelief),
"Invalid successor belief.");
556 if (observationTriangulationResolutions) {
557 Triangulation triangulation = triangulateBelief(successorBelief, observationTriangulationResolutions.value()[successor.first]);
558 for (
size_t j = 0; j < triangulation.size(); ++j) {
560 BeliefValueType a = triangulation.weights[j] * successor.second;
561 destinations.emplace_back(triangulation.gridPoints[j], storm::utility::convertNumber<ValueType>(a));
563 }
else if (observationGridClippingResolutions) {
564 BeliefClipping clipping = clipBeliefToGrid(successorBelief, observationGridClippingResolutions.value()[successor.first],
566 if (clipping.isClippable) {
567 BeliefValueType a = (storm::utility::one<BeliefValueType>() - clipping.delta) * successor.second;
568 destinations.emplace_back(clipping.targetBelief, storm::utility::convertNumber<ValueType>(a));
571 destinations.emplace_back(getOrAddBeliefId(successorBelief), storm::utility::convertNumber<ValueType>(successor.second));
574 destinations.emplace_back(getOrAddBeliefId(successorBelief), storm::utility::convertNumber<ValueType>(successor.second));
581template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
584 auto res = clipBeliefToGrid(getBelief(beliefId), resolution, isInfinite);
585 res.startingBelief = beliefId;
589template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
592 uint32_t obs = getBeliefObservation(belief);
593 STORM_LOG_ASSERT(obs < beliefToIdMap.size(),
"Belief has unknown observation.");
595 lpSolver = storm::utility::solver::getLpSolver<BeliefValueType>(
"POMDP LP Solver");
601 std::vector<BeliefValueType> helper(belief.size(), storm::utility::zero<BeliefValueType>());
602 helper[0] = storm::utility::convertNumber<BeliefValueType>(resolution);
605 std::vector<storm::expressions::Expression> decisionVariables;
607 auto bigDelta = lpSolver->addBoundedContinuousVariable(
"D", storm::utility::zero<BeliefValueType>(), storm::utility::one<BeliefValueType>(),
608 storm::utility::one<BeliefValueType>());
610 std::vector<storm::expressions::Expression> deltas;
612 for (
auto const &state : belief) {
615 if (isInfinite[state.first]) {
616 auto localDelta = lpSolver->addBoundedContinuousVariable(
"d_" + std::to_string(
i), storm::utility::zero<BeliefValueType>(), state.second);
618 deltas.push_back(deltaExpr);
619 lpSolver->addConstraint(
"state_val_inf_" + std::to_string(
i), deltaExpr == lpSolver->getConstant(storm::utility::zero<BeliefValueType>()));
622 BeliefValueType bound = state.second;
623 if (!isInfinite.
empty()) {
624 bound = isInfinite[state.first] ? storm::utility::zero<BeliefValueType>() : state.second;
626 auto localDelta = lpSolver->addBoundedContinuousVariable(
"d_" + std::to_string(
i), storm::utility::zero<BeliefValueType>(), bound);
632 std::vector<BeliefType> gridCandidates;
634 BeliefType candidate;
635 auto belIter = belief.begin();
636 for (uint64_t j = 0; j < belief.size() - 1; ++j) {
637 if (!cc.isEqual(helper[j] - helper[j + 1], storm::utility::zero<BeliefValueType>())) {
638 candidate[belIter->first] = (helper[j] - helper[j + 1]) / storm::utility::convertNumber<BeliefValueType>(resolution);
642 if (!cc.isEqual(helper[belief.size() - 1], storm::utility::zero<BeliefValueType>())) {
643 candidate[belIter->first] = helper[belief.size() - 1] / storm::utility::convertNumber<BeliefValueType>(resolution);
645 if (isEqual(candidate, belief)) {
647 return BeliefClipping{
false, noId(), noId(), storm::utility::zero<BeliefValueType>(), {},
true};
649 gridCandidates.push_back(candidate);
652 auto decisionVar = lpSolver->addBinaryVariable(
"a_" + std::to_string(gridCandidates.size() - 1));
657 for (
auto const &state : belief) {
662 if (candidate.find(state.first) != candidate.end()) {
663 targetValue = lpSolver->getConstant(candidate.at(state.first));
665 targetValue = lpSolver->getConstant(storm::utility::zero<BeliefValueType>());
674 lpSolver->addConstraint(
"state_eq_" + std::to_string(
i) +
"_" + std::to_string(gridCandidates.size() - 1), leftSide >= rightSide);
679 if (helper.back() == storm::utility::convertNumber<BeliefValueType>(resolution)) {
684 auto helperIt = helper.end() - 1;
685 while (*helperIt == *(helperIt - 1)) {
688 STORM_LOG_ASSERT(helperIt != helper.begin(),
"Error in grid clipping - index wrong");
693 while (helperIt != helper.end()) {
701 lpSolver->addConstraint(
"choice",
storm::expressions::sum(decisionVariables) == lpSolver->getConstant(storm::utility::one<BeliefValueType>()));
709 lpSolver->optimize();
711 BeliefId targetBelief = noId();
713 BeliefType deltaValues;
714 auto optDelta = storm::utility::zero<BeliefValueType>();
715 auto deltaSum = storm::utility::zero<BeliefValueType>();
716 if (lpSolver->isOptimal()) {
717 optDelta = lpSolver->getObjectiveValue();
718 for (uint64_t dist = 0; dist < gridCandidates.size(); ++dist) {
719 if (lpSolver->getBinaryValue(lpSolver->getManager().getVariable(
"a_" + std::to_string(dist)))) {
720 targetBelief = getOrAddBeliefId(gridCandidates[dist]);
725 for (
auto const &state : belief) {
726 auto val = lpSolver->getContinuousValue(lpSolver->getManager().getVariable(
"d_" + std::to_string(
i)));
727 if (cc.isLess(storm::utility::zero<BeliefValueType>(), val)) {
728 deltaValues.emplace(state.first, val);
734 if (cc.isEqual(optDelta, storm::utility::zero<BeliefValueType>())) {
737 STORM_LOG_WARN(
"LP solver returned an optimal value of 0. This should definitely not happen when using a grid");
740 return BeliefClipping{
false, noId(), noId(), storm::utility::zero<BeliefValueType>(), {},
false};
743 if (optDelta == storm::utility::one<BeliefValueType>()) {
744 STORM_LOG_WARN(
"LP solver returned an optimal value of 1. Sum of state clipping values is " << deltaSum);
749 if (deltaSum == storm::utility::one<BeliefValueType>()) {
750 return BeliefClipping{
false, noId(), noId(), storm::utility::zero<BeliefValueType>(), {},
false};
755 return BeliefClipping{lpSolver->isOptimal(), noId(), targetBelief, optDelta, deltaValues,
false};
758template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
760 STORM_LOG_ASSERT(pomdp.getInitialStates().getNumberOfSetBits() < 2,
"POMDP contains more than one initial state");
761 STORM_LOG_ASSERT(pomdp.getInitialStates().getNumberOfSetBits() == 1,
"POMDP does not contain an initial state");
763 belief[*pomdp.getInitialStates().begin()] = storm::utility::one<BeliefValueType>();
766 return getOrAddBeliefId(belief);
769template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
771 BeliefType
const &belief) {
772 uint32_t obs = getBeliefObservation(belief);
773 STORM_LOG_ASSERT(obs < beliefToIdMap.size(),
"Belief has unknown observation.");
774 auto insertioRes = beliefToIdMap[obs].emplace(belief, beliefs.size());
775 if (insertioRes.second) {
778 beliefs.push_back(belief);
781 return insertioRes.first->second;
783template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
785 return getBelief(beliefId).begin()->first;
788template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
790 if (pomdp.hasObservationValuations()) {
791 return pomdp.getObservationValuations().getStateInfo(getBeliefObservation(beliefId));
793 STORM_LOG_TRACE(
"Cannot get observation labels as no observation valuation has been defined for the POMDP. Return empty label instead.");
798template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
800 return getBeliefAsVector(getBelief(beliefId));
803template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
804std::vector<BeliefValueType> BeliefManager<PomdpType, BeliefValueType, StateType>::getBeliefAsVector(
const BeliefType &belief) {
805 std::vector<BeliefValueType> res(pomdp.getNumberOfStates(), storm::utility::zero<BeliefValueType>());
806 for (
auto const &stateprob : belief) {
807 res[stateprob.first] = stateprob.second;
812template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
815 std::vector<BeliefValueType> beliefAsVector = getBeliefAsVector(beliefId);
816 std::vector<BeliefValueType> res(matrix.
getRowCount());
double round(double val, int precision)
std::vector< BeliefValueType > computeMatrixBeliefProduct(BeliefId const &beliefId, storm::storage::SparseMatrix< BeliefValueType > &matrix)
void joinSupport(BeliefId const &beliefId, BeliefSupportType &support)
boost::container::flat_set< StateType > BeliefSupportType
PomdpType::ValueType ValueType
BeliefManager(PomdpType const &pomdp, BeliefValueType const &precision, TriangulationMode const &triangulationMode)
std::vector< std::pair< BeliefId, ValueType > > expandAndTriangulate(BeliefId const &beliefId, uint64_t actionIndex, std::vector< BeliefValueType > const &observationResolutions)
boost::container::flat_map< StateType, BeliefValueType > BeliefType
uint32_t getBeliefObservation(BeliefId beliefId)
void setRewardModel(std::optional< std::string > rewardModelName=std::nullopt)
std::string toString(BeliefId const &beliefId) const
uint64_t getBeliefNumberOfChoices(BeliefId beliefId)
uint64_t getRepresentativeState(BeliefId const &beliefId)
Returns the first state in the belief as a representative.
std::vector< std::pair< BeliefId, ValueType > > expand(BeliefId const &beliefId, uint64_t actionIndex)
BeliefId const & getInitialBelief() const
std::vector< std::pair< BeliefId, ValueType > > expandAndClip(BeliefId const &beliefId, uint64_t actionIndex, std::vector< uint64_t > const &observationResolutions)
ValueType getBeliefActionReward(BeliefId const &beliefId, uint64_t const &localActionIndex) const
BeliefId getNumberOfBeliefIds() const
void addToDistribution(DistributionType &distr, StateType const &state, BeliefValueType const &value)
std::string getObservationLabel(BeliefId const &beliefId)
ValueType getWeightedSum(BeliefId const &beliefId, std::vector< ValueType > const &summands)
BeliefClipping clipBeliefToGrid(BeliefId const &beliefId, uint64_t resolution, storm::storage::BitVector isInfinite=storm::storage::BitVector())
bool isEqual(BeliefId const &first, BeliefId const &second) const
Triangulation triangulateBelief(BeliefId beliefId, BeliefValueType resolution)
A bit vector that is internally represented as a vector of 64-bit values.
bool empty() const
Retrieves whether no bits are set to true in this bit vector.
A class that holds a possibly non-square matrix in the compressed row storage format.
void multiplyWithVector(std::vector< value_type > const &vector, std::vector< value_type > &result, std::vector< value_type > const *summand=nullptr) const
Multiplies the matrix with the given vector and writes the result to the given result vector.
index_type getRowCount() const
Returns the number of rows of the matrix.
#define STORM_LOG_WARN(message)
#define STORM_LOG_DEBUG(message)
#define STORM_LOG_TRACE(message)
#define STORM_LOG_ERROR(message)
#define STORM_LOG_ASSERT(cond, message)
Expression sum(std::vector< storm::expressions::Expression > const &expressions)
std::string toString(PomdpMemoryPattern const &pattern)
ValueType floor(ValueType const &number)
bool isZero(ValueType const &a)
bool isInteger(ValueType const &number)
ValueType round(ValueType const &number)
std::vector< BeliefId > gridPoints
std::vector< BeliefValueType > weights