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), cc(precision, false), triangulationMode(triangulationMode) {
85 beliefToIdMap.resize(pomdp.getNrObservations());
86 initialBeliefId = computeInitialBelief();
89template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
91 if (rewardModelName) {
92 auto const &rewardModel = pomdp.getRewardModel(rewardModelName.value());
93 pomdpActionRewardVector = rewardModel.getTotalRewardVector(pomdp.getTransitionMatrix());
95 setRewardModel(pomdp.getUniqueRewardModelName());
99template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
101 pomdpActionRewardVector.clear();
104template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
106 return std::numeric_limits<BeliefId>::max();
109template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
111 return isEqual(getBelief(first), getBelief(second));
114template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
116 return toString(getBelief(beliefId));
119template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
121 std::stringstream str;
123 for (uint64_t
i = 0;
i < t.
size(); ++
i) {
130template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
132 BeliefId const &beliefId, std::vector<ValueType>
const &summands) {
133 auto result = storm::utility::zero<ValueType>();
134 for (
auto const &entry : getBelief(beliefId)) {
135 result += storm::utility::convertNumber<ValueType>(entry.second) * storm::utility::convertNumber<ValueType>(summands.at(entry.first));
140template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
142 BeliefId const &beliefId, std::unordered_map<StateType, ValueType>
const &summands) {
143 bool successful =
true;
144 auto result = storm::utility::zero<ValueType>();
145 for (
auto const &entry : getBelief(beliefId)) {
146 auto probIter = summands.find(entry.first);
147 if (probIter != summands.end()) {
148 result += storm::utility::convertNumber<ValueType>(entry.second) * storm::utility::convertNumber<ValueType>(summands.at(entry.first));
154 return {successful, result};
157template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
159 return initialBeliefId;
162template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
164 BeliefId const &beliefId, uint64_t
const &localActionIndex)
const {
165 auto const &belief = getBelief(beliefId);
166 STORM_LOG_ASSERT(!pomdpActionRewardVector.empty(),
"Requested a reward although no reward model was specified.");
167 auto result = storm::utility::zero<ValueType>();
168 auto const &choiceIndices = pomdp.getTransitionMatrix().getRowGroupIndices();
169 for (
auto const &entry : belief) {
170 uint64_t choiceIndex = choiceIndices[entry.first] + localActionIndex;
171 STORM_LOG_ASSERT(choiceIndex < choiceIndices[entry.first + 1],
"Invalid local action index.");
172 STORM_LOG_ASSERT(choiceIndex < pomdpActionRewardVector.size(),
"Invalid choice index.");
173 result += storm::utility::convertNumber<ValueType>(entry.second) * pomdpActionRewardVector[choiceIndex];
178template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
180 return getBeliefObservation(getBelief(beliefId));
183template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
185 auto const &belief = getBelief(beliefId);
186 return pomdp.getNumberOfChoices(belief.begin()->first);
189template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
191 BeliefId beliefId, BeliefValueType resolution) {
192 return triangulateBelief(getBelief(beliefId), resolution);
195template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
196template<
typename DistributionType>
198 auto insertionRes = distr.emplace(state, value);
199 if (!insertionRes.second) {
200 insertionRes.first->second += value;
204template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
205template<
typename DistributionType>
207 if (distr.size() == 1 && cc.isEqual(distr.begin()->second, storm::utility::one<BeliefValueType>())) {
209 distr.begin()->second = storm::utility::one<BeliefValueType>();
213template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
215 auto const &belief = getBelief(beliefId);
216 for (
auto const &entry : belief) {
217 support.insert(entry.first);
221template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
223 return beliefs.size();
226template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
227std::vector<std::pair<typename BeliefManager<PomdpType, BeliefValueType, StateType>::BeliefId,
230 std::vector<BeliefValueType>
const &observationResolutions) {
231 return expandInternal(beliefId, actionIndex, observationResolutions);
234template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
235std::vector<std::pair<typename BeliefManager<PomdpType, BeliefValueType, StateType>::BeliefId,
238 std::vector<uint64_t>
const &observationResolutions) {
239 return expandInternal(beliefId, actionIndex, std::nullopt, observationResolutions);
242template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
243std::vector<std::pair<typename BeliefManager<PomdpType, BeliefValueType, StateType>::BeliefId,
246 return expandInternal(beliefId, actionIndex);
249template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
251 BeliefId
const &
id)
const {
253 STORM_LOG_ASSERT(
id < getNumberOfBeliefIds(),
"Belief index " <<
id <<
" is out of range.");
257template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
259 BeliefType
const &belief)
const {
260 uint32_t obs = getBeliefObservation(belief);
261 STORM_LOG_ASSERT(obs < beliefToIdMap.size(),
"Belief has unknown observation.");
262 auto idIt = beliefToIdMap[obs].find(belief);
267template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
269 std::stringstream str;
272 for (
auto const &entry : belief) {
278 str << entry.first <<
": " << std::setprecision(std::numeric_limits<double>::max_digits10 + 1) << entry.second;
284template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
286 if (first.size() != second.size()) {
289 auto secondIt = second.begin();
290 for (
auto const &firstEntry : first) {
291 if (firstEntry.first != secondIt->first) {
294 if (!cc.isEqual(firstEntry.second, secondIt->second)) {
302template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
303bool BeliefManager<PomdpType, BeliefValueType, StateType>::assertBelief(BeliefType
const &belief)
const {
304 auto sum = storm::utility::zero<BeliefValueType>();
305 std::optional<uint32_t> observation;
306 for (
auto const &entry : belief) {
307 if (entry.first >= pomdp.getNumberOfStates()) {
308 STORM_LOG_ERROR(
"Belief does refer to non-existing pomdp state " << entry.first <<
".");
311 uint64_t entryObservation = pomdp.getObservation(entry.first);
313 if (observation.value() != entryObservation) {
318 observation = entryObservation;
326 if (entry.second < storm::utility::zero<BeliefValueType>()) {
330 if (cc.isLess(storm::utility::one<BeliefValueType>(), entry.second)) {
336 if (!cc.isOne(sum)) {
337 STORM_LOG_ERROR(
"Belief does not sum up to one. (" << sum <<
" instead).");
343template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
344bool BeliefManager<PomdpType, BeliefValueType, StateType>::assertTriangulation(BeliefType
const &belief, Triangulation
const &triangulation)
const {
345 if (triangulation.weights.size() != triangulation.gridPoints.size()) {
346 STORM_LOG_ERROR(
"Number of weights and points in triangulation does not match.");
349 if (triangulation.size() == 0) {
353 BeliefType triangulatedBelief;
354 auto weightSum = storm::utility::zero<BeliefValueType>();
355 for (uint64_t
i = 0;
i < triangulation.weights.size(); ++
i) {
356 if (cc.isZero(triangulation.weights[
i])) {
360 if (cc.isLess(triangulation.weights[
i], storm::utility::zero<BeliefValueType>())) {
364 if (cc.isLess(storm::utility::one<BeliefValueType>(), triangulation.weights[
i])) {
367 weightSum += triangulation.weights[
i];
368 BeliefType
const &gridPoint = getBelief(triangulation.gridPoints[
i]);
369 for (
auto const &pointEntry : gridPoint) {
370 BeliefValueType &triangulatedValue = triangulatedBelief.emplace(pointEntry.first, storm::utility::zero<BeliefValueType>()).first->second;
371 triangulatedValue += triangulation.weights[
i] * pointEntry.second;
374 if (!cc.isOne(weightSum)) {
378 if (!assertBelief(triangulatedBelief)) {
381 if (!isEqual(belief, triangulatedBelief)) {
388template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
391 return pomdp.getObservation(belief.begin()->first);
394template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
395void BeliefManager<PomdpType, BeliefValueType, StateType>::triangulateBeliefFreudenthal(BeliefType
const &belief, BeliefValueType
const &resolution,
396 Triangulation &result) {
399 StateType numEntries = belief.size();
405 std::set<FreudenthalDiff, std::greater<>> sorted_diffs;
406 std::vector<BeliefValueType> qsRow;
407 qsRow.reserve(numEntries);
408 std::vector<StateType> toOriginalIndicesMap;
409 toOriginalIndicesMap.reserve(numEntries);
410 BeliefValueType x = resolution;
411 for (
auto const &entry : belief) {
413 sorted_diffs.emplace(toOriginalIndicesMap.size(), x - qsRow.back());
414 toOriginalIndicesMap.push_back(entry.first);
415 x -= entry.second * resolution;
418 qsRow.push_back(storm::utility::zero<BeliefValueType>());
420 result.weights.reserve(numEntries);
421 result.gridPoints.reserve(numEntries);
422 auto currentSortedDiff = sorted_diffs.begin();
423 auto previousSortedDiff = sorted_diffs.end();
424 --previousSortedDiff;
425 for (StateType
i = 0;
i < numEntries; ++
i) {
427 BeliefValueType weight = previousSortedDiff->diff - currentSortedDiff->diff;
430 weight += storm::utility::one<BeliefValueType>();
433 qsRow[previousSortedDiff->dimension] += storm::utility::one<BeliefValueType>();
435 if (!cc.isZero(weight)) {
436 result.weights.push_back(weight);
438 BeliefType gridPoint;
439 for (StateType j = 0; j < numEntries; ++j) {
440 BeliefValueType gridPointEntry = qsRow[j] - qsRow[j + 1];
441 if (!cc.isZero(gridPointEntry)) {
442 gridPoint[toOriginalIndicesMap[j]] = gridPointEntry / resolution;
445 result.gridPoints.push_back(getOrAddBeliefId(gridPoint));
447 previousSortedDiff = currentSortedDiff++;
451template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
452void BeliefManager<PomdpType, BeliefValueType, StateType>::triangulateBeliefDynamic(BeliefType
const &belief, BeliefValueType
const &resolution,
453 Triangulation &result) {
457 BeliefValueType finalResolution = resolution;
458 uint64_t finalResolutionMisses = belief.size() + 1;
460 for (BeliefValueType currResolution = resolution; currResolution > resolution / 2; --currResolution) {
461 uint64_t currResMisses = 0;
462 bool continueWithNextResolution =
false;
463 for (
auto const &belEntry : belief) {
464 BeliefValueType product = belEntry.second * currResolution;
467 if (currResMisses >= finalResolutionMisses) {
469 continueWithNextResolution =
true;
474 if (!continueWithNextResolution) {
475 STORM_LOG_ASSERT(currResMisses < finalResolutionMisses,
"Distance for this resolution should not be larger than a previously checked one.");
476 finalResolution = currResolution;
477 finalResolutionMisses = currResMisses;
478 if (currResMisses == 0) {
487 triangulateBeliefFreudenthal(belief, finalResolution, result);
490template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
492 BeliefType
const &belief, BeliefValueType
const &resolution) {
493 STORM_LOG_ASSERT(assertBelief(belief),
"Input belief for triangulation is not valid.");
494 Triangulation result;
496 if (belief.size() == 1u) {
497 result.weights.push_back(storm::utility::one<BeliefValueType>());
498 result.gridPoints.push_back(getOrAddBeliefId(belief));
500 auto ceiledResolution = storm::utility::ceil<BeliefValueType>(resolution);
501 switch (triangulationMode) {
502 case TriangulationMode::Static:
503 triangulateBeliefFreudenthal(belief, ceiledResolution, result);
505 case TriangulationMode::Dynamic:
506 triangulateBeliefDynamic(belief, ceiledResolution, result);
516template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
517std::vector<std::pair<typename BeliefManager<PomdpType, BeliefValueType, StateType>::BeliefId,
519BeliefManager<PomdpType, BeliefValueType, StateType>::expandInternal(BeliefId
const &beliefId, uint64_t actionIndex,
520 std::optional<std::vector<BeliefValueType>>
const &observationTriangulationResolutions,
521 std::optional<std::vector<uint64_t>>
const &observationGridClippingResolutions) {
522 std::vector<std::pair<BeliefId, ValueType>> destinations;
524 BeliefType belief = getBelief(beliefId);
527 BeliefType successorObs;
528 for (
auto const &pointEntry : belief) {
529 uint64_t state = pointEntry.first;
530 for (
auto const &pomdpTransition : pomdp.getTransitionMatrix().getRow(state, actionIndex)) {
532 auto obs = pomdp.getObservation(pomdpTransition.getColumn());
533 addToDistribution(successorObs, obs, pointEntry.second * storm::utility::convertNumber<BeliefValueType>(pomdpTransition.getValue()));
537 adjustDistribution(successorObs);
540 for (
auto const &successor : successorObs) {
541 BeliefType successorBelief;
542 for (
auto const &pointEntry : belief) {
543 uint64_t state = pointEntry.first;
544 for (
auto const &pomdpTransition : pomdp.getTransitionMatrix().getRow(state, actionIndex)) {
545 if (pomdp.getObservation(pomdpTransition.getColumn()) == successor.first) {
546 BeliefValueType prob = pointEntry.second * storm::utility::convertNumber<BeliefValueType>(pomdpTransition.getValue()) / successor.second;
547 addToDistribution(successorBelief, pomdpTransition.getColumn(), prob);
551 adjustDistribution(successorBelief);
552 STORM_LOG_ASSERT(assertBelief(successorBelief),
"Invalid successor belief.");
555 if (observationTriangulationResolutions) {
556 Triangulation triangulation = triangulateBelief(successorBelief, observationTriangulationResolutions.value()[successor.first]);
557 for (
size_t j = 0; j < triangulation.size(); ++j) {
559 BeliefValueType a = triangulation.weights[j] * successor.second;
560 destinations.emplace_back(triangulation.gridPoints[j], storm::utility::convertNumber<ValueType>(a));
562 }
else if (observationGridClippingResolutions) {
563 BeliefClipping clipping = clipBeliefToGrid(successorBelief, observationGridClippingResolutions.value()[successor.first],
565 if (clipping.isClippable) {
566 BeliefValueType a = (storm::utility::one<BeliefValueType>() - clipping.delta) * successor.second;
567 destinations.emplace_back(clipping.targetBelief, storm::utility::convertNumber<ValueType>(a));
570 destinations.emplace_back(getOrAddBeliefId(successorBelief), storm::utility::convertNumber<ValueType>(successor.second));
573 destinations.emplace_back(getOrAddBeliefId(successorBelief), storm::utility::convertNumber<ValueType>(successor.second));
580template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
583 auto res = clipBeliefToGrid(getBelief(beliefId), resolution, isInfinite);
584 res.startingBelief = beliefId;
588template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
591 uint32_t obs = getBeliefObservation(belief);
592 STORM_LOG_ASSERT(obs < beliefToIdMap.size(),
"Belief has unknown observation.");
594 lpSolver = storm::utility::solver::getLpSolver<BeliefValueType>(
"POMDP LP Solver");
600 std::vector<BeliefValueType> helper(belief.size(), storm::utility::zero<BeliefValueType>());
601 helper[0] = storm::utility::convertNumber<BeliefValueType>(resolution);
604 std::vector<storm::expressions::Expression> decisionVariables;
606 auto bigDelta = lpSolver->addBoundedContinuousVariable(
"D", storm::utility::zero<BeliefValueType>(), storm::utility::one<BeliefValueType>(),
607 storm::utility::one<BeliefValueType>());
609 std::vector<storm::expressions::Expression> deltas;
611 for (
auto const &state : belief) {
614 if (isInfinite[state.first]) {
615 auto localDelta = lpSolver->addBoundedContinuousVariable(
"d_" + std::to_string(
i), storm::utility::zero<BeliefValueType>(), state.second);
617 deltas.push_back(deltaExpr);
618 lpSolver->addConstraint(
"state_val_inf_" + std::to_string(
i), deltaExpr == lpSolver->getConstant(storm::utility::zero<BeliefValueType>()));
621 BeliefValueType bound = state.second;
622 if (!isInfinite.
empty()) {
623 bound = isInfinite[state.first] ? storm::utility::zero<BeliefValueType>() : state.second;
625 auto localDelta = lpSolver->addBoundedContinuousVariable(
"d_" + std::to_string(
i), storm::utility::zero<BeliefValueType>(), bound);
631 std::vector<BeliefType> gridCandidates;
633 BeliefType candidate;
634 auto belIter = belief.begin();
635 for (uint64_t j = 0; j < belief.size() - 1; ++j) {
636 if (!cc.isEqual(helper[j] - helper[j + 1], storm::utility::zero<BeliefValueType>())) {
637 candidate[belIter->first] = (helper[j] - helper[j + 1]) / storm::utility::convertNumber<BeliefValueType>(resolution);
641 if (!cc.isEqual(helper[belief.size() - 1], storm::utility::zero<BeliefValueType>())) {
642 candidate[belIter->first] = helper[belief.size() - 1] / storm::utility::convertNumber<BeliefValueType>(resolution);
644 if (isEqual(candidate, belief)) {
646 return BeliefClipping{
false, noId(), noId(), storm::utility::zero<BeliefValueType>(), {},
true};
648 gridCandidates.push_back(candidate);
651 auto decisionVar = lpSolver->addBinaryVariable(
"a_" + std::to_string(gridCandidates.size() - 1));
656 for (
auto const &state : belief) {
661 if (candidate.find(state.first) != candidate.end()) {
662 targetValue = lpSolver->getConstant(candidate.at(state.first));
664 targetValue = lpSolver->getConstant(storm::utility::zero<BeliefValueType>());
673 lpSolver->addConstraint(
"state_eq_" + std::to_string(
i) +
"_" + std::to_string(gridCandidates.size() - 1), leftSide >= rightSide);
678 if (helper.back() == storm::utility::convertNumber<BeliefValueType>(resolution)) {
683 auto helperIt = helper.end() - 1;
684 while (*helperIt == *(helperIt - 1)) {
687 STORM_LOG_ASSERT(helperIt != helper.begin(),
"Error in grid clipping - index wrong");
692 while (helperIt != helper.end()) {
700 lpSolver->addConstraint(
"choice",
storm::expressions::sum(decisionVariables) == lpSolver->getConstant(storm::utility::one<BeliefValueType>()));
708 lpSolver->optimize();
710 BeliefId targetBelief = noId();
712 BeliefType deltaValues;
713 auto optDelta = storm::utility::zero<BeliefValueType>();
714 auto deltaSum = storm::utility::zero<BeliefValueType>();
715 if (lpSolver->isOptimal()) {
716 optDelta = lpSolver->getObjectiveValue();
717 for (uint64_t dist = 0; dist < gridCandidates.size(); ++dist) {
718 if (lpSolver->getBinaryValue(lpSolver->getManager().getVariable(
"a_" + std::to_string(dist)))) {
719 targetBelief = getOrAddBeliefId(gridCandidates[dist]);
724 for (
auto const &state : belief) {
725 auto val = lpSolver->getContinuousValue(lpSolver->getManager().getVariable(
"d_" + std::to_string(
i)));
726 if (cc.isLess(storm::utility::zero<BeliefValueType>(), val)) {
727 deltaValues.emplace(state.first, val);
733 if (cc.isEqual(optDelta, storm::utility::zero<BeliefValueType>())) {
736 STORM_LOG_WARN(
"LP solver returned an optimal value of 0. This should definitely not happen when using a grid");
739 return BeliefClipping{
false, noId(), noId(), storm::utility::zero<BeliefValueType>(), {},
false};
742 if (optDelta == storm::utility::one<BeliefValueType>()) {
743 STORM_LOG_WARN(
"LP solver returned an optimal value of 1. Sum of state clipping values is " << deltaSum);
748 if (deltaSum == storm::utility::one<BeliefValueType>()) {
749 return BeliefClipping{
false, noId(), noId(), storm::utility::zero<BeliefValueType>(), {},
false};
754 return BeliefClipping{lpSolver->isOptimal(), noId(), targetBelief, optDelta, deltaValues,
false};
757template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
759 STORM_LOG_ASSERT(pomdp.getInitialStates().getNumberOfSetBits() < 2,
"POMDP contains more than one initial state");
760 STORM_LOG_ASSERT(pomdp.getInitialStates().getNumberOfSetBits() == 1,
"POMDP does not contain an initial state");
762 belief[*pomdp.getInitialStates().begin()] = storm::utility::one<BeliefValueType>();
765 return getOrAddBeliefId(belief);
768template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
770 BeliefType
const &belief) {
771 uint32_t obs = getBeliefObservation(belief);
772 STORM_LOG_ASSERT(obs < beliefToIdMap.size(),
"Belief has unknown observation.");
773 auto insertioRes = beliefToIdMap[obs].emplace(belief, beliefs.size());
774 if (insertioRes.second) {
777 beliefs.push_back(belief);
780 return insertioRes.first->second;
782template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
784 return getBelief(beliefId).begin()->first;
787template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
789 if (pomdp.hasObservationValuations()) {
790 return pomdp.getObservationValuations().getStateInfo(getBeliefObservation(beliefId));
792 STORM_LOG_TRACE(
"Cannot get observation labels as no observation valuation has been defined for the POMDP. Return empty label instead.");
797template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
799 return getBeliefAsVector(getBelief(beliefId));
802template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
803std::vector<BeliefValueType> BeliefManager<PomdpType, BeliefValueType, StateType>::getBeliefAsVector(
const BeliefType &belief) {
804 std::vector<BeliefValueType> res(pomdp.getNumberOfStates(), storm::utility::zero<BeliefValueType>());
805 for (
auto const &stateprob : belief) {
806 res[stateprob.first] = stateprob.second;
811template<
typename PomdpType,
typename BeliefValueType,
typename StateType>
814 std::vector<BeliefValueType> beliefAsVector = getBeliefAsVector(beliefId);
815 std::vector<BeliefValueType> res(matrix.
getRowCount());
double round(double val, int precision)
A class that implements the LpSolver interface using glpk as the background solver.
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