Dynamic Programming for MDPs
Imagine you are handed the complete blueprint of a warehouse robot's world. You know every possible state, every action's exact consequences, and every reward the robot could receive. There is no uncertainty left to learn — the model is fully known. The only question is computational: given this blueprint, how do you compute the best possible way to act? This is precisely the setting where dynamic programming (DP) for Markov Decision Processes shines. It turns the abstract Bellman Equations into concrete, iterative procedures. These procedures provably converge to optimal behavior. DP methods matter because they are the mathematical bedrock underneath almost all of modern reinforcement learning. Even though real-world agents rarely have a perfect model of their environment, some algorithms do learn from experience. These include Temporal-Difference Learning, Q-learning, and actor-critic methods. They are best understood as approximations of the exact DP updates described here. Understanding DP is understanding the target that model-free methods are chasing without a model. The big picture is this: an MDP defines a recursive relationship. This relationship connects the value of a state to the values of its successor states. It is captured by the Bellman equations. Dynamic programming exploits this recursive structure directly. Instead of solving a giant system of equations in one shot, DP methods repeatedly sweep over the state space. They update each state's value estimate using the current estimates of its neighbors. This technique is called bootstrapping. Because the updates use full knowledge of the transition and reward model, DP performs what are called full backups. These average over every possible next state rather than sampling one. This article builds the complete DP toolkit for MDPs. It shows how the Bellman equations become update rules. It explains why sweeping over the whole state space with bootstrapped estimates is guaranteed to converge. It covers what this costs computationally, and where the classic pitfalls lie. It sets up, but does not fully develop, three canonical algorithms. These are iterative policy evaluation, policy iteration, and value iteration. All three inherit this machinery directly.
- Dynamic programming solves MDPs by treating the Bellman equations as update rules, applied repeatedly over the entire state space.
- Bootstrapping means updating a value estimate using other current estimates, not final ground-truth values.
- Full backups average over every possible next state and reward, using the known transition model — no sampling needed.
- Convergence is guaranteed because the Bellman operator is a contraction mapping in the max-norm.
- DP requires a complete and accurate model of the environment; without one, these exact methods do not apply directly.
- DP's per-sweep cost scales with , making it exact but expensive for large state spaces — motivating sampling-based successors.
Dynamic programming turns the Bellman equations into iterative update rules that repeatedly bootstrap off full, model-based backups until the value estimates converge to the true values.
The idea
A Markov Decision Process is defined by states , actions , a transition model , a reward function, and a discount factor . The Bellman equations express the value of a state as a recursive sum over immediate reward plus the discounted value of the next state. For a fixed policy , the Bellman expectation equation is
For the optimal value function, the Bellman optimality equation replaces the average over actions with a maximum:
These are systems of equations in unknowns. In principle one could solve them directly with linear algebra (for , which is linear in ), but this requires inverting an matrix, which costs and becomes impractical as state spaces grow. Dynamic programming instead treats each Bellman equation as an assignment operator: replace the "" with "" and apply it repeatedly to every state, using the current estimates of the values on the right-hand side. This is bootstrapping: a value estimate is updated using other value estimates that are themselves still being refined, rather than using final, ground-truth outcomes. It is what distinguishes DP (and later, TD learning) from Monte Carlo methods, which wait for actual returns to unfold before updating anything. The second defining feature is the full backup. Because the model is completely known, each update can average over every possible next state and reward exactly, weighted by their true probabilities — no sampling, no estimation error from a finite number of trials. This is why DP methods, when they converge, converge to the exact value function, not an approximation contaminated by sampling noise. The cost of this exactness is that every single successor state must be enumerated and its probability known, which is precisely the requirement of having a complete model.
How it works
The mechanism is a repeated sweep: for each state, the algorithm consults the model, computes the Bellman backup, and updates the state's value. Two flavors of sweep matter for laying groundwork here.
Full policy evaluation sweep. Given a fixed policy , apply the Bellman expectation equation as an update rule to every state, repeatedly, until values stop changing appreciably. Each state's new value is a weighted average over the actions the policy would take, and within that, an average over the model's transition probabilities.
Full optimality sweep. Instead of averaging over actions according to a policy, take the maximum over actions at each state. This directly targets , without ever holding a fixed policy in hand — this is the operation underlying value iteration. Two implementation choices recur in every DP algorithm:
- Two-array vs. in-place updates. A synchronous sweep computes all new values from a frozen copy of the old array, then swaps. An in-place (asynchronous within a sweep) sweep overwrites values immediately, letting later states in the sweep see fresher information. In-place updates often converge faster in practice and still provably converge, though the convergence argument is slightly more delicate.
- Stopping criterion. Sweeps continue until the maximum change in any state's value, , drops below a small threshold .
Below is the generic template that both iterative policy evaluation and value iteration specialize. ``` function DP-SWEEP(states S, model P, R, gamma, V, mode):
# mode = "evaluate" (needs policy pi) or "optimize" delta = 0 for each state s in S: v_old = V[s] if mode == "evaluate": total = 0 for each action a with pi(a|s) > 0: q = 0 for each (s_next, r, prob) in P(s, a): q += prob (r + gamma V[s_next]) total += pi(a|s) q V[s] = total else if mode == "optimize": best_q = -infinity for each action a in A(s): q = 0 for each (s_next, r, prob) in P(s, a): q += prob (r + gamma * V[s_next]) best_q = max(best_q, q) V[s] = best_q delta = max(delta, abs(v_old - V[s])) return delta
function DP-SOLVE(states S, model P, R, gamma, theta, mode, pi=None): V = array of zeros, size |S| repeat: delta = DP-SWEEP(S, P, R, gamma, V, mode) until delta < theta return V ``` Every terminal (absorbing) state is defined to have value 0 and is either excluded from the sweep or handled with a trivial self-loop of value 0, which prevents the recursion from being ill-defined. This is the algorithm's essential base case: without a properly anchored terminal value, the recursive backups have nothing fixed to converge toward. The overall shape that DP work builds toward is: 1. Iterative policy evaluation — repeatedly runs the `"evaluate"` sweep for a fixed until . 2. Policy iteration — alternates full evaluation with a policy improvement step (greedify the policy with respect to the current ), provably converging to . 3. Value iteration — runs the `"optimize"` sweep directly, folding evaluation and improvement into a single update, converging to .
Complexity & correctness
Time complexity per sweep. For each of the states, the update considers up to actions, and for each action sums over up to possible successor states (the transition model can, in the worst case, connect any state to any other). This gives
per full sweep. In practice, transition models are usually sparse — each pair has only possible successors — reducing the cost to . The number of sweeps needed for convergence to a fixed tolerance is not bounded by a fixed constant in general, but is controlled by the contraction rate , discussed below; for value iteration, an -accurate value function is reached in sweeps in the worst case, giving a total cost polynomial in , , and .
Space complexity. DP needs to store one value per state, , plus (for policy-based variants) one action per state, — dominated by the model itself, which if stored explicitly is in the dense case.
Correctness: why bootstrapped full backups converge. Define the Bellman optimality operator acting on any value function by
The DP optimality sweep is exactly the iteration . The correctness argument rests on two facts. Fact 1 — is a contraction in the max-norm. For any two value functions ,
This follows because the max over actions and the weighted sum over successor states are both non-expansive operations (a max of differences is bounded by the max absolute difference, and a convex combination is bounded by the largest term), and each term differs only through the component, contributing exactly one factor of . Fact 2 — is the unique fixed point of . This is precisely the statement of the Bellman optimality equation: , and by the Banach fixed-point theorem, since is a -contraction on a complete metric space ( with the max-norm) and , has exactly one fixed point, and iterating from any starting point converges to it:
This is why bootstrapping is safe here: even though is not correct, applying repeatedly provably shrinks the error geometrically, regardless of the (finite) starting guess. The same contraction argument applies to the Bellman expectation operator for a fixed policy, giving convergence of iterative policy evaluation to .
Tradeoffs. DP is exact and convergence is mathematically guaranteed, but it requires: 1. A complete, correct model — unavailable in most real applications. 2. Enumerating every state — infeasible when is astronomically large or continuous (the curse of dimensionality). 3. A full sweep over all states even if most of them are irrelevant to the optimal policy from a given start state — motivating asynchronous and prioritized variants, and eventually sample-based methods that only visit states the agent actually encounters.
Worked example
Consider a tiny 1-D "corridor" MDP with states plus an absorbing goal (value fixed at 0) reachable from state 3. The agent can move `Right` (deterministic) or `Stay` (deterministic), reward per step until reaching , discount for finite-horizon simplicity within this trace (we use to keep the contraction visibly at work). Fixed policy : always choose `Right`. Transition model: from state , `Right` leads deterministically to ; from state 3, `Right` leads to (value 0, absorbing). We run iterative policy evaluation (the `"evaluate"` sweep with a deterministic policy, so the average over actions collapses to the single chosen action):
| Sweep | ||||
|---|---|---|---|---|
| 0 (init) | 0.000 | 0.000 | 0.000 | — |
| 1 | 1.000 | |||
| 2 | 0.900 | |||
| 3 | 0.810 | |||
| 4 | 0.000 |
(Sweep 3 uses the previous sweep's values for state 2 and 3 under synchronous updates; by sweep 4 the values stop changing — the sweep has converged.) Notice this matches the closed-form geometric series exactly: , , , confirming the DP sweep reached the true under this policy, not merely something close to it. Now switch the sweep to `"optimize"` mode, introducing a second action `Stay` (self-loop, reward , clearly suboptimal here since it never reaches the goal). At each state the max over `Right`, `Stay` will always select `Right`, since `Stay` produces an infinite loop of rewards discounted forever, i.e. value , far worse than any finite path to the goal. This is a direct illustration of the maximization step in the Bellman optimality backup pruning away a clearly bad action — the same mechanism value iteration will use, sweep after sweep, to discover and, from it, .
Common pitfalls & traps
| Pitfall | Why it happens | Fix |
|---|---|---|
| Forgetting terminal-state anchoring | Recursion has no fixed reference point, values drift or never stabilize | Explicitly fix and exclude/self-loop it in the sweep |
| Using with no terminal or absorbing structure | Sums diverge, contraction argument fails ( is no longer a contraction) | Require , or guarantee termination with probability 1 |
| Confusing full backup with sample backup | Assuming a single sampled transition suffices, introducing bias/variance not present in true DP | Full backups must sum over all weighted by |
| Off-by-one in stopping threshold | Sweeping one extra/too-few iteration, reporting non-converged as final | Compare to after a full sweep, not mid-sweep |
| Treating in-place updates as unsound | Assuming only two-array (Jacobi-style) sweeps converge | In-place (Gauss–Seidel-style) sweeps still contract and typically converge faster |
| Ignoring the model-accuracy assumption | Applying DP with an approximate or learned model and expecting exactness | DP correctness is contingent on being exactly correct |
Pioneers & history
Origins · 1 minRichard E. Bellman and how this was discovered
Bellman coined the term "dynamic programming" while working on multistage decision processes at RAND in the 1950s, formalizing the principle of optimality: an optimal policy has the property that, whatever the initial decision, the remaining decisions must themselves be optimal with respect to the state resulting from the first. This principle is exactly what licenses the recursive Bellman equations, and by extension every DP algorithm for MDPs built on top of them.
Where this matters
Exact DP for MDPs underlies planning modules in robotics and operations research whenever a reliable simulator or transition model exists — inventory management, elevator scheduling, and network routing problems have all been solved historically with policy iteration or value iteration on hand-built models. In modern deep RL, DP is less often run to convergence on the full state space (too large), but its update rule is the direct ancestor of the Temporal-Difference Learning update used in Q-learning, SARSA, and actor-critic methods, all of which replace the exact expectation over successor states with a sampled successor, trading exactness for scalability. Model-based reinforcement learning systems, including those that learn a model and then plan with it (e.g., Dyna-style architectures, MuZero-style planning with a learned model), essentially run truncated or approximate DP sweeps inside a larger learning loop. Understanding DP correctly is therefore a prerequisite for understanding almost every value-based deep RL algorithm as an approximation of a known-convergent ideal.
Ask the tutor: How does the choice between synchronous and in-place sweeps affect the number of iterations needed for value iteration to converge in practice?
Is dynamic programming here the same as the DP used in algorithms like knapsack or edit distance?
Yes, in spirit. Both rely on optimal substructure — an optimal solution to the whole problem can be built from optimal solutions to subproblems — and both use memoization/iteration over overlapping subproblems to avoid recomputation. The MDP version is distinctive because the "subproblems" are states linked by a probabilistic transition model, and the recursion (the Bellman equation) is defined over an expectation rather than a deterministic recurrence. The underlying principle, Bellman's principle of optimality, is literally the mathematical justification shared by both settings.
Why does dynamic programming require a model, and what happens without one?
Every DP backup needs to compute an exact expectation over all possible successor states and rewards. Without this model, you cannot perform the sum in the Bellman equation directly. Model-free methods like TD-learning and Q-learning respond to this gap by replacing the exact expectation with a sample-based estimate from actual or simulated experience, updating toward a sampled successor's value instead of averaging over all successors. This is a strictly weaker guarantee per update (introducing variance) but removes the requirement of ever knowing the model explicitly.
What is the difference between synchronous and in-place (asynchronous) DP sweeps?
A synchronous sweep computes every state's new value from a frozen snapshot of the previous sweep's values, then updates all states at once — clean for analysis, easy to parallelize. An in-place sweep updates values one at a time, immediately using freshly updated neighbors within the same sweep. In-place updates often converge in fewer sweeps because information propagates faster, and they still converge under the same contraction argument, since each individual update is still a valid application of a contracting operator, just interleaved differently.
Does dynamic programming for MDPs always converge in a finite number of steps?
Not exactly — convergence to or in the continuous-value sense is asymptotic, guaranteed only in the limit, since the contraction shrinks error by a factor of each sweep but never reaches exactly zero error in finitely many steps for irrational error ratios. In practice, algorithms stop when the maximum change across a sweep drops below a small threshold , which gives a provably bounded approximation error, not exact equality. Policy iteration is a notable exception: because there are only finitely many deterministic policies, it terminates in a genuinely finite number of iterations once no policy improvement is possible.
How does the "curse of dimensionality" affect dynamic programming for MDPs?
Each additional state variable multiplies the size of the state space, since the state space is typically the Cartesian product of variable domains. A DP sweep's cost scales at least linearly in (more realistically for dense models), so state spaces with many variables become computationally intractable to sweep exhaustively, even though the algorithm remains mathematically well defined. This is the central practical motivation for approximate DP, function approximation, and sampling-based reinforcement learning, all of which sacrifice some exactness to escape this scaling wall.
What is the connection between DP's Bellman operator and the later algorithms it foreshadows?
Iterative policy evaluation is exactly repeated application of the Bellman expectation operator for a fixed policy. Policy iteration alternates this evaluation with a greedy policy-improvement step, provably producing a monotonically improving sequence of policies that terminates at . Value iteration instead applies the Bellman optimality operator directly, without ever holding a policy fixed, converging straight to . All three inherit their correctness from the same contraction-mapping argument described here — they differ only in which operator is applied and how the resulting values are turned into a policy.
Can DP methods handle stochastic rewards and stochastic transitions equally well?
Yes — the full backup already sums over the joint distribution of next state and reward, so stochasticity in either dimension is handled identically, as long as this joint distribution is fully known. The only requirement is that the sum (or integral, in continuous cases) be computable; highly complex or continuous reward distributions can make the backup expensive or require discretization, but the correctness argument via the contraction property does not change with the source of the randomness.