Policy Improvement
Policy improvement transforms an existing policy into a superior one by choosing actions that maximize expected return under current value estimates.
Why Does This Exist?
In reinforcement learning, evaluating an agent's current strategy through policy evaluation computes how much cumulative return each state yields under that fixed behavior. However, evaluation alone does not change behavior. To discover an optimal strategy, an agent requires a systematic, mathematically principled mechanism to upgrade its choices.
Without a formal improvement rule, attempting to modify an agent's actions risks catastrophic instability. In a sequential decision problem, changing an action in one state alters the state distribution and downstream trajectories throughout the entire environment. Naively tweaking actions can inadvertently degrade long-term performance, trap the agent in suboptimal cycles, or cause performance collapse.
The Policy Improvement Theorem provides the theoretical guarantee that prevents this failure. It proves that by taking an action that looks locally greedy with respect to the current state-value function , the resulting policy is guaranteed to achieve equal or greater expected return from every single state in the environment ( for all ). This monotonic improvement property turns policy search into an orderly ascent toward optimality.
Think of It Like This
Upgrading Chess Openings Against an Opponent's Repertoire
Imagine you are a tournament chess player with an established opening repertoire (). After analyzing hundreds of recorded games against a rival, your chess engine calculates your expected win rate from every board position that typically arises ().
On move 6, your traditional opening book dictates playing a modest pawn move . Your engine evaluation shows that maintains your baseline win expectation of (). However, deep engine calculations reveal an alternative knight move : taking this move yields an immediate tactical threat and leads to board configurations that evaluate to (), even assuming you revert to your standard opening repertoire for all subsequent moves.
Policy improvement is the decision to update your opening notebook: whenever you reach this specific board state, you permanently replace with ().
Because the expected return of taking once and following thereafter exceeds the baseline value of , committing to every time you encounter that position can never hurt your long-term score. Even better, because this superior position is reached repeatedly, the advantage compounds across all subsequent games.
Where the analogy stops: In tournament chess, a human opponent actively studies your games and prepares counter-strategies in response, creating a non-stationary two-player game. In a standard Markov Decision Process, the environment's transition dynamics and reward functions remain stationary, meaning that improvements against the environment never trigger an adversarial counter-adjustment.
How It Actually Works
Action-Value Greedification and the Policy Improvement Theorem
Let an environment be defined as a Markov Decision Process , where is the state space, is the action space, represents the transition dynamics, and is the discount factor.
Suppose the agent follows an initial deterministic policy , yielding evaluated state-values .
1. Computing Action-Values
To determine whether selecting an alternative action in state improves return, we evaluate the action-value function . This represents the expected return of taking action right now, and subsequently following policy forever after:
2. Greedification (Policy Update)
We construct a new deterministic policy by selecting the action that maximizes at each state:
By definition of the operator, the new action satisfies:
3. Mathematical Proof of the Policy Improvement Theorem
The Policy Improvement Theorem (Bellman, 1957; Howard, 1960; Sutton & Barto, 2018) asserts:
If for all , then the overall policy is globally as good as, or better than, :
The proof proceeds by repeatedly unrolling the Bellman inequality:
Because the inequality holds for every successor state , we substitute into the expression:
Expanding this relationship recursively across consecutive time steps:
Taking the infinite-horizon limit as , with discount factor and bounded immediate rewards, the terminal discounted term vanishes: . Therefore:
This completes the proof: for all .
4. Convergence to Optimality
If the improved policy achieves strictly identical values to ( for all ), then:
This matches the Bellman Optimality Equation. Consequently, both and must be optimal policies . In any finite MDP with states and actions, there are exactly distinct deterministic policies; because each improvement step strictly increases value until reaching optimality, policy improvement cannot cycle and must terminate at the optimal policy in a finite number of steps.
Worked numerical example
Consider a 2-state environment with discount factor :
- State (Staging Area) offers two actions:
- (Conservative): Transitions to with probability (), and to with probability ().
- (Venturesome): Transitions to with probability (), and slips back to with probability ().
- State (High-Yield Vault) has a single fixed action:
- : Transitions to with probability (), and drops back to with probability ().
Step 1: Evaluate Baseline Policy
Our baseline policy selects action in (). We solve the linear Bellman expectation system:
Rearranging into standard matrix form:
Solving this system yields:
Step 2: Compute Action-Values
Now we evaluate both candidate actions available in state :
- Action :
- Action :
Comparing the two action-values:
Step 3: Greedification
The policy improvement step selects:
Step 4: True Value of the Improved Policy
Now we compute the actual state values under the updated policy:
In matrix form:
Solving this linear system gives:
Notice the global ripple effect:
- (+30.4% gain)
- (+17.7% gain)
Even though the agent took the exact same action in state , its value rose by because when transitions occasionally drop the agent back into , the improved policy makes the superior choice , boosting cumulative returns across the entire trajectory.
Code
from typing import Dict, List, Tuple
# Transition model: (state, action) -> list of (probability, next_state, reward)TransitionModel = Dict[Tuple[str, str], List[Tuple[float, str, float]]]Policy = Dict[str, str]ValueFunction = Dict[str, float]
def evaluate_policy( policy: Policy, transitions: TransitionModel, states: List[str], gamma: float = 0.9, theta: float = 1e-9,) -> ValueFunction: """Iteratively computes state values v_pi(s) via the Bellman expectation equation.""" v: ValueFunction = {s: 0.0 for s in states} while True: delta = 0.0 for s in states: a = policy[s] # Bellman expectation backup: v(s) = sum_{s', r} p(s', r | s, a) * [r + gamma * v(s')] v_new = sum( prob * (r + gamma * v[s_next]) for prob, s_next, r in transitions[(s, a)] ) delta = max(delta, abs(v[s] - v_new)) v[s] = v_new if delta < theta: break return v
def compute_action_value( state: str, action: str, v: ValueFunction, transitions: TransitionModel, gamma: float = 0.9,) -> float: """Computes q_pi(s, a) = sum_{s', r} p(s', r | s, a) * [r + gamma * v(s')].""" return sum( prob * (r + gamma * v[s_next]) for prob, s_next, r in transitions[(state, action)] )
def policy_improvement( v: ValueFunction, transitions: TransitionModel, states: List[str], actions: Dict[str, List[str]], gamma: float = 0.9,) -> Policy: """ Greedifies policy: pi'(s) = argmax_a q_pi(s, a). Applies deterministic tie-breaking by candidate order. """ improved_policy: Policy = {}
for s in states: available_actions = actions[s] # Evaluate q_pi(s, a) for all candidate actions action_values = { a: compute_action_value(s, a, v, transitions, gamma) for a in available_actions } # Deterministic greedification: break numerical ties by fixed index best_action = max( available_actions, key=lambda a: (round(action_values[a], 7), -available_actions.index(a)), ) improved_policy[s] = best_action
return improved_policy
if __name__ == "__main__": states = ["s1", "s2"] actions = { "s1": ["a1", "a2"], "s2": ["stay"], } transitions: TransitionModel = { ("s1", "a1"): [(0.8, "s1", 1.0), (0.2, "s2", 1.0)], ("s1", "a2"): [(0.9, "s2", 0.0), (0.1, "s1", -1.0)], ("s2", "stay"): [(0.7, "s2", 5.0), (0.3, "s1", 0.0)], } gamma = 0.9
# 1. Evaluate baseline policy pi where pi(s1) = a1 baseline_policy: Policy = {"s1": "a1", "s2": "stay"} v_pi = evaluate_policy(baseline_policy, transitions, states, gamma=gamma)
print("--- 1. Baseline Policy Evaluation v_pi ---") for s in states: print(f"v_pi({s}) = {v_pi[s]:.2f}")
# 2. Compute action-values q_pi(s1, a) print("\n--- 2. Action-Value Greedification in s1 ---") q_s1_a1 = compute_action_value("s1", "a1", v_pi, transitions, gamma=gamma) q_s1_a2 = compute_action_value("s1", "a2", v_pi, transitions, gamma=gamma) print(f"q_pi(s1, a1) = {q_s1_a1:.2f} (current baseline)") print(f"q_pi(s1, a2) = {q_s1_a2:.2f} (candidate improvement)")
# 3. Policy improvement step improved_policy = policy_improvement(v_pi, transitions, states, actions, gamma=gamma) print(f"\nImproved Policy pi': {improved_policy}")
# 4. Evaluate new policy pi' v_prime = evaluate_policy(improved_policy, transitions, states, gamma=gamma) print("\n--- 3. Improved Policy Evaluation v_pi' ---") for s in states: print(f"v_pi'({s}) = {v_prime[s]:.2f} (Delta: +{v_prime[s] - v_pi[s]:.2f})")
# Assertions validating Policy Improvement Theorem assert q_s1_a2 > v_pi["s1"], "Candidate action must yield strictly higher q-value" assert improved_policy["s1"] == "a2", "Greedy update must select action a2" assert v_prime["s1"] >= v_pi["s1"], "Monotonic improvement guarantee violated for s1" assert v_prime["s2"] >= v_pi["s2"], "Monotonic improvement guarantee violated for s2" print("\nPolicy Improvement Theorem assertions passed successfully.")--- 1. Baseline Policy Evaluation v_pi ---v_pi(s1) = 18.18v_pi(s2) = 22.73
--- 2. Action-Value Greedification in s1 ---q_pi(s1, a1) = 18.18 (current baseline)q_pi(s1, a2) = 19.95 (candidate improvement)
Improved Policy pi': {'s1': 'a2', 's2': 'stay'}
--- 3. Improved Policy Evaluation v_pi' ---v_pi'(s1) = 23.71 (Delta: +5.53)v_pi'(s2) = 26.76 (Delta: +4.04)
Policy Improvement Theorem assertions passed successfully.Watch Out For
Non-deterministic tie-breaking causing policy oscillation
When two or more actions yield identical action-values (), arbitrary or random tie-breaking breaks convergence. If Python's dictionary iteration or non-deterministic sorting flips the winner on consecutive iterations, policy iteration will oscillate endlessly between and despite having already reached optimal value.
Symptom: The policy never stabilizes, reporting changes on every iteration even though state values have completely converged ().
Fix: Implement a strict, deterministic tie-breaking rule. Always prefer retaining the existing action whenever an alternative action's value is within numerical tolerance . If multiple novel actions tie, break ties using a fixed alphabetical or indexed action hierarchy.
Greedifying on imprecise or noisy value estimates
The Policy Improvement Theorem strictly guarantees only when action-values are computed from the exact true state values . In approximate reinforcement learning or early-stopped policy evaluation, value estimates contain estimation errors .
Symptom: Greedification on noisy value estimates selects an action that appears superficially better but actually degrades policy return (), causing policy degradation or divergence.
Fix: In dynamic programming, ensure iterative policy evaluation converges beneath a stringent threshold () before greedifying. In sample-based or deep reinforcement learning, avoid hard 1-step greedification; instead, employ conservative policy updates, trust-region constraints (such as TRPO or PPO), or entropy-regularized policy gradients that bound policy divergence per step.
The Quick Version
- Policy improvement generates a new policy by acting greedily with respect to current value estimates: .
- The Policy Improvement Theorem mathematically guarantees monotonic non-decreasing expected return from every state: for all .
- Greedifying an action in one state causes a positive ripple effect throughout the entire Markov chain, increasing values even in states where the policy did not change.
- When greedification produces no change in policy return ( for all ), the policy has satisfied the Bellman Optimality Equation and is guaranteed optimal ().