Skip to content
AI360Xpert
Beta

n-Step TD Prediction

n-step TD prediction delays bootstrapping by looking ahead n transitions, letting you smoothly tune between the rapid low-variance updates of one-step TD and the unbiased trajectory sampling of Monte Carlo.

n-step TD prediction forms a spectrum between 1-step TD and Monte Carlo by accumulating n actual rewards along a trajectory before bootstrapping from the estimated state value.
n-step TD prediction forms a spectrum between 1-step TD and Monte Carlo by accumulating n actual rewards along a trajectory before bootstrapping from the estimated state value.

Why Does This Exist?

In reinforcement learning, estimating a state value function V(s)V(s) requires an update target. Classical methods stand at two opposing extremes of a fundamental trade-off:

  1. One-step Temporal Difference learning, or TD(0): Bootstraps immediately after experiencing a single transition (n=1n=1). The target is Rt+1+γV(St+1)R_{t+1} + \gamma V(S_{t+1}). Because it only depends on a single sample step, its variance is low. However, its target heavily relies on the current value estimate V(St+1)V(S_{t+1}). If the initial value estimates are poorly calibrated, TD(0) injects substantial estimation bias into every update. Furthermore, a terminal reward must trickle backwards one transition per episode, requiring many episodes for distant states to learn.
  2. Monte Carlo (MC) prediction: Waits until the entire trajectory terminates (n=∞n=\infty) before computing the actual sample return Gt=∑k=0T−t−1γkRt+k+1G_t = \sum_{k=0}^{T-t-1} \gamma^k R_{t+k+1}. Because it uses actual realized rewards with zero bootstrapping, its target is completely unbiased. But accumulating dozens or hundreds of stochastic transitions introduces high sample variance. MC also cannot learn in non-terminating continuing tasks or mid-episode.

n-step TD prediction exists to bridge this gap. Instead of forcing an all-or-nothing choice between one step and complete termination, it parameterizes the lookahead horizon to an arbitrary integer n≥1n \ge 1. By accumulating nn steps of real environment transitions before substituting the remaining future with a bootstrapped value estimate, nn-step TD lets practitioners dial the exact sweet spot between bias and variance. Empirically, intermediate horizons (such as n∈[3,10]n \in [3, 10]) learn significantly faster and achieve lower asymptotic error than either extreme.

Think of It Like This

Performance Reviews: Daily Check-Ins vs. Quarterly Milestones vs. Retirement Retrospectives

Imagine evaluating the career trajectory and performance of a project lead:

  • 1-Step TD (The Daily Check-In): At 5:00 PM on Monday, you observe today's output (R1R_1). You then evaluate the lead's entire career value by combining Monday's output with your existing subjective hunch about where they will stand on Tuesday evening (V(S1)V(S_1)). Because you only observed eight hours of real work, your review is dominated by your prior hunch. If your initial evaluation model is biased or flawed, your updates are distorted. Moreover, major breakthrough deliverables that take months to complete take forever to reflect in their Monday review.
  • Monte Carlo (The Retirement Retrospective): You refuse to evaluate the project lead until they retire 35 years later (TT). You then calculate their true lifetime deliverables with zero guesswork. While this retrospective is completely free of subjective estimation bias, it comes decades too late to guide ongoing project decisions. Furthermore, 35 years of macroeconomic swings, team reorganizations, and random luck introduce enormous variance.
  • n-Step TD (The Quarterly Milestone Review): You evaluate the lead after a defined 3-month project sprint (n=3n=3 months). You log 90 days of concrete, verifiable code commits, product releases, and customer feedback (R1,R2,R3R_1, R_2, R_3). Only at that 3-month milestone do you combine those hard facts with an updated forecast for the remaining project roadmap (V(S3)V(S_3)). You anchor the evaluation in substantial real data while keeping feedback timely enough to steer future work.

Where the analogy stops: In reinforcement learning, the future forecast V(St+n)V(S_{t+n}) is multiplied by an exact geometric discount factor γn\gamma^n, and updates are applied retroactively with an exact step size α\alpha using a sliding trajectory buffer.

How It Actually Works

Multi-Step Bootstrapping and the Error Reduction Property

Consider an agent interacting with an environment in discrete time steps t=0,1,2,…t = 0, 1, 2, \dots. At time step tt, the agent occupies state StS_t, takes action AtA_t, transitions to state St+1S_{t+1}, and receives a scalar reward Rt+1R_{t+1}. The discount factor is γ∈[0,1]\gamma \in [0, 1], and the episode terminates at time step TT.

1. The n-Step Return

The core object of nn-step TD prediction is the nn-step return, denoted Gt:t+nG_{t:t+n}. It sums the first nn discounted rewards and bootstraps from the estimated value of the state visited nn steps into the future:

Gt:t+n=Rt+1+γRt+2+γ2Rt+3+⋯+γn−1Rt+n+γnVt+n−1(St+n)G_{t:t+n} = R_{t+1} + \gamma R_{t+2} + \gamma^2 R_{t+3} + \dots + \gamma^{n-1} R_{t+n} + \gamma^n V_{t+n-1}(S_{t+n})

Where:

  • Rt+kR_{t+k} is the reward observed at transition kk.
  • γk−1\gamma^{k-1} discounts the reward received kk steps ahead.
  • Vt+n−1(St+n)V_{t+n-1}(S_{t+n}) is the estimate of the value of state St+nS_{t+n} available at time t+n−1t+n-1.
  • γn\gamma^n scales the bootstrapped value estimate.

If the trajectory reaches or surpasses terminal time step TT (that is, t+n≥Tt + n \ge T), the return is simply truncated at TT, and no bootstrapping occurs because the value of a terminal state is identically zero:

Gt:t+n=Gt=∑k=t+1Tγk−t−1Rkwhen t+n≥TG_{t:t+n} = G_t = \sum_{k=t+1}^T \gamma^{k-t-1} R_k \quad \text{when } t + n \ge T

Notice the two boundary conditions:

  • When n=1n = 1: Gt:t+1=Rt+1+γVt(St+1)G_{t:t+1} = R_{t+1} + \gamma V_t(S_{t+1}), which is the standard one-step TD target.
  • When n=∞n = \infty (or n≥T−tn \ge T - t): Gt:∞=GtG_{t:\infty} = G_t, which is the complete Monte Carlo return.

2. The Value Update Rule

Because computing Gt:t+nG_{t:t+n} requires knowledge of transitions up to time step t+nt+n, the update for state StS_t cannot be executed at time tt. It is delayed until time t+nt+n.

Let τ=t−n+1\tau = t - n + 1 denote the index of the state being updated. When the agent reaches time step tt (for t≥n−1t \ge n - 1), it updates the value of the state visited at time τ≥0\tau \ge 0:

Vt(Sτ)=Vt−1(Sτ)+α[Gτ:τ+n−Vt−1(Sτ)]V_{t}(S_\tau) = V_{t-1}(S_\tau) + \alpha \left[ G_{\tau:\tau+n} - V_{t-1}(S_\tau) \right]

Where:

  • α∈(0,1]\alpha \in (0, 1] is the step-size learning rate.
  • Gτ:τ+n−Vt−1(Sτ)G_{\tau:\tau+n} - V_{t-1}(S_\tau) is the nn-step TD error.
  • All other state estimates remain unchanged: Vt(s)=Vt−1(s)V_t(s) = V_{t-1}(s) for all s≠Sτs \ne S_\tau.

When the episode terminates at step TT, the agent must drain its buffer by continuing to apply updates for all remaining historical states τ=T−n+1,…,T−1\tau = T - n + 1, \dots, T - 1 until every visited state has been updated.

3. Theoretical Guarantee: The Error Reduction Property

Why is multi-step bootstrapping guaranteed to behave well? Sutton and Barto established the error reduction property of nn-step returns:

max⁡s∣Eπ[Gt:t+n∣St=s]−vπ(s)∣≤γnmax⁡s∣V(s)−vπ(s)∣\max_s \left| \mathbb{E}_\pi \left[ G_{t:t+n} \mid S_t = s \right] - v_\pi(s) \right| \le \gamma^n \max_s \left| V(s) - v_\pi(s) \right|

Where vπ(s)v_\pi(s) is the true underlying value under policy π\pi.

This theorem proves that the expected nn-step return is guaranteed to be a strictly better estimate of vπv_\pi than the current estimate VV, shrinking the worst-case error by a geometric factor of at least γn\gamma^n. As nn increases, the worst-case bias decays exponentially at rate γn\gamma^n.

Worked numerical example

To see how nn-step returns accelerate reward propagation, let us trace a single episode through a 5-step deterministic trajectory:

States: S0→R1=1.0S1→R2=2.0S2→R3=0.0S3→R4=10.0S4 (Terminal)\text{States: } S_0 \xrightarrow{R_1 = 1.0} S_1 \xrightarrow{R_2 = 2.0} S_2 \xrightarrow{R_3 = 0.0} S_3 \xrightarrow{R_4 = 10.0} S_4 \text{ (Terminal)}

Let:

  • Discount factor γ=0.9\gamma = 0.9
  • Step size α=0.5\alpha = 0.5
  • Initial value estimates for all states: V(s)=0.0V(s) = 0.0 for all s∈{S0,S1,S2,S3,S4}s \in \{S_0, S_1, S_2, S_3, S_4\}

We will compare the update applied to the starting state S0S_0 across n=1n=1, n=2n=2, n=3n=3, and Monte Carlo (n=4n=4):

Case 1: One-Step TD (n=1n = 1)

At time step t=1t=1, the agent observes transition S0→S1S_0 \to S_1 with reward R1=1.0R_1 = 1.0. τ=1−1=0  ⟹  Updating S0\tau = 1 - 1 = 0 \implies \text{Updating } S_0 G0:1=R1+γV(S1)=1.0+0.9×(0.0)=1.0000G_{0:1} = R_1 + \gamma V(S_1) = 1.0 + 0.9 \times (0.0) = 1.0000 V(S0)←0.0+0.5×(1.0000−0.0)=0.5000V(S_0) \leftarrow 0.0 + 0.5 \times (1.0000 - 0.0) = \mathbf{0.5000}

The large downstream reward R4=10.0R_4 = 10.0 has zero impact on S0S_0 in this episode.

Case 2: Two-Step TD (n=2n = 2)

At time step t=2t=2, the agent has observed S0→S1→S2S_0 \to S_1 \to S_2 with rewards R1=1.0,R2=2.0R_1 = 1.0, R_2 = 2.0. τ=2−2=0  ⟹  Updating S0\tau = 2 - 2 = 0 \implies \text{Updating } S_0 G0:2=R1+γR2+γ2V(S2)=1.0+0.9×(2.0)+(0.9)2×(0.0)=1.0+1.8000=2.8000G_{0:2} = R_1 + \gamma R_2 + \gamma^2 V(S_2) = 1.0 + 0.9 \times (2.0) + (0.9)^2 \times (0.0) = 1.0 + 1.8000 = 2.8000 V(S0)←0.0+0.5×(2.8000−0.0)=1.4000V(S_0) \leftarrow 0.0 + 0.5 \times (2.8000 - 0.0) = \mathbf{1.4000}

Now S0S_0 directly benefits from both R1R_1 and R2R_2, nearly tripling its value adjustment.

Case 3: Three-Step TD (n=3n = 3)

At time step t=3t=3, the agent has observed transitions up to S3S_3 with rewards R1=1.0,R2=2.0,R3=0.0R_1 = 1.0, R_2 = 2.0, R_3 = 0.0. τ=3−3=0  ⟹  Updating S0\tau = 3 - 3 = 0 \implies \text{Updating } S_0 G0:3=R1+γR2+γ2R3+γ3V(S3)=1.0+0.9×(2.0)+0.81×(0.0)+0.729×(0.0)=2.8000G_{0:3} = R_1 + \gamma R_2 + \gamma^2 R_3 + \gamma^3 V(S_3) = 1.0 + 0.9 \times (2.0) + 0.81 \times (0.0) + 0.729 \times (0.0) = 2.8000 V(S0)←0.0+0.5×(2.8000−0.0)=1.4000V(S_0) \leftarrow 0.0 + 0.5 \times (2.8000 - 0.0) = \mathbf{1.4000}

Case 4: Full Monte Carlo (n=4n = 4, Horizon Reaches Terminal T=4T=4)

At time step t=4t=4, the terminal state S4S_4 is reached. τ=4−4=0  ⟹  Updating S0\tau = 4 - 4 = 0 \implies \text{Updating } S_0 G0:4=R1+γR2+γ2R3+γ3R4=1.0+0.9(2.0)+0.81(0.0)+0.729(10.0)=1.0+1.8000+0.0+7.2900=10.0900G_{0:4} = R_1 + \gamma R_2 + \gamma^2 R_3 + \gamma^3 R_4 = 1.0 + 0.9(2.0) + 0.81(0.0) + 0.729(10.0) = 1.0 + 1.8000 + 0.0 + 7.2900 = 10.0900 V(S0)←0.0+0.5×(10.0900−0.0)=5.0450V(S_0) \leftarrow 0.0 + 0.5 \times (10.0900 - 0.0) = \mathbf{5.0450}

Comparison Across the Full Episode

When the episode finishes and all buffered updates are drained, the learned values across all states are:

MethodV(S0)V(S_0)V(S1)V(S_1)V(S2)V(S_2)V(S3)V(S_3)
n=1n=1 (TD(0))0.50000.50001.00001.00000.00000.00005.00005.0000
n=2n=21.40001.40001.00001.00004.50004.50005.00005.0000
n=3n=31.40001.40005.05005.05004.50004.50005.00005.0000
n=4n=4 (MC)5.04505.04505.05005.05004.50004.50005.00005.0000

Notice how the terminal reward R4=10.0R_4 = 10.0 propagates backwards:

  • In n=1n=1, it only reaches S3S_3.
  • In n=2n=2, it reaches S3S_3 and S2S_2.
  • In n=3n=3, it reaches S3,S2S_3, S_2, and S1S_1.
  • In Monte Carlo, it travels all the way back to S0S_0 in a single episode.

Code

The following self-contained Python implementation processes an episodic trajectory using an explicit sliding window update buffer, properly handling the delayed updates and the end-of-episode draining phase.

from typing import Dict, List, Optional, Tuple

def n_step_td_prediction(    trajectory: List[Tuple[str, float]],    n: int,    gamma: float = 0.9,    alpha: float = 0.5,    initial_values: Optional[Dict[str, float]] = None,) -> Dict[str, float]:    """Computes state value estimates using episodic n-step TD prediction.
    Args:        trajectory: List of (state, reward) tuples where reward is received          upon entering state. First element is (S0, 0.0); last is (Terminal,          final_reward).        n: Number of lookahead steps before bootstrapping (n >= 1).        gamma: Discount factor in [0, 1].        alpha: Step size learning rate in (0, 1].        initial_values: Optional initial state values dictionary.
    Returns:        Dictionary mapping non-terminal state identifiers to updated values.    """    states = [step[0] for step in trajectory]    rewards = [step[1] for step in trajectory]    total_steps = len(trajectory) - 1  # Terminal step T
    # Initialize value dictionary    v_table = (        {s: 0.0 for s in set(states)}        if initial_values is None        else initial_values.copy()    )    terminal_state = states[total_steps]    v_table[terminal_state] = 0.0  # Terminal state value is always 0.0
    t = 0    while True:        # tau is the index of the state whose estimate is currently being updated        tau = t - n + 1
        if tau >= 0:            # 1. Sum observed rewards from step tau + 1 up to min(tau + n, T)            g_return = 0.0            horizon = min(tau + n, total_steps)            for i in range(tau + 1, horizon + 1):                discount_power = i - tau - 1                g_return += (gamma**discount_power) * rewards[i]
            # 2. Add bootstrapped value estimate only if horizon does not reach terminal step            if tau + n < total_steps:                bootstrapped_state = states[tau + n]                g_return += (gamma**n) * v_table[bootstrapped_state]
            # 3. Apply gradient-descent update rule to state S_tau            state_to_update = states[tau]            v_table[state_to_update] += alpha * (                g_return - v_table[state_to_update]            )
        # Termination condition: last updated state is T - 1        if tau == total_steps - 1:            break
        t += 1
    return {        s: round(v_table[s], 4)        for s in sorted(v_table.keys())        if s != terminal_state    }

# Trajectory: S0 -> (R=1.0) -> S1 -> (R=2.0) -> S2 -> (R=0.0) -> S3 -> (R=10.0) -> S4 (Terminal)example_trajectory = [    ("S0", 0.0),    ("S1", 1.0),    ("S2", 2.0),    ("S3", 0.0),    ("S4", 10.0),]
print("n=1 (TD(0)):", n_step_td_prediction(example_trajectory, n=1))print("n=2:        ", n_step_td_prediction(example_trajectory, n=2))print("n=3:        ", n_step_td_prediction(example_trajectory, n=3))print("n=4 (MC):   ", n_step_td_prediction(example_trajectory, n=4))
# -> Expected output:# -> n=1 (TD(0)): {'S0': 0.5, 'S1': 1.0, 'S2': 0.0, 'S3': 5.0}# -> n=2:         {'S0': 1.4, 'S1': 1.0, 'S2': 4.5, 'S3': 5.0}# -> n=3:         {'S0': 1.4, 'S1': 5.05, 'S2': 4.5, 'S3': 5.0}# -> n=4 (MC):    {'S0': 5.045, 'S1': 5.05, 'S2': 4.5, 'S3': 5.0}

Watch Out For

Terminal Boundary Off-by-One and Phantom Bootstrapping

A prevalent bug when implementing nn-step TD is blindly adding the bootstrapped term γnV(Sτ+n)\gamma^n V(S_{\tau+n}) without checking whether the lookahead index τ+n\tau + n has surpassed the episode boundary TT.

The Failure Mode: When an agent approaches the end of an episode, τ+n\tau + n frequently equals or exceeds TT. If the code does not clamp the reward summation at TT and unconditionally includes a bootstrap term, two severe errors occur:

  1. Out-of-Bounds Exceptions: Attempting to query states[tau + n] crashes with an indexing exception.
  2. Phantom Value Bleed: If the lookup wraps around or indexes a non-zero terminal value, the algorithm adds a "phantom" bootstrap value γnV(Sterm)\gamma^n V(S_{\text{term}}) into the return. This injects artificial bias into terminal transitions, causing value estimates near episode goals to diverge.
  3. Premature Loop Termination: Ceasing execution as soon as t=Tt = T without draining the buffer drops the final n−1n-1 states (τ=T−n+1,…,T−1\tau = T-n+1, \dots, T-1) without ever updating them.

The Fix:

  • Accumulate discounted rewards strictly up to min⁡(τ+n,T)\min(\tau + n, T).
  • Add the bootstrapped value γnV(Sτ+n)\gamma^n V(S_{\tau+n}) if and only if τ+n<T\tau + n < T.
  • Continue the outer loop until τ=T−1\tau = T - 1 to ensure all remaining states in the sliding buffer receive their updates before the episode finishes.

The Quick Version

  • Tunable spectrum: nn-step TD prediction bridges 1-step TD(0) and full Monte Carlo, letting you select an intermediate horizon nn that balances bootstrapping bias against trajectory variance.
  • Delayed updates: Updates to state SτS_\tau are computed at time τ+n\tau + n, requiring a memory buffer of size n+1n+1 to store recent states and rewards.
  • Faster reward propagation: Increasing nn propagates terminal rewards multiple steps backwards within a single episode, eliminating the single-transition bottleneck of TD(0).
  • Error reduction guarantee: The expected nn-step return is guaranteed to contract the maximum value error by at least γn\gamma^n, ensuring stable convergence toward the true value function vπv_\pi.