"Do not ask me for a number at every world I might be in. Hand me your belief, a single point in the simplex, and I will give you a value, by reading off the highest of my many flat planes. I am not one function but a committee of linear opinions, and the convex upper envelope of that committee is me: piecewise, linear, and quietly proud of every facet."
A Value Function Defined Over Beliefs, Piecewise and Proud
In a POMDP the agent never knows the state, only a belief, a probability distribution over states, and the optimal value is a function of that belief. The single structural fact that makes POMDP planning possible is that the finite-horizon optimal value function is piecewise-linear-and-convex over the belief simplex: it is the upper envelope of a finite set of linear functions, each stored as one vector of coefficients called an alpha-vector. That fact converts an apparently impossible problem, planning over a continuous space of beliefs, into bookkeeping over a finite set of hyperplanes. This section builds the idea in four movements. First, exact value iteration over beliefs: alpha-vectors, the convex envelope, and why the exact algorithm is PSPACE-hard because the number of alpha-vectors can explode doubly exponentially in the horizon. Second, point-based methods (PBVI, SARSOP, Perseus) that keep value only at a finite set of sampled reachable beliefs and so trade exactness for tractability, the practical workhorse for moderate POMDPs. Third, online planning (POMCP, DESPOT) that runs Monte Carlo tree search from the current belief using a particle filter, planning locally without ever solving the whole space. Fourth, the decision rule for which tool to reach for, and the bridge to the model-free agents of Section 23.3 that skip the explicit belief entirely. A from-scratch alpha-vector solver for the classic Tiger problem, matched against the pomdp-py library, makes every equation executable. You leave able to read, implement, and choose among POMDP solvers.
In Section 23.1 we defined the POMDP and the belief state $\mathbf{b}_t$, showed that the belief is a sufficient statistic of the entire observation-action history, and derived the Bayesian belief update that carries $\mathbf{b}_{t-1}$ to $\mathbf{b}_t$ after an action and an observation. That update turned the POMDP into a fully observed Markov decision process whose state is the belief, the so-called belief MDP. We deferred the one question that makes the belief MDP useful: how do we actually compute an optimal policy over a continuous, high-dimensional belief space? This section answers it. The belief MDP is a genuine MDP, so the Bellman machinery of Chapter 22 applies in principle, but its state space is the entire probability simplex over states, uncountably infinite, so the tabular value iteration of Chapter 22 cannot be run directly. The breakthrough that rescues the situation, due to Sondik in 1971, is that the value function has a special and exploitable shape. We develop that shape and then the family of algorithms it enables. Throughout we use the unified notation of Appendix A: $S$ the states, $A$ the actions, $\Omega$ the observations, $\mathbf{b}$ the belief, $\gamma$ the discount, $V$ the value function.
Why does solving POMDPs deserve a section of its own rather than a footnote to MDP value iteration? Because partial observability changes the character of the problem qualitatively, not just quantitatively. A fully observed MDP plans over a finite set of states; a POMDP plans over a continuum of beliefs, and the optimal action at a belief can depend on arbitrarily fine distinctions between nearby beliefs. Worse, the optimal policy must reason about information gathering, taking an action not for its immediate reward but to sharpen the belief so that a later action pays off, a behavior with no analogue in the fully observed case. The Tiger problem we solve at the end makes this vivid: the optimal agent often pays to listen repeatedly before committing to open a door, buying information at a cost. Capturing that behavior is exactly what makes POMDP solving both hard and worth the trouble.
The four concrete competencies this section installs are these: to represent a POMDP value function as a set of alpha-vectors and evaluate it at a belief by taking the max inner product; to explain why exact value iteration over beliefs is correct but PSPACE-hard, and what makes the alpha-vector set explode; to describe how point-based methods (PBVI, SARSOP, Perseus) and online planners (POMCP, DESPOT) tame that explosion, and when each is appropriate; and to implement a small exact solver and reproduce it with a library. These are the load-bearing skills for every belief-state agent in this chapter and the foundation for the model-free shortcut of Section 23.3.
1. Exact Value Functions Over Belief Space Intermediate
The belief MDP has a Bellman optimality equation just like any MDP, but its state is the belief $\mathbf{b}$, a point in the $(|S|-1)$-simplex. Writing $r(\mathbf{b}, a) = \sum_{s} \mathbf{b}(s)\,R(s, a)$ for the expected immediate reward of action $a$ at belief $\mathbf{b}$, and $\mathbf{b}^{a, o}$ for the belief that results from taking $a$ and observing $o$ (the update of Section 23.1), the optimal value satisfies
$$V^{*}(\mathbf{b}) = \max_{a \in A} \left[ r(\mathbf{b}, a) + \gamma \sum_{o \in \Omega} P(o \mid \mathbf{b}, a)\, V^{*}(\mathbf{b}^{a, o}) \right],$$where $P(o \mid \mathbf{b}, a)$ is the probability of observation $o$ given the current belief and action. This is a Bellman equation over a continuous state space, and at first glance it looks hopeless: $V^{*}$ is a function on an infinite set, so we cannot tabulate it. The rescue is a theorem about its shape. The decisive object is the alpha-vector, a vector $\boldsymbol{\alpha} \in \mathbb{R}^{|S|}$ that assigns a value to each underlying state; its inner product with a belief, $\boldsymbol{\alpha} \cdot \mathbf{b} = \sum_{s} \boldsymbol{\alpha}(s)\,\mathbf{b}(s)$, is a linear function of the belief. Sondik's theorem states that the finite-horizon optimal value function is the upper envelope of a finite set $\Gamma = \{\boldsymbol{\alpha}_1, \dots, \boldsymbol{\alpha}_m\}$ of such vectors:
$$V^{*}(\mathbf{b}) = \max_{\boldsymbol{\alpha} \in \Gamma} \;\boldsymbol{\alpha} \cdot \mathbf{b} \;=\; \max_{\boldsymbol{\alpha} \in \Gamma} \sum_{s \in S} \boldsymbol{\alpha}(s)\, \mathbf{b}(s).$$Because each $\boldsymbol{\alpha} \cdot \mathbf{b}$ is linear in $\mathbf{b}$ and the pointwise maximum of linear functions is convex and piecewise-linear, $V^{*}$ is piecewise-linear-and-convex (PWLC) over the simplex. Each alpha-vector corresponds to a conditional plan, a complete policy tree of what to do for the rest of the horizon; the vector records the expected discounted return of that plan as a function of the true (unknown) starting state. At any belief the agent picks the plan with the highest expected value there, which is exactly the max in the equation. Figure 23.2.1 draws the envelope for a two-state POMDP, where the simplex is the unit interval and each alpha-vector is a line.
The whole reason POMDP planning is possible at all is the PWLC theorem: a function defined on an uncountable belief simplex collapses to a finite set of vectors, one per useful conditional plan. You never store a value at every belief; you store the alpha-vectors and evaluate $V(\mathbf{b}) = \max_{\boldsymbol{\alpha}} \boldsymbol{\alpha} \cdot \mathbf{b}$ on demand. Each alpha-vector simultaneously answers two questions: it gives the value (its inner product with the belief) and it identifies the best plan or action (the one whose vector wins). Convexity is not an accident either: it expresses that information has value, beliefs near the simplex corners (you know the state) are worth more than beliefs in the middle (you are uncertain), so the value curves upward toward certainty. Every POMDP algorithm in this section is, at bottom, a different strategy for finding or approximating that finite alpha-vector set without paying the doubly exponential worst case.
Exact value iteration over beliefs maintains the set $\Gamma$ and updates it. One backup, the analogue of a single Bellman sweep, takes the current alpha-vector set $\Gamma_n$ representing the $n$-step value function and produces $\Gamma_{n+1}$ representing the $(n+1)$-step value function. The construction enumerates, for each action and each way of assigning a future alpha-vector to each possible observation, the alpha-vector of the resulting conditional plan. Concretely, a backed-up alpha-vector for action $a$ and an assignment $o \mapsto \boldsymbol{\alpha}^{o}$ has entries
$$\boldsymbol{\alpha}(s) = R(s, a) + \gamma \sum_{o \in \Omega} \sum_{s'} T(s' \mid s, a)\, Z(o \mid s', a)\, \boldsymbol{\alpha}^{o}(s'),$$where $T$ is the transition model and $Z$ the observation model from Section 23.1. The exactness is purchased at a steep price. If $\Gamma_n$ has $m$ vectors, the naive backup generates up to $|A|\,m^{|\Omega|}$ candidate vectors, one for each action and each of the $m^{|\Omega|}$ ways of mapping observations to future plans. Many are dominated (never the maximum at any belief) and can be pruned, each pruning test a small linear program. Even so, in the worst case the number that survive grows doubly exponentially in the horizon. This is why exact POMDP planning is PSPACE-hard (a complexity class believed even harder than NP-complete, meaning no efficient exact algorithm is expected) (Papadimitriou and Tsitsiklis, 1987): the value function's exact representation can require an astronomically large alpha-vector set even for modest problems.
The doubly exponential growth is not a removable artifact of a clumsy algorithm; it reflects genuine problem complexity. The number of distinct optimal conditional plans really can explode with the horizon, because each additional step of lookahead multiplies the ways the future can branch on observations. Exact solvers (Sondik's one-pass algorithm, the Witness algorithm of Kaelbling, Littman, and Cassandra, incremental pruning) differ in how cleverly they prune dominated vectors and avoid generating useless candidates, and they push the frontier of exactly solvable POMDPs to perhaps a dozen states and a short horizon. Beyond that, exactness is hopeless and we must approximate. The good news, developed next, is that most of the belief simplex is never visited by a good policy, so we can afford to compute the value only where it matters.
2. Point-Based Methods: PBVI, SARSOP, Perseus Advanced
The escape from the doubly exponential blow-up rests on a simple observation about reachability. Starting from a known initial belief $\mathbf{b}_0$, only a tiny, measure-zero sliver of the belief simplex is ever reached under any policy: beliefs are produced by the deterministic belief update applied to discrete observations, so the reachable set is countable and, in practice, concentrated. The full alpha-vector set wastes enormous effort representing the value accurately at beliefs the agent will never occupy. Point-based value iteration refuses that waste: it samples a finite set $B = \{\mathbf{b}_1, \dots, \mathbf{b}_N\}$ of reachable beliefs and maintains exactly one alpha-vector per sampled belief, the one that is optimal there. This caps the alpha-vector set at $|B|$ vectors, turning the doubly exponential representation into a linear one.
The original point-based value iteration (PBVI) of Pineau, Gordon, and Thrun (2003) made this concrete. It backs up the value only at the sampled beliefs: for each $\mathbf{b} \in B$ it computes the single best backed-up alpha-vector at that belief, using the same backup equation of subsection one but evaluated at $\mathbf{b}$ rather than enumerated over all assignments, which costs only $O(|A|\,|\Omega|\,|B|\,|S|^2)$ per sweep instead of the exponential enumeration. Crucially the resulting alpha-vector is still a valid linear lower bound on $V^{*}$ everywhere, not just at $\mathbf{b}$, so the set of point-based alpha-vectors defines a value function over the whole simplex that lower-bounds the optimal one and improves monotonically. PBVI also grows $B$ over time by expanding to newly reachable beliefs, refining the approximation where the policy actually goes.
Two refinements dominate practice. Perseus (Spaan and Vlassis, 2005) is a randomized point-based backup: it backs up beliefs in random order and stops a sweep as soon as every sampled belief's value has improved, so a single backed-up vector often improves many beliefs at once, giving large speedups. SARSOP (Kurniawati, Hsu, and Lee, 2008), the current workhorse for moderate POMDPs, is smarter about which beliefs to sample: it maintains both a lower bound (alpha-vectors) and an upper bound on $V^{*}$ and uses them to guide sampling toward the optimally reachable belief space, the beliefs reached under near-optimal policies, pruning branches that the gap between bounds proves cannot be optimal. SARSOP routinely solves POMDPs with hundreds to thousands of states that are far beyond any exact method.
Take a three-state POMDP and a point-based solver that has returned three alpha-vectors, $\boldsymbol{\alpha}_1 = (10, 0, -2)$, $\boldsymbol{\alpha}_2 = (1, 8, 1)$, $\boldsymbol{\alpha}_3 = (-3, 2, 9)$, each tagged with the action it recommends (say left, listen, right). At the belief $\mathbf{b} = (0.2, 0.7, 0.1)$ we evaluate each inner product: $\boldsymbol{\alpha}_1 \cdot \mathbf{b} = 10(0.2) + 0(0.7) - 2(0.1) = 1.8$; $\boldsymbol{\alpha}_2 \cdot \mathbf{b} = 1(0.2) + 8(0.7) + 1(0.1) = 5.9$; $\boldsymbol{\alpha}_3 \cdot \mathbf{b} = -3(0.2) + 2(0.7) + 9(0.1) = 1.7$. The maximum is $\boldsymbol{\alpha}_2$ at $5.9$, so $V(\mathbf{b}) = 5.9$ and the agent takes the action listen tagged on $\boldsymbol{\alpha}_2$. Notice that the belief is concentrated on state $s_2$ (mass $0.7$), and the winning alpha-vector is precisely the one that rewards being in $s_2$: the max-inner-product rule automatically selects the plan suited to where the agent thinks it is. This is exactly the lookup the from-scratch solver of subsection five performs at every step.
The trade point-based methods make is clean and worth stating precisely. They give up the guarantee of exactness: the returned value function is a lower bound on $V^{*}$, tight at and near the sampled beliefs, looser elsewhere, and the policy it induces is near-optimal rather than optimal, with the gap controllable by sampling more beliefs. In exchange they convert an intractable problem into a tractable one: the representation size is bounded by the number of sampled beliefs, not the horizon, and the per-sweep cost is polynomial. For the moderate POMDPs that arise in robotics navigation, dialogue management, and medical decision support, point-based methods with SARSOP are the default offline solver, and we use the offline-solve-then-deploy pattern in the practical example below.
The deep reason point-based methods work is almost philosophical: a competent agent simply never finds itself at most beliefs. To reach a belief that is exactly $(0.31, 0.31, 0.38)$ over three states you would need a precise, improbable sequence of observations, and even if you reached it once you would essentially never return. The reachable belief set is a thin, fractal-looking thread winding through the simplex, and the vast interior is a ghost town the agent never visits. Exact value iteration politely computes the value of every ghost town anyway; point-based methods send a scout down the thread the agent will actually walk and compute the value only there. It is the difference between mapping every grain of sand on a beach and mapping the one path to your towel.
3. Online Planning: POMCP and DESPOT Advanced
Point-based methods are offline: they solve the whole (reachable) problem once, producing a policy that maps any belief to an action, then deploy it. Online planning takes the opposite stance. It does no precomputation; instead, at each decision point, it plans from the current belief only, searching forward a limited horizon to choose the next action, then executes that action, observes, updates the belief, and replans. This is the POMDP analogue of model predictive control: solve a local lookahead afresh at every step. The advantage is that online planning never represents the value over the whole simplex, so it scales to enormous state spaces where even point-based methods choke; the cost is per-step computation and the need for a fast simulator of the POMDP.
The two dominant online planners both run Monte Carlo tree search (MCTS) in belief space, and both sidestep the central difficulty of online POMDP planning, which is that the belief itself is expensive to represent and update exactly in a large state space. Their shared trick is to represent the belief not as an explicit distribution but as a particle filter, a weighted set of sampled states, exactly the unweighted-particle and resampling machinery developed for nonlinear filtering in Section 7.4. The belief-MDP-to-particle-filter callback is direct: the sequential Monte Carlo that tracked a continuous latent state under nonlinear dynamics in Chapter 7 is reused here to track the discrete (or continuous) hidden state of a POMDP during planning, with the simulator playing the role of the dynamics and observation models.
POMCP (Partially Observable Monte Carlo Planning, Silver and Veness, 2010) marries that particle-filter belief to UCT, the upper-confidence-bound tree search of Chapter 22. It builds a search tree whose nodes are action-observation histories; at each node it stores a set of particles approximating the belief there. A simulation samples a state from the root particle set, then descends the tree choosing actions by UCB and observations by simulating the model, expanding the tree and running a rollout at the frontier, and finally backs up the return along the path. After a budget of simulations it plays the root action with the highest mean return. POMCP needs only a generative simulator (sample next state, observation, reward), never the explicit $T$ and $Z$ tables, so it handles POMDPs with millions of states. DESPOT (Determinized Sparse Partially Observable Tree, Ye, Somani, Hsu, and Lee, 2017) sharpens this by searching a sparse tree built from a small set of deterministic sampled "scenarios" (fixed random seeds), which dramatically reduces the variance and branching of the search and admits a regret bound; DESPOT and its successors are the strongest online POMDP planners for large problems and underpin much of modern autonomous-driving decision-making.
Suppose a robot's belief over $\{s_{\text{left}}, s_{\text{right}}\}$ is carried by $K = 1000$ particles, $600$ at $s_{\text{left}}$ and $400$ at $s_{\text{right}}$, so the implied belief is $(0.6, 0.4)$. The robot takes action listen and the observation model says a noisy "hear-left" sensor reads correctly with probability $0.85$. After observing "hear-left", we reweight each particle by the observation likelihood: left particles get weight $0.85$, right particles get $0.15$. The unnormalized mass is $600(0.85) = 510$ on left and $400(0.15) = 60$ on right; normalizing gives a posterior belief of $(510 / 570, 60 / 570) \approx (0.895, 0.105)$. Resampling $1000$ particles from these weights yields roughly $895$ left and $105$ right particles, the new belief, ready for the next planning iteration. This is the Section 7.4 particle update operating inside the POMCP tree, and it is why online planners need no explicit belief vector: the particle cloud is the belief.
The mental model that unifies the two planner families is search-versus-solve. Point-based methods solve: they invest heavy offline computation to produce a policy good everywhere on the reachable simplex, amortized over many deployments. Online planners search: they invest light per-step computation to produce a good action here and now, paying the cost again at every step but never needing to represent the global value. The choice between them, the subject of subsection four, turns on whether the state space is small enough to solve offline and whether you can afford per-step planning latency at deployment.
The frontier is fusing the belief-state rigor of this section with deep learning. Learned belief representations replace the explicit particle filter with a recurrent or state-space encoder that compresses the history into a latent belief, the approach taken by the recurrent and SSM-based agents of Section 23.3 and by the world-model agents of Chapter 29 (DreamerV3, 2023 to 2024, plans in a learned latent belief). Neural-network-guided online search brings AlphaZero-style learned value and policy priors to POMCP and DESPOT, cutting the simulation budget by an order of magnitude; recent work (2023 to 2025) on differentiable particle filters and on combining DESPOT with learned heuristics targets exactly the autonomous-driving and robotic-manipulation settings where the state space defeats classical solvers. A third thread asks whether large sequence models can implicitly solve POMDPs by in-context belief tracking, connecting to the Decision Transformer line of Chapter 28. The 2026 practitioner's reality: SARSOP and DESPOT remain the reliable classical baselines, but learned belief states and neural search guidance are where partial-observability research is moving, and the line between "solving a POMDP" and "training a sequence model" is blurring.
4. When to Use What, and the Bridge to Model-Free Agents Intermediate
With four families on the table, exact value iteration, point-based offline solvers, online tree search, and (next section) model-free belief-free agents, the practitioner needs a decision rule rather than a catalogue. The choice is governed by three questions: how large is the state space, do you have an explicit model or only a simulator, and can you afford per-step planning latency at deployment. Figure 23.2.2 lays out the answer.
| Method | Best when | Needs | Output | Scale (states) |
|---|---|---|---|---|
| Exact VI (incremental pruning, Witness) | tiny problem, exactness required, proofs/teaching | explicit $T, Z, R$ | optimal alpha-vector set | $\lesssim 10$ |
| Point-based (SARSOP, Perseus, PBVI) | moderate problem, fixed model, plan once and deploy | explicit $T, Z, R$, initial belief | near-optimal alpha-vectors (a policy) | $10^2$ to $10^4$ |
| Online (POMCP, DESPOT) | huge or unknown state space, per-step planning affordable | generative simulator only | one good action per step | $10^4$ to $10^7{+}$ |
| Model-free recurrent agent (Section 23.3) | no model, learn from interaction, latent belief is enough | environment to interact with, rewards | a reactive policy (no explicit belief) | unbounded (function approx.) |
The three rows above all share a commitment that the fourth abandons: they reason explicitly about the belief, the posterior over states, and they require (point-based, exact) or simulate (online) a model of the world. That commitment is a strength when a model is available and a liability when it is not. Real systems, a dialogue agent facing an unknown user, a trading agent in a market it cannot simulate, a robot in an unmodeled environment, often have no clean $T$ and $Z$ to hand. For them the question becomes: can we get the benefit of belief-state reasoning without ever writing down the belief or the model?
Section 23.1 proved that the belief $\mathbf{b}_t$ is a sufficient statistic of the history: act optimally on the belief and you act optimally, period. Everything in this section computes that belief explicitly and plans over it. But sufficiency cuts both ways. If a recurrent network's hidden state can be trained to carry whatever information about the history the policy needs, then that hidden state is functioning as a belief, learned implicitly from reward rather than computed from a model. This is the conceptual bridge to Section 23.3: a model-free recurrent agent does not maintain $\mathbf{b}_t$ or know $T$ and $Z$; it learns a hidden state $\mathbf{h}_t = f(\mathbf{h}_{t-1}, \mathbf{o}_t, \mathbf{a}_{t-1})$ that summarizes the past well enough to act, exactly the recurrence of Chapter 9 repurposed as a belief tracker. The explicit belief and the learned hidden state are two solutions to one problem: compress the history into a sufficient statistic for action.
This is the temporal thread of this book closing another loop. The Kalman filter and HMM of Chapter 7 tracked a latent state with a known model; the RNN of Chapter 9 learned to track latent structure from data; here the POMDP belief is the Bayesian latent-state tracker made into a decision-maker, and Section 23.3 will hand that tracking job to a learned recurrent or state-space network. Same loop, $\mathbf{h}_t = f(\mathbf{h}_{t-1}, \cdot)$, three incarnations: filtered, learned, and now acting. The explicit-belief methods of this section are the principled, model-based end of that spectrum; the model-free agents of the next section are the scalable, model-free end. Knowing both, and when each is the right tool, is the point of the chapter.
5. Worked Example: Solving the Tiger Problem Advanced
We now make the alpha-vector machinery executable on the canonical small POMDP, the Tiger problem (Kaelbling, Littman, and Cassandra, 1998). The agent stands before two doors; behind one is a tiger, behind the other a reward. The hidden state is $s \in \{\text{tiger-left}, \text{tiger-right}\}$. The agent can listen (cost $-1$, and receive a noisy observation that correctly localizes the tiger with probability $0.85$), open-left, or open-right (opening the door without the tiger gives $+10$, opening the door with the tiger gives $-100$, and resets the problem). The tension is exactly the information-gathering behavior promised in the introduction: the agent must decide whether its current belief is sharp enough to open a door or whether to pay to listen again. Code 23.2.1 builds the model and a from-scratch one-step alpha-vector backup, then evaluates the value and best action across the belief simplex.
import numpy as np
# --- Tiger POMDP model (states: 0 = tiger-left, 1 = tiger-right) ---
S = [0, 1] # hidden states
A = ["listen", "open-left", "open-right"] # actions
O = [0, 1] # observations: 0 = hear-left, 1 = hear-right
gamma = 0.95
# Reward R[a][s]: expected immediate reward of action a in state s.
R = {
"listen": np.array([-1.0, -1.0]), # listening always costs 1
"open-left": np.array([-100.0, 10.0]), # tiger-left: open-left is disaster
"open-right": np.array([10.0, -100.0]), # tiger-right: open-right is disaster
}
# Observation model Z[a][s', o]: P(observe o | next-state s', action a).
LISTEN_ACC = 0.85
Z_listen = np.array([[LISTEN_ACC, 1 - LISTEN_ACC], # s'=tiger-left -> mostly hear-left
[1 - LISTEN_ACC, LISTEN_ACC]]) # s'=tiger-right -> mostly hear-right
# Opening a door resets the problem; observations become uninformative (0.5, 0.5).
Z_open = np.array([[0.5, 0.5], [0.5, 0.5]])
Z = {"listen": Z_listen, "open-left": Z_open, "open-right": Z_open}
# Transition: listen keeps the state; opening resets to a uniform 50/50 over states.
T = {
"listen": np.eye(2),
"open-left": np.array([[0.5, 0.5], [0.5, 0.5]]),
"open-right": np.array([[0.5, 0.5], [0.5, 0.5]]),
}
def backup(Gamma):
"""One exact alpha-vector backup: Gamma (list of vectors) -> new set."""
new_alphas = []
for a in A:
# For each observation, the best future alpha-vector is chosen per state s'.
# Build, for every assignment o -> future alpha, the backed-up vector.
# With |O|=2 and |Gamma| future vectors there are |Gamma|^2 assignments.
for alpha_o0 in Gamma: # future plan if we observe o=0
for alpha_o1 in Gamma: # future plan if we observe o=1
alpha = R[a].copy() # immediate reward term R(s,a)
for s in S: # add discounted future for each start state
fut = 0.0
for sp in S: # sum over next states s'
fut += T[a][s, sp] * (
Z[a][sp, 0] * alpha_o0[sp] +
Z[a][sp, 1] * alpha_o1[sp])
alpha[s] += gamma * fut
new_alphas.append((a, alpha))
return new_alphas
def prune(alphas, grid=201):
"""Drop alpha-vectors that are never the max over a fine belief grid."""
bs = np.linspace(0, 1, grid)
keep = {}
for b in bs:
belief = np.array([b, 1 - b])
a, alpha = max(alphas, key=lambda av: av[1] @ belief) # winner at this belief
keep[tuple(np.round(alpha, 6))] = (a, alpha) # dedupe by value
return list(keep.values())
# Value iteration: start from the zero vector and back up a few times.
Gamma = [np.zeros(2)]
for _ in range(8): # 8-step horizon
raw = backup(Gamma)
Gamma_pairs = prune(raw)
Gamma = [al for (_, al) in Gamma_pairs]
# Evaluate value and best action across the belief simplex.
print("alpha-vectors after pruning:", len(Gamma_pairs))
for b in [0.0, 0.3, 0.5, 0.7, 1.0]:
belief = np.array([b, 1 - b]) # b = P(tiger-left)
a, alpha = max(Gamma_pairs, key=lambda av: av[1] @ belief)
print(f"b(tiger-left)={b:.2f} V={alpha @ belief:7.3f} best action: {a}")
backup function implements the alpha-vector backup equation of subsection one, enumerating one vector per (action, observation-to-future-plan assignment); prune keeps only the vectors that dominate somewhere on a fine belief grid, the practical stand-in for the linear-program pruning of exact solvers. The final loop reads off value and best action across the simplex.alpha-vectors after pruning: 23
b(tiger-left)=0.00 V= 14.355 best action: open-left
b(tiger-left)=0.30 V= 5.838 best action: listen
b(tiger-left)=0.50 V= 5.324 best action: listen
b(tiger-left)=0.70 V= 5.838 best action: listen
b(tiger-left)=1.00 V= 14.355 best action: open-right
The numeric payoff is the action map: confident beliefs trigger a door-opening, uncertain beliefs trigger listening. That is precisely the choosing-the-best-action-at-a-given-belief computation, and it is nothing but the max-inner-product lookup of subsection one. Now the library pair. The pomdp-py library (Zheng and Tellex, 2020) provides the Tiger model and a battery of solvers; Code 23.2.2 solves the same problem with its value-iteration solver in a handful of lines.
import pomdp_py
from pomdp_py.problems.tiger import TigerProblem # built-in Tiger model
# Build the Tiger POMDP with an initial uniform belief over the two states.
init_true_state = "tiger-left"
init_belief = pomdp_py.Histogram({"tiger-left": 0.5, "tiger-right": 0.5})
tiger = TigerProblem(0.85, init_true_state, init_belief) # 0.85 = listen accuracy
# Exact value iteration over the belief space (horizon 8, same as from scratch).
vi = pomdp_py.ValueIteration(horizon=8, discount_factor=0.95)
policy = vi.plan(tiger.agent) # solve: returns a policy tree
# Query the recommended action at a few beliefs.
for p_left in [0.05, 0.5, 0.95]:
b = pomdp_py.Histogram({"tiger-left": p_left, "tiger-right": 1 - p_left})
tiger.agent.set_belief(b)
print(f"P(tiger-left)={p_left:.2f} -> action: {policy.plan(tiger.agent)}")
pomdp-py. The library ships the model, the belief representation (Histogram), and an exact ValueIteration solver; the entire backup, pruning, and policy-extraction logic of Code 23.2.1 collapses to two calls, vi.plan(...) and policy.plan(...).P(tiger-left)=0.05 -> action: TigerAction(open-left)
P(tiger-left)=0.50 -> action: TigerAction(listen)
P(tiger-left)=0.95 -> action: TigerAction(open-right)
Read the two code blocks together. Code 23.2.1 implemented the alpha-vector backup, the grid-based pruning, and the value-and-action readout of subsections one and two by hand, roughly 60 lines. Code 23.2.2 reproduced the identical policy with about 8 lines of pomdp-py: the from-scratch backup-and-prune machinery collapses to two library calls, an order-of-magnitude line-count reduction, with the alpha-vector enumeration, dominated-vector pruning, and policy-tree construction all handled internally. The library also exposes SARSOP (point-based) and POMCP (online) solvers behind the same interface, so scaling from the toy Tiger to a thousand-state problem is a one-line solver swap, not a rewrite.
Who: A team building a voice assistant's dialogue manager for a flight-booking service, where the user's true intent is hidden and speech recognition is noisy.
Situation: The hidden state is the user's goal (origin, destination, date), never observed directly; each user utterance is a noisy observation filtered through an error-prone speech recognizer, exactly a POMDP with a large but structured state space.
Problem: A purely reactive system that acted on the single most likely recognized intent confirmed too rarely and booked wrong flights when recognition erred; it needed to reason about its uncertainty and ask clarifying questions when, and only when, the belief warranted it.
Dilemma: Exact value iteration was hopeless at the state-space size. Online POMCP could run but added latency to every turn and needed a fast user simulator. An offline point-based policy would have low per-turn latency but required solving the model once.
Decision: They modeled intent slots as a factored POMDP and solved it offline with SARSOP, producing an alpha-vector policy that mapped the current belief over user goals to either a confirm, an ask-clarify, or a book action, the dialogue analogue of Tiger's listen-versus-open decision.
How: At each turn the system updated its belief with the speech-recognition likelihood (the particle-style reweighting of subsection three), then looked up the best action by the max-inner-product rule over the SARSOP alpha-vectors, asking a clarifying question precisely when the belief was too diffuse to act safely.
Result: The POMDP policy asked for clarification adaptively, more when recognition confidence was low, and cut mis-bookings substantially versus the reactive baseline, because it valued information-gathering exactly as the Tiger agent values listening.
Lesson: Partial observability plus a cost of acting wrong equals a POMDP, and the alpha-vector policy turns "how sure am I?" into a principled choose-to-clarify-or-act decision. Offline point-based solving (SARSOP) is the right tool when the model is known and per-turn latency must stay low.
The from-scratch solver of Code 23.2.1 ran about 60 lines of backup-and-prune bookkeeping for a two-state toy. pomdp-py collapses the model, the belief, the exact backup, the pruning, and the policy extraction to roughly 8 lines (Code 23.2.2), and the same interface swaps in pomdp_py.sarsop (point-based, subsection two) or pomdp_py.POMCP (online tree search, subsection three) with a single line change. For Python the practical stack is: pomdp-py for prototyping and the classic algorithms; the C++ SARSOP reference implementation (APPL toolkit) and despot for production-scale offline and online solving respectively. The library handles alpha-vector dominance pruning by linear programming (not a grid), particle-filter belief tracking, and the UCT bookkeeping of POMCP internally, the parts most error-prone to write by hand.
6. Summary and What You Can Now Do
This section turned the belief MDP of Section 23.1 into something solvable. The pivotal fact is the PWLC theorem: the optimal value function over the continuous belief simplex is the upper envelope of a finite set of alpha-vectors, so a function on an uncountable space reduces to bookkeeping over hyperplanes, and evaluating it is a max inner product. Exact value iteration over beliefs is correct but PSPACE-hard, its alpha-vector set exploding doubly exponentially in the horizon. Point-based methods (PBVI, Perseus, SARSOP) tame the explosion by computing value only at sampled reachable beliefs, the practical offline workhorse for moderate POMDPs. Online planners (POMCP, DESPOT) abandon offline solving entirely, running Monte Carlo tree search from the current belief with a particle filter, the same sequential Monte Carlo of Section 7.4, and so scale to enormous state spaces. The decision rule, exact for tiny, point-based for moderate-with-model, online for huge-with-simulator, sets up the bridge to Section 23.3, where model-free recurrent and state-space agents drop the explicit belief and learn a sufficient hidden state directly from reward. The Tiger solver, hand-rolled and then in pomdp-py, made every equation executable and showed the signature behavior of optimal POMDP control: gather information when uncertain, act when confident.
Concretely, you can now: represent a POMDP value function as alpha-vectors and read off value and best action by the max-inner-product rule; explain why exact solving is intractable and what point-based and online methods give up to scale; choose the right solver family for a given problem; and implement a small exact solver, then reach for pomdp-py, SARSOP, or DESPOT for anything larger. The next section, Recurrent and SSM-Based Agents for Partial Observability, takes the model-free road that this section's decision table pointed to.
7. Worked Example: Alpha-Vector Backup for the Tiger POMDP Intermediate
The alpha-vector backup equation and the PBVI update rule were stated in subsections one and two and executed by Code 23.2.1 in about 60 lines, but the code hides the arithmetic. This section strips every step down to arithmetic on small numbers so you can verify each calculation by hand and build the intuition that PBVI and SARSOP automate at scale. We work entirely in the two-state Tiger POMDP using the exact model defined in subsection five: states $S = \{\text{TL}, \text{TR}\}$ (tiger-left, tiger-right), actions $A = \{\text{OL}, \text{OR}, \text{L}\}$ (open-left, open-right, listen), observations $\Omega = \{\text{HL}, \text{HR}\}$ (hear-left, hear-right), discount $\gamma = 0.95$.
Step 1: One-step alpha-vectors ($\Gamma_1$, horizon = 1)
With a one-step horizon, the only return is the immediate reward. The alpha-vector for each action records $R(s, a)$ for every state $s$:
$\boldsymbol{\alpha}_{\text{OL}} = (R(\text{TL},\text{OL}),\; R(\text{TR},\text{OL})) = (-100,\; +10)$
$\boldsymbol{\alpha}_{\text{OR}} = (R(\text{TL},\text{OR}),\; R(\text{TR},\text{OR})) = (+10,\; -100)$
$\boldsymbol{\alpha}_{\text{L}} = (R(\text{TL},\text{L}),\; R(\text{TR},\text{L})) = (-1,\; -1)$
Evaluating each as a linear function of the belief $b = b(\text{TL}) \in [0, 1]$ (with $b(\text{TR}) = 1 - b$):
$V_{\text{OL}}(b) = -100 \cdot b + 10 \cdot (1-b) = 10 - 110b$ (steep negative slope)
$V_{\text{OR}}(b) = +10 \cdot b - 100 \cdot (1-b) = -100 + 110b$ (steep positive slope)
$V_{\text{L}}(b) = -1 \cdot b - 1 \cdot (1-b) = -1$ (horizontal line)
The upper envelope of these three lines is the one-step optimal value $V_1(b) = \max(V_{\text{OL}}, V_{\text{OR}}, V_{\text{L}})$. The crossover beliefs where listen starts dominating are found by setting $V_{\text{L}} = V_{\text{OL}}$:
$-1 = 10 - 110b \Rightarrow b = 11/110 \approx 0.100$, and by symmetry $V_{\text{L}} = V_{\text{OR}}$ gives $b \approx 0.900$.
One-step policy: open-left when $b < 0.100$ (almost certain the tiger is on the right), open-right when $b > 0.900$ (almost certain the tiger is on the left), listen otherwise. This matches human intuition: you only open a door when you are very confident about which side the tiger is on.
Step 2: Belief update after one listen observation
Starting at the prior $\mathbf{b}_0 = (0.5, 0.5)$, the agent listens and observes "hear-left" (HL). The belief update (from Section 23.1) multiplies the predicted belief by the observation likelihood and renormalizes:
Unnormalized: $\tilde{b}(\text{TL}) = P(\text{HL} \mid \text{TL}, \text{L}) \cdot b_0(\text{TL}) = 0.85 \times 0.5 = 0.425$
Unnormalized: $\tilde{b}(\text{TR}) = P(\text{HL} \mid \text{TR}, \text{L}) \cdot b_0(\text{TR}) = 0.15 \times 0.5 = 0.075$
Normalizing constant: $\eta = 0.425 + 0.075 = 0.500$
$b_1(\text{TL}) = 0.425 / 0.500 = 0.850, \quad b_1(\text{TR}) = 0.075 / 0.500 = 0.150$
One hear-left moves the belief from $(0.5, 0.5)$ to $(0.85, 0.15)$: you now believe with 85% confidence the tiger is on the left. At $b = 0.85$, which is inside the listen region $(0.10, 0.90)$, the optimal one-step action is still to listen.
After a second hear-left from $b_1 = (0.85, 0.15)$:
$\tilde{b}(\text{TL}) = 0.85 \times 0.85 = 0.7225$, $\tilde{b}(\text{TR}) = 0.15 \times 0.15 = 0.0225$, $\eta = 0.745$
$b_2(\text{TL}) = 0.7225 / 0.745 \approx 0.970$
Now $b_2(\text{TL}) = 0.970 > 0.900$: the agent is confident enough. The optimal action switches to open-right (since the tiger is almost certainly on the left, the right door is safe).
Step 3: PBVI backup to compute the two-step alpha-vector for listen
PBVI extends the one-step $\Gamma_1$ set to a two-step set $\Gamma_2$ by one backup. We compute the backed-up alpha-vector for action $\text{L}$ at the starting belief $\mathbf{b}_0 = (0.5, 0.5)$. The backup equation for a single action $a$ with observation-to-future-plan assignment $o \mapsto \boldsymbol{\alpha}^o$ is:
$$\alpha^{\text{new}}_a(s) = R(s, a) + \gamma \sum_{s'} T(s' \mid s, a) \sum_{o} Z(o \mid s', a)\; \alpha^o(s')$$For action $\text{L}$: transitions keep the state ($T(\text{TL} \mid \text{TL}, \text{L}) = 1$, $T(\text{TR} \mid \text{TR}, \text{L}) = 1$), and the listen sensor is noisy ($Z(\text{HL} \mid \text{TL}, \text{L}) = 0.85$, $Z(\text{HR} \mid \text{TL}, \text{L}) = 0.15$, and flipped for TR).
At each observation, the best future alpha-vector from $\Gamma_1$ is selected by inner product with the post-observation belief. After observing HL from $\mathbf{b}_0 = (0.5, 0.5)$, we found $b_1 = (0.85, 0.15)$. Evaluating $\Gamma_1$ at that belief:
$V_{\text{OL}}(b_1) = 10 - 110(0.85) = 10 - 93.5 = -83.5$
$V_{\text{OR}}(b_1) = -100 + 110(0.85) = -100 + 93.5 = -6.5$
$V_{\text{L}}(b_1) = -1$
Best future plan given HL: $\boldsymbol{\alpha}^{\text{HL}} = \boldsymbol{\alpha}_{\text{L}} = (-1, -1)$ with value $-1$.
After observing HR from $\mathbf{b}_0$, the symmetric update gives $b(\text{TL}) = 0.15$, $b(\text{TR}) = 0.85$:
$V_{\text{OL}}(b) = 10 - 110(0.15) = 10 - 16.5 = -6.5$
$V_{\text{OR}}(b) = -100 + 110(0.15) = -100 + 16.5 = -83.5$
$V_{\text{L}}(b) = -1$
Best future plan given HR: $\boldsymbol{\alpha}^{\text{HR}} = \boldsymbol{\alpha}_{\text{L}} = (-1, -1)$ with value $-1$.
Now compute the backed-up alpha-vector for action L entry by entry. For state TL ($s = \text{TL}$, so $s' = \text{TL}$ under the identity listen transition):
$\alpha^{\text{new}}_{\text{L}}(\text{TL}) = R(\text{TL}, \text{L}) + \gamma \bigl[ Z(\text{HL} \mid \text{TL}, \text{L})\,\alpha^{\text{HL}}(\text{TL}) + Z(\text{HR} \mid \text{TL}, \text{L})\,\alpha^{\text{HR}}(\text{TL}) \bigr]$
$= -1 + 0.95 \bigl[ 0.85 \times (-1) + 0.15 \times (-1) \bigr]$
$= -1 + 0.95 \times (-1) = -1 - 0.95 = -1.95$
By symmetry, $\alpha^{\text{new}}_{\text{L}}(\text{TR}) = -1.95$ as well. So the backed-up listen vector is $\boldsymbol{\alpha}^{\text{new}}_{\text{L}} = (-1.95, -1.95)$, and $V_{\text{L}}^{(2)}(b) = -1.95$ for any belief: two steps of certain listening costs $-1 - 0.95 = -1.95$ in discounted total.
This one arithmetic example shows what every PBVI sweep does: pick the best future alpha-vector per observation, fold it back through the transition and observation probabilities, add the immediate reward. PBVI repeats this for every belief point in its set and every action, pruning dominated vectors. SARSOP does the same but chooses which belief points to back up by bounding the gap to the optimal value, concentrating effort on beliefs the optimal policy actually visits.
The step-by-step arithmetic above makes three things concrete that the code of Code 23.2.1 computes but does not narrate. First, the one-step policy thresholds ($b < 0.10$ for open-left, $b > 0.90$ for open-right) emerge directly from setting two alpha-vector lines equal: no optimization loop is needed, only high-school algebra applied to the reward differences. Second, the belief update compounds: two consistent hear-left observations drive the belief from 50% to 97%, crossing the action threshold and switching the policy, exactly the evidence-accumulation property that makes the POMDP listen before it acts. Third, the backup integral for action L collapses cleanly to $-1 - \gamma = -1.95$ because the listen sensor keeps both the state and the best future plan symmetric. Real POMDP problems break this symmetry across states and observations, which is why Code 23.2.1 enumerates all $|\Gamma|^{|\Omega|}$ assignments, but the arithmetic structure is identical to what you just traced by hand.
PBVI and SARSOP automate this three-step process across a set of sampled reachable beliefs. PBVI backs up every belief in $B$ each sweep, updating each belief's alpha-vector to the backed-up one with the highest value there, and periodically expands $B$ by simulating forward from the current best policy. SARSOP adds an upper bound on $V^*$ alongside the lower bound (the alpha-vectors), uses the gap to prioritize which beliefs to back up next, and prunes branches where the gap proves no reachable belief can benefit from further backup. In both cases the per-sweep cost is $O(|B| \cdot |A| \cdot |\Omega| \cdot |S|^2)$: linear in the number of sampled beliefs rather than doubly exponential in the horizon. The Tiger example finishes in milliseconds at an 8-step horizon because $|B|$ stays under 100 reachable beliefs; a thousand-state robotic navigation POMDP with SARSOP keeps $|B|$ in the hundreds to thousands, which is why point-based methods are the practical workhorse for moderate POMDPs while exact value iteration is reserved for teaching and tiny verification tasks.
Exercises
Argue from first principles why the optimal POMDP value function must be convex over the belief simplex, not merely piecewise-linear. Hint: consider two beliefs $\mathbf{b}_1, \mathbf{b}_2$ and their mixture $\lambda \mathbf{b}_1 + (1 - \lambda)\mathbf{b}_2$, and what extra freedom an agent has if it is told which of the two situations it is actually in versus only knowing the mixture. Relate your answer to the statement "information has nonnegative value" and explain why this means a belief near a simplex corner is worth at least as much as a blurred belief in the interior.
Extend the from-scratch Tiger code of Code 23.2.1 with a simple online planner. Represent the belief as $K = 500$ particles over $\{\text{tiger-left}, \text{tiger-right}\}$. At each decision, for each of the three actions run $M = 200$ Monte Carlo rollouts of depth $5$ (sample a state from the particle set, simulate the action's reward and a transition, recurse with a random policy), average the returns, and pick the best action. Update the particle belief by reweighting with the listen observation likelihood ($0.85$) and resampling, exactly the update in the subsection-three numeric example. Verify that your online planner reproduces the listen-when-uncertain, open-when-confident behavior of the exact solver, and report how the chosen action at $\mathbf{b} = (0.5, 0.5)$ changes as you increase the rollout count $M$.
Take any moderate POMDP from pomdp-py (for example RockSample or a small maze) and solve it twice: once with the offline SARSOP solver and once with the online POMCP planner. Compare not just average return but where they disagree on actions, and characterize the beliefs at which the online planner, limited by its simulation budget, departs from the offline near-optimal policy. Then connect your finding forward: argue informally whether a model-free recurrent agent of Section 23.3, which learns an implicit belief from reward, would be more likely to fail at the same beliefs (where information must be gathered carefully) or at different ones, and what that says about the price of dropping the explicit belief.