Policy Evaluation
Given a fixed policy, policy evaluation scores every state by the return that policy earns from there, sweeping Bellman backups until the numbers stop moving.
Why Does This Exist?
You cannot improve a policy you have not measured. If you change actions without knowing what the current ones earn, you might trade a slow starter for a fast loser. Policy evaluation is the measuring step: for a fixed policy it computes the state value function, the expected discounted return from every state.
This is the prediction half of control. Dynamic programming splits control into two jobs, and this page covers the first. Its sibling, policy improvement, covers the second: acting greedily on the values found here. Alternating the two gives policy iteration.
The one idea you need first
A state value is the expected return from state while following policy . Return means discounted cumulative reward, , where the discount factor in says a reward tomorrow is worth less than one today. The Bellman equations page writes this expectation recursively; here we turn that recursion into an algorithm.
Think of It Like This
Grading a fixed bus timetable
A transport inspector must grade a bus timetable she cannot change. Every bus runs its posted route, and she rides each one, noting fares collected now plus the fares the same timetable will collect later, discounted because late money counts less.
Her first pass records only fares collected today. Her second pass adds the discounted fares those same buses collect tomorrow. Each pass reaches one stop further back along the route. The adjustments shrink every pass, and when no stop's grade moves by more than a cent, she stops. She never changed a single departure. She just knows exactly what the timetable is worth from every stop.
The analogy stops where models stop: it assumes she knows every fare and transfer probability exactly. Real agents usually must learn them from samples.
How It Actually Works
For a fixed policy , the true values satisfy the Bellman expectation equation. The symbol is the probability of taking action in state , is the probability of landing in with reward , and is the discount factor:
In words: average over the actions your policy takes, then over everything the environment might do, of immediate reward plus discounted successor value. Solving this linear system directly costs , so we iterate instead. Start anywhere, arbitrary with terminal states at zero, and sweep:
The backup is a contraction with factor : the worst error shrinks by at least each sweep, so the sequence converges to the unique from any start. Stop when the largest single-state move falls below a small threshold :
The final error is bounded by , so pick with that multiplier in mind.
Worked example
Three stops in a line lead to a terminal: paying , paying , terminal paying . Discount , threshold . Start at .
Sweep 1 uses only immediate rewards, so and . Only the stop beside the payout knows anything yet.
Sweep 2 backs the payout one stop further: , giving and .
Sweep 3 reaches the far stop: , giving . Sweep 4 changes nothing, so and we stop at . One sweep per stop of distance: that is the rhythm to remember.
Code
This snippet runs the worked example with plain sweeps, so you can watch the values propagate one stop per pass.
def evaluate_chain(gamma: float = 0.9, theta: float = 0.05): """Bellman sweeps on s1 -> s2 -> s3 -> terminal(+10).""" values = [0.0, 0.0, 0.0] # [V(s1), V(s2), V(s3)] rewards = [0.0, 0.0, 10.0] successors = [1, 2, None] sweep = 0 while True: sweep += 1 delta = 0.0 nxt = values[:] for i in range(3): target = rewards[i] if successors[i] is None else rewards[i] + gamma * values[successors[i]] delta = max(delta, abs(target - values[i])) nxt[i] = target values = nxt if delta < theta: break return sweep, [round(v, 1) for v in values]
print(evaluate_chain())Watch Out For
Stopping before distant rewards arrive
Each sweep carries reward information back exactly one transition. With a loose threshold the loop quits while far states still read zero, and the next improvement step then acts on ignorance.
Symptom: states far from any reward keep value zero while near ones look settled. Fix: watch per sweep and confirm it decayed geometrically near rate before trusting the values. Inside policy iteration you can stop early on purpose, but then do it knowingly, not by accident.
Setting the threshold without the gamma multiplier
A threshold of sounds precise, but the true error can be , which is when and when .
Symptom: greedy actions flip between runs that differ only in . Fix: divide your error budget by that multiplier first, then set . High discount demands a far tighter threshold for the same accuracy.
The Quick Version
- Policy evaluation computes , the expected discounted return of a fixed policy from every state.
- It sweeps the Bellman expectation backup until the largest single-state change drops below .
- The backup is a contraction with factor , so convergence from any start is guaranteed.
- Reward news travels one transition per sweep, as 0.0 became 8.1, 9.0 and 10.0 across three passes here.
- True error can reach , so tighten as nears 1.