Skip to content
AI360Xpert
Beta

Policy Evaluation

Iterative policy evaluation determines the true expected value of every state under a fixed policy by repeatedly applying Bellman backups until estimates converge.

Iterative policy evaluation sweeps across states, updating value estimates via Bellman expectation backups until convergence.
Iterative policy evaluation sweeps across states, updating value estimates via Bellman expectation backups until convergence.

Why Does This Exist?

In reinforcement learning, an agent cannot systematically improve its behavior without knowing the exact long-term return its current behavior produces. If an agent modifies its decisions arbitrarily without a reliable baseline, it risks choosing actions that yield immediate gratification but precipitate catastrophic long-term failure. Policy evaluation solves this foundational problem by computing the state-value function Vπ(s)V^\pi(s)—the expected discounted cumulative reward from every state ss when following a specified policy π\pi.

Without policy evaluation, the foundational paradigm of Generalized Policy Iteration (GPI) breaks down. An agent must evaluate where it currently stands before it can identify which actions are genuinely superior.

Policy evaluation occupies a specific theoretical niche distinguishable from neighboring techniques:

  • Versus Value Iteration: Value iteration computes the optimal value function V∗(s)V^*(s) directly by embedding a greedy policy maximization operator (max⁡a\max_a) into every single update sweep. Policy evaluation, by contrast, evaluates an arbitrary, fixed policy π\pi using the expectation over actions ∑aπ(a∣s)\sum_a \pi(a \mid s), decoupling evaluation from policy improvement.
  • Versus Monte Carlo Evaluation: Monte Carlo methods estimate values by simulating sample trajectories until terminal episodes, requiring zero knowledge of environment transition dynamics but suffering from high sampling variance and failing on non-terminating horizons. Policy evaluation leverages full dynamic programming models to compute exact expectations across all branching paths in single-step sweeps with zero sample variance.
  • Versus Temporal Difference (TD) Learning: TD methods update online from single observed state-action transitions (s,a,r,s′)(s, a, r, s'), whereas dynamic programming policy evaluation performs an exhaustive, full-width expectation backup across all possible transitions simultaneously.

Think of It Like This

An Auditor Appraising a Fixed Corporate Business Plan

Imagine a senior financial auditor contracted to calculate the valuation of an enterprise operating under a rigid, unalterable business plan (the fixed policy π\pi). The company sells recurring subscriptions with known retention rates, standard billing tiers, and fixed customer renewal discounts.

The auditor is strictly forbidden from changing business operations—they cannot adjust retail prices, alter marketing spend, or fire underperforming teams. Their sole mandate is to determine what every client account tier (state ss) is worth across the total life of the contract.

  1. Initial ledger (k=0k = 0): The auditor starts with a blank valuation sheet, initializing every customer account value to zero.
  2. First reconciliation sweep (k=1k = 1): The auditor records only the immediate quarterly retainer fees billed today (immediate rewards rr). Accounts that bill today show positive revenue; accounts that bill later remain zero.
  3. Compounding subsequent sweeps (k=2,3,…k = 2, 3, \dots): The auditor recognizes that retaining an account today guarantees a specific probability of renewal next quarter. They discount next quarter's revenue by an annual cost of capital γ\gamma and fold it into today's valuation sheet.

With each full audit cycle, valuation adjustments propagate backward through the client relationship pipeline. While early iterations produce large balance adjustments, the difference between consecutive audits eventually shrinks to pennies. Once the maximum adjustment across all account tiers drops below an auditing tolerance θ\theta, the valuation ledger stabilizes into the true enterprise value VπV^\pi.

The analogy stops because real economic markets face non-stationary macroeconomic shocks and unknown behavioral probabilities. Dynamic programming assumes stationary, fully modeled transition dynamics p(s′,r∣s,a)p(s', r \mid s, a) where every outcome probability is precisely specified.

How It Actually Works

The Bellman Expectation Backup and Contraction Mapping

Iterative policy evaluation operates on a Markov Decision Process (MDP) defined by the tuple (S,A,p,γ)(\mathcal{S}, \mathcal{A}, p, \gamma), where S\mathcal{S} is the finite set of states, A\mathcal{A} is the action space, p(s′,r∣s,a)p(s', r \mid s, a) represents the environment dynamics, and γ∈[0,1)\gamma \in [0, 1) is the discount factor.

For a fixed policy π(a∣s)=P(At=a∣St=s)\pi(a \mid s) = \mathbb{P}(A_t = a \mid S_t = s), the true state-value function VπV^\pi satisfies the Bellman expectation equation:

Vπ(s)=∑a∈Aπ(a∣s)∑s′∈S∑rp(s′,r∣s,a)[r+γVπ(s′)]∀s∈SV^\pi(s) = \sum_{a \in \mathcal{A}} \pi(a \mid s) \sum_{s' \in \mathcal{S}} \sum_{r} p(s', r \mid s, a) \left[ r + \gamma V^\pi(s') \right] \quad \forall s \in \mathcal{S}

When the state space is large, solving this system of ∣S∣|\mathcal{S}| linear equations directly via matrix inversion has time complexity O(∣S∣3)\mathcal{O}(|\mathcal{S}|^3), which quickly becomes prohibitive. Iterative policy evaluation turns this recursive equation into an iterative update rule. Starting with an arbitrary initial value vector V0V_0 (with V0(terminal)=0V_0(\text{terminal}) = 0), the algorithm computes successive approximations:

Vk+1(s)=∑a∈Aπ(a∣s)∑s′∈S∑rp(s′,r∣s,a)[r+γVk(s′)]V_{k+1}(s) = \sum_{a \in \mathcal{A}} \pi(a \mid s) \sum_{s' \in \mathcal{S}} \sum_{r} p(s', r \mid s, a) \left[ r + \gamma V_k(s') \right]

Convergence is guaranteed by the Banach Fixed-Point Theorem. Defining the Bellman expectation operator Tπ:R∣S∣→R∣S∣T^\pi: \mathbb{R}^{|\mathcal{S}|} \to \mathbb{R}^{|\mathcal{S}|} as:

(TπV)(s)=∑a∈Aπ(a∣s)∑s′,rp(s′,r∣s,a)[r+γV(s′)](T^\pi V)(s) = \sum_{a \in \mathcal{A}} \pi(a \mid s) \sum_{s', r} p(s', r \mid s, a) \left[ r + \gamma V(s') \right]

Under the supremum (infinity) norm ∥V∥∞=max⁡s∈S∣V(s)∣\|V\|_\infty = \max_{s \in \mathcal{S}} |V(s)|, the operator satisfies:

∥TπU−TπV∥∞≤γ∥U−V∥∞\|T^\pi U - T^\pi V\|_\infty \le \gamma \|U - V\|_\infty

Because γ<1\gamma < 1, TπT^\pi is a strict γ\gamma-contraction mapping on the complete metric space R∣S∣\mathbb{R}^{|\mathcal{S}|}. This mathematical property guarantees:

  1. TπT^\pi has a single, unique fixed point satisfying TπVπ=VπT^\pi V^\pi = V^\pi.
  2. The sequence generated by Vk+1=TπVkV_{k+1} = T^\pi V_k converges geometrically at rate O(γk)\mathcal{O}(\gamma^k) to VπV^\pi from any arbitrary initialization V0V_0.

The iteration halts when the maximum change across all states between consecutive sweeps is strictly bounded by a small threshold θ>0\theta > 0:

Δ=max⁡s∈S∣Vk+1(s)−Vk(s)∣<θ\Delta = \max_{s \in \mathcal{S}} \left| V_{k+1}(s) - V_k(s) \right| < \theta

By contraction properties, terminating at Δ<θ\Delta < \theta guarantees that the distance between the current estimate and the true value function satisfies:

∥Vk+1−Vπ∥∞≤γ1−γθ\|V_{k+1} - V^\pi\|_\infty \le \frac{\gamma}{1 - \gamma} \theta

Worked numerical example

Consider a 3-state linear Markov chain: S={s1,s2,s3}\mathcal{S} = \{s_1, s_2, s_3\} leading to an absorbing terminal state sTs_T where V(sT)≡0V(s_T) \equiv 0. The discount factor is γ=0.9\gamma = 0.9, and the stopping threshold is θ=0.05\theta = 0.05.

Under policy π\pi, the agent transitions deterministically to the right:

  • From s1s_1, the agent steps to s2s_2 with reward r=0r = 0.
  • From s2s_2, the agent steps to s3s_3 with reward r=0r = 0.
  • From s3s_3, the agent steps into sTs_T with reward r=+10.0r = +10.0.

Initialize all state values to zero at k=0k = 0:

V0(s1)=0.0,V0(s2)=0.0,V0(s3)=0.0V_0(s_1) = 0.0, \quad V_0(s_2) = 0.0, \quad V_0(s_3) = 0.0

Iteration 1 (k=1k = 1):

  • V1(s1)=0+0.9⋅V0(s2)=0+0.9(0.0)=0.0V_1(s_1) = 0 + 0.9 \cdot V_0(s_2) = 0 + 0.9(0.0) = 0.0
  • V1(s2)=0+0.9⋅V0(s3)=0+0.9(0.0)=0.0V_1(s_2) = 0 + 0.9 \cdot V_0(s_3) = 0 + 0.9(0.0) = 0.0
  • V1(s3)=10.0+0.9⋅V0(sT)=10.0+0.9(0.0)=10.0V_1(s_3) = 10.0 + 0.9 \cdot V_0(s_T) = 10.0 + 0.9(0.0) = 10.0

Compute the maximum update delta:

Δ1=max⁡(∣0.0−0.0∣,∣0.0−0.0∣,∣10.0−0.0∣)=10.0\Delta_1 = \max(|0.0 - 0.0|, |0.0 - 0.0|, |10.0 - 0.0|) = 10.0

Since Δ1=10.0≥θ\Delta_1 = 10.0 \ge \theta, the algorithm executes sweep 2 with value vector V1=[0.0,0.0,10.0]V_1 = [0.0, 0.0, 10.0].

Iteration 2 (k=2k = 2):

  • V2(s1)=0+0.9⋅V1(s2)=0+0.9(0.0)=0.0V_2(s_1) = 0 + 0.9 \cdot V_1(s_2) = 0 + 0.9(0.0) = 0.0
  • V2(s2)=0+0.9⋅V1(s3)=0+0.9(10.0)=9.0V_2(s_2) = 0 + 0.9 \cdot V_1(s_3) = 0 + 0.9(10.0) = 9.0
  • V2(s3)=10.0+0.9⋅V1(sT)=10.0+0.9(0.0)=10.0V_2(s_3) = 10.0 + 0.9 \cdot V_1(s_T) = 10.0 + 0.9(0.0) = 10.0

Compute the maximum update delta:

Δ2=max⁡(∣0.0−0.0∣,∣9.0−0.0∣,∣10.0−10.0∣)=9.0\Delta_2 = \max(|0.0 - 0.0|, |9.0 - 0.0|, |10.0 - 10.0|) = 9.0

Since Δ2=9.0≥θ\Delta_2 = 9.0 \ge \theta, values continue to propagate upstream with value vector V2=[0.0,9.0,10.0]V_2 = [0.0, 9.0, 10.0].

Iteration 3 (k=3k = 3) and Final Convergence:

  • V3(s1)=0+0.9⋅V2(s2)=0+0.9(9.0)=8.1V_3(s_1) = 0 + 0.9 \cdot V_2(s_2) = 0 + 0.9(9.0) = 8.1
  • V3(s2)=0+0.9⋅V2(s3)=0+0.9(10.0)=9.0V_3(s_2) = 0 + 0.9 \cdot V_2(s_3) = 0 + 0.9(10.0) = 9.0
  • V3(s3)=10.0+0.9⋅V2(sT)=10.0+0.9(0.0)=10.0V_3(s_3) = 10.0 + 0.9 \cdot V_2(s_T) = 10.0 + 0.9(0.0) = 10.0

On iteration 4 (k=4k = 4), evaluating all states yields identical values V4=[8.1,9.0,10.0]V_4 = [8.1, 9.0, 10.0], producing Δ4=0.0<θ\Delta_4 = 0.0 < \theta. The iteration terminates at the exact analytical fixed point Vπ=[8.1,9.0,10.0]V^\pi = [8.1, 9.0, 10.0].

Code

from typing import List, Tuple
def iterative_policy_evaluation(    grid_size: Tuple[int, int] = (4, 4),    terminals: List[Tuple[int, int]] = [(0, 0), (3, 3)],    gamma: float = 1.0,    theta: float = 1e-4,) -> Tuple[List[List[float]], int]:    """Computes state values for an equiprobable random policy on a Gridworld.        Args:        grid_size: Dimensions of the grid (rows, columns).        terminals: List of coordinate tuples marking terminal states.        gamma: Discount factor in [0, 1].        theta: Precision threshold for stopping condition.            Returns:        Tuple containing the converged 2D value grid and the iteration count.    """    rows, cols = grid_size    # Initialize state values to zero    V: List[List[float]] = [[0.0 for _ in range(cols)] for _ in range(rows)]        # Actions: Up, Down, Left, Right    actions: List[Tuple[int, int]] = [(-1, 0), (1, 0), (0, -1), (0, 1)]    prob_a: float = 1.0 / len(actions)    iterations: int = 0
    while True:        delta: float = 0.0        # Create a copy for synchronous value updates        new_V: List[List[float]] = [row[:] for row in V]
        for r in range(rows):            for c in range(cols):                if (r, c) in terminals:                    continue
                v_expected: float = 0.0                for dr, dc in actions:                    nr, nc = r + dr, c + dc                    # Wall bounce: staying in place if move goes off grid                    if not (0 <= nr < rows and 0 <= nc < cols):                        nr, nc = r, c                    reward: float = -1.0                    v_expected += prob_a * (reward + gamma * V[nr][nc])
                new_V[r][c] = v_expected                delta = max(delta, abs(new_V[r][c] - V[r][c]))
        V = new_V        iterations += 1
        if delta < theta:            break
    return V, iterations

if __name__ == "__main__":    converged_V, num_sweeps = iterative_policy_evaluation()    print(f"Converged after {num_sweeps} sweeps:")    for row in converged_V:        print([round(val, 1) for val in row])
    # Expected output:    # Converged after 173 sweeps:    # [0.0, -14.0, -20.0, -22.0]    # [-14.0, -18.0, -20.0, -20.0]    # [-20.0, -20.0, -18.0, -14.0]    # [-22.0, -20.0, -14.0, 0.0]

Watch Out For

Stopping Threshold Pitfall: Incomplete Convergence vs Excessive Computation

Setting the convergence threshold θ\theta creates a sharp trade-off between numerical precision and computational waste:

  • Stopping Too Early (θ\theta too loose): In policy evaluation, reward information propagates backward only one transition step per sweep. If θ\theta is set too large (e.g., θ=1.0\theta = 1.0), the algorithm halts before value signals from distant rewards reach early upstream states. In Generalized Policy Iteration, acting greedily on half-propagated value estimates causes the policy improvement step to select suboptimal actions.
  • Stopping Too Late (θ\theta excessively tight): Because convergence is asymptotic, setting θ=10−16\theta = 10^{-16} forces dozens of costly sweeps computing negligible micro-adjustments that have zero influence on which action has the highest value.
  • The Fix: Bound the true value error using the theoretical relation ∥Vk−Vπ∥∞≤γ1−γθ\|V_k - V^\pi\|_\infty \le \frac{\gamma}{1 - \gamma} \theta. If using policy evaluation inside Policy Iteration, truncate policy evaluation early: truncating after just 5 to 10 sweeps (as done in Value Iteration or Modified Policy Iteration) still guarantees policy improvement while slashing computation by orders of magnitude.

The Quick Version

  • Policy evaluation computes the true state-value function Vπ(s)V^\pi(s) for an unvarying policy π\pi without modifying agent decisions.
  • It iteratively applies the Bellman expectation backup operator across all states: Vk+1(s)←∑aπ(a∣s)∑s′,rp(s′,r∣s,a)[r+γVk(s′)]V_{k+1}(s) \leftarrow \sum_a \pi(a \mid s) \sum_{s', r} p(s', r \mid s, a)[r + \gamma V_k(s')].
  • Because the Bellman expectation operator is a contraction mapping in the infinity norm, convergence to a unique fixed point VπV^\pi is guaranteed for any initial values when γ<1\gamma < 1.
  • The sweep loop terminates once the maximum single-state variation Δ=max⁡s∣Vk+1(s)−Vk(s)∣\Delta = \max_s |V_{k+1}(s) - V_k(s)| falls below a specified tolerance threshold θ\theta.