Generalized Policy Iteration (GPI)
GPI is the shared loop behind most RL: estimate how good the current policy is, then make the policy greedier, and repeat until neither can improve.
Why Does This Exist?
You need values to improve a policy, and you need a policy to define values. That circle is the whole difficulty. Policy evaluation fixes behavior and measures return. Greedy improvement fixes values and picks better actions. Doing either one perfectly before touching the other wastes work, because each step invalidates the other.
Sutton and Barto named the general pattern GPI. It says the two processes can interleave at any grain, from full sweeps to single samples, and still head to the same optimum. That one idea turns policy iteration, value iteration, SARSA, Q-learning and actor critic into settings on one dial rather than separate tricks.
The one idea you need first
The Bellman expectation for fixed says equals mean reward plus times next values. The greedy policy picks the action with the largest one step lookahead under current . GPI is those two updates chasing each other.
Think of It Like This
Two legs walking uphill
Your left leg plants and feels the slope where you stand. That is evaluation. Your right leg swings toward higher ground based on that feel. That is improvement. Neither leg walks alone.
If the left leg kept measuring without stepping, you would stand still polishing a number for a path you never take. If the right leg kept lunging without planting, you would trip. Alternating small steps climbs fastest.
Where it stops: hikers take even steps. GPI steps can be lopsided, like ten tiny critic moves per actor move.
How It Actually Works
Hold , move toward with Bellman backups. Hold , move toward greedy by picking one step returns. The improvement theorem says a policy that looks better under old values is no worse in truth, so return does not go down.
Picture two lines crossing. One line is , where values match the policy. The other is , where the policy matches values. Each update moves toward one line and off the other, making a zigzag. The only joint rest point satisfies the Bellman optimum, hence .
Where common methods sit
- Full sweeps to convergence then greedy replacement behaves like policy iteration.
- One sweep then greedy replacement behaves like value iteration.
- One state at a time in any order behaves like asynchronous dynamic programming.
- One sampled transition with epsilon greedy behavior behaves like SARSA or Q-learning.
- Small critic and actor gradient steps together behave like actor critic.
No table needed: smaller evaluation grain means faster policy turns at noisier values.
Worked example
Two states , actions , . Rewards are fixed: in , stays in for , goes to for ; in , goes to for , stays in for . Start , .
First evaluation sweep under : , , so .
Greedy step on : in , and , pick ; in , and , pick . So , already optimal.
Next evaluation under : , . The policy stays put. True fixed point solves and . Later sweeps give , , , closing on .
Code
One sweep plus greedy choice, matching the hand trace:
def eval_sweep(V: list[float], policy: list[int], gamma: float) -> list[float]: """One Bellman expectation sweep for the 2 state MDP.""" # next state and reward tables: [state][action] -> (next_state, reward) nxt = [[0, 1], [0, 1]] rew = [[1.0, 3.0], [0.0, 2.0]] out = [0.0, 0.0] for s in (0, 1): a = policy[s] out[s] = rew[s][a] + gamma * V[nxt[s][a]] return [round(x, 2) for x in out]
def greedy(V: list[float], gamma: float) -> list[int]: """Greedy policy over one step lookahead.""" nxt = [[0, 1], [0, 1]] rew = [[1.0, 3.0], [0.0, 2.0]] pol = [0, 0] for s in (0, 1): qs = [rew[s][a] + gamma * V[nxt[s][a]] for a in (0, 1)] pol[s] = max((0, 1), key=lambda a: qs[a]) return pol
V1 = eval_sweep([0.0, 0.0], [0, 0], 0.5)print(V1) # -> [1.0, 0.0]print(greedy(V1, 0.5)) # -> [1, 1]print(eval_sweep(V1, [1, 1], 0.5)) # -> [3.0, 2.0]Here means and means , so is . Numbers match and above.
Watch Out For
Evaluating a bad policy to high precision
Teams run evaluation to tiny tolerance before one improvement, polishing values for behavior about to be discarded. The symptom is slow progress with shrinking Bellman error but a frozen policy.
Use truncated sweeps. One to a few backups per improvement is enough early, as in value iteration. Save deep evaluation for after the policy stabilizes.
Going fully greedy too early on noisy values
Strict greedy choice on fresh estimates kills search. Unvisited actions stay underestimated forever, so evaluation never corrects them. The symptom is fast lock in to a weak policy.
Keep search alive during improvement with epsilon greedy moves, optimistic starts, or entropy terms, then anneal toward greedy as values settle.
The Quick Version
- GPI alternates toward and toward greedy at any grain.
- Each move helps one side and disturbs the other, tracing a zigzag to one rest point.
- That rest point satisfies Bellman optimality, hence .
- On the two state MDP with gamma 0.5, one sweep finds the optimal policy and values close on 5.0 and 4.0.
- Policy iteration, value iteration, SARSA, Q-learning and actor critic are grain choices on this loop.