Skip to content
AI360Xpert
Beta

Trajectory Sampling

Rather than wasting computational budget updating every state in an enormous state space equally, trajectory sampling simulates rollouts using an internal environment model. This restricts planning updates exclusively to states that the agent will actually encounter under its current policy.

Trajectory sampling focuses planning updates exclusively along simulated on-policy trajectories, avoiding wasted computation on unreachable or irrelevant regions of the state space.
Trajectory sampling focuses planning updates exclusively along simulated on-policy trajectories, avoiding wasted computation on unreachable or irrelevant regions of the state space.

Why Does This Exist?

In model-based reinforcement learning and Dynamic Programming, planning algorithms improve value functions and policies by simulating transitions through an internal environment model. The traditional approach is uniform sweeping: the planner iterates through the entire state space S\mathcal{S} in an exhaustive round-robin fashion, applying Bellman backups to each state with equal frequency.

While uniform sweeping guarantees global convergence in small, toy Markov Decision Processes, it fails completely when scaled to practical problems:

  1. The Curse of Irrelevant States: In realistic tasks, the state space ∣S∣|\mathcal{S}| is combinatorial or massive. Worse, the vast majority of these states are either physically unreachable from starting conditions or represent bizarre, pathological configurations that an agent following a reasonable policy will never encounter.
  2. Diluted Computational Budget: If an environment contains 1,000,0001,000,000 states but the agent only ever visits 1,0001,000 of them along plausible goal-oriented trajectories, uniform sweeping expends 99.9%99.9\% of its planning computation updating values for states that have literally zero impact on decision-making. Important bottleneck states receive only a trickle of updates.

Trajectory sampling exists to align the distribution of planning computation with the distribution of actual agent experience.

Instead of sweeping the state space uniformly, the agent uses its learned model to simulate complete episodes starting from initial states and selecting actions according to its current policy π\pi. By executing planning updates exclusively along these simulated rollouts, updates are distributed according to the on-policy state distribution dπ(s)d^\pi(s). States that are frequently visited under the policy receive intense, focused refinement, while unreachable states consume zero computational cycles.

Think of It Like This

The Continental GPS Router

Imagine programming a GPS navigation engine to compute the fastest driving route from Seattle to San Francisco.

A uniform sweeping router would load every intersection, dirt road, alleyway, and rural roundabout across the entire North American continent—from Anchorage, Alaska to Key West, Florida—into memory. It would iterate through every single crossroads in round-robin order, recalculating speed limits and traffic lights for all of them equally.

For hours, your computer fan would spin at maximum speed while the system calculated optimal left turns in southern Ohio and downtown Miami—intersections that have literally zero relevance to driving down the Pacific coast.

A trajectory sampling router operates with common sense:

  1. It begins at your current Seattle coordinates (S0S_0).
  2. It projects prospective travel corridors southward along major highways (Interstate 5 and US-101), querying its road network model to simulate intersections along plausible paths toward San Francisco.
  3. It refines junction choices along that prospective corridor, ignoring the millions of irrelevant roads in other states.

Because 100% of the processor's budget is concentrated on the corridor of reachable travel, you receive a near-optimal driving itinerary in milliseconds.

Where the analogy stops: Road networks have static, fixed highway layouts. In reinforcement learning, the environment's transition probabilities and rewards can be stochastic, and updating the policy alters which future states become reachable. Consequently, trajectory sampling must maintain sufficient exploratory action selection to prevent missing newly promising corridors.

How It Actually Works

The On-Policy Distribution and Simulated Rollout Mechanism

In planning frameworks such as Dyna-Q and Real-Time Dynamic Programming (RTDP), trajectory sampling generates simulated trajectories using the agent's learned or given model M=⟨p(s′,r∣s,a)⟩\mathcal{M} = \langle p(s', r \mid s, a) \rangle.

The On-Policy State Distribution

Let an agent start at state S0∼ρ0S_0 \sim \rho_0 and follow target policy π\pi. The discounted on-policy state distribution dπ(s)d^\pi(s) is defined as:

dπ(s)≐(1−γ)∑t=0∞γtP(St=s∣S0∼ρ0,π)d^\pi(s) \doteq (1 - \gamma) \sum_{t=0}^\infty \gamma^t P(S_t = s \mid S_0 \sim \rho_0, \pi)

where:

  • ρ0\rho_0 is the starting state distribution.
  • γ∈[0,1)\gamma \in [0, 1) is the discount factor.
  • P(St=s∣S0,π)P(S_t = s \mid S_0, \pi) is the probability that state ss is occupied at time step tt under policy π\pi.

When a planner samples trajectories according to dπ(s)d^\pi(s), the frequency of planning updates applied to state ss is directly proportional to its probability of being visited during actual task execution.

Algorithmic Flow of Trajectory Sampling Planning

At each planning cycle:

  1. Initialize State: Sample a start state S∼ρ0S \sim \rho_0 (or select the agent's current real-world state).
  2. Rollout Loop: Until a terminal state is reached or horizon limit is met: a. Action Selection: Select action AA according to behavior policy b(⋅∣S)b(\cdot \mid S) (e.g., ϵ\epsilon-greedy with respect to current QQ): A∼b(⋅∣S)A \sim b(\cdot \mid S) b. Model Query: Query the internal transition model to generate a simulated next state S′S' and reward RR: S′,R∼p(⋅,⋅∣S,A)S', R \sim p(\cdot, \cdot \mid S, A) c. In-Place Planning Update: Update the action-value estimate Q(S,A)Q(S, A) using a sample backup: Q(S,A)←Q(S,A)+α[R+γmax⁡a′Q(S′,a′)−Q(S,A)]Q(S, A) \leftarrow Q(S, A) + \alpha \left[ R + \gamma \max_{a'} Q(S', a') - Q(S, A) \right] (or alternatively apply a full expected Bellman backup if branching is small). d. Advance Simulation: Step forward along the simulated trajectory: S←S′S \leftarrow S'

The Short-Term vs. Long-Term Convergence Trade-off

Richard Sutton and Andrew Barto analyzed the fundamental trade-off between uniform sweeping and on-policy trajectory sampling (Section 8.6):

Policy Value / Convergence    ▲    │                                  Trajectory Sampling (Fast early gains)    │                         .────────────────────────────────────────────►    │                   . - '    │             . - '    │       . - '                      Uniform Sweeps (Sluggish start, slow global convergence)    │   . '                   .────────────────────────────────────────────►    │  '          . - - - - '    │ . - - - - '    └──────────────────────────────────────────────────────────────► Planning Updates      0               Low Budget (Practical)                  Infinite Budget (Asymptotic)
  1. Under Low-to-Moderate Budgets: Trajectory sampling converges dramatically faster. By directing 100% of backups to reachable states along the current trajectory, the agent rapidly discovers a working policy to reach the goal.
  2. Under Infinite Budgets: Uniform sweeping eventually guarantees that all states in S\mathcal{S}—even bizarre, unreachable corners—converge to their true Bellman values. However, because an optimal agent will never visit unreachable states anyway, investing compute to evaluate them provides zero performance benefit in real tasks.

Worked numerical comparison

Consider an environment with 1010 total discrete states: S={S0,S1,…,S9}\mathcal{S} = \{S_0, S_1, \dots, S_9\}.

  • The task begins at start state S0S_0.
  • Under policy π\pi, the reachable chain is: S0→S1→S2→S3→TerminalS_0 \xrightarrow{} S_1 \xrightarrow{} S_2 \xrightarrow{} S_3 \xrightarrow{} \text{Terminal}.
  • States S4,S5,…,S9S_4, S_5, \dots, S_9 (66 states, 60%60\% of the state space) are unreachable or irrelevant loops with zero reward.
  • Transition dynamics: Reward is 0.00.0 on intermediate transitions, with a terminal reward of +10.0+10.0 upon exiting S3S_3.
  • Discount factor: γ=0.9\gamma = 0.9. Step-size learning rate: α=0.5\alpha = 0.5.

True Optimal Values on Reachable States

Working backward from the goal:

  • V∗(S3)=10.0000V^*(S_3) = 10.0000
  • V∗(S2)=0.9×10.0000=9.0000V^*(S_2) = 0.9 \times 10.0000 = \mathbf{9.0000}
  • V∗(S1)=0.9×9.0000=8.1000V^*(S_1) = 0.9 \times 9.0000 = \mathbf{8.1000}
  • V∗(S0)=0.9×8.1000=7.2900V^*(S_0) = 0.9 \times 8.1000 = \mathbf{7.2900}

All states are initialized to 0.00000.0000. The planner is allocated a budget of exactly 4040 planning updates.


Case A: Uniform Sweeping (4040 Updates)

With 1010 total states, a uniform round-robin sweep updates each state in sequence (S0,S1,…,S9S_0, S_1, \dots, S_9) across 44 complete passes (40/10=440 / 10 = 4 updates per state).

  1. Reachable states (S0…S3S_0 \dots S_3): Each state receives only 44 updates.
  2. Unreachable states (S4…S9S_4 \dots S_9): Absorb 2424 updates (60%60\% of total budget) calculating transitions for states the agent never visits!

After 44 passes, the value estimates on the reachable chain are:

  • V(S3)=9.3750V(S_3) = 9.3750
  • V(S2)=6.1875V(S_2) = 6.1875
  • V(S1)=2.5312V(S_1) = 2.5312
  • V(S0)=0.4556V(S_0) = 0.4556

Mean Squared Error (MSE) on the task states:

MSEuniform=14[(0.4556−7.29)2+(2.5312−8.1)2+(6.1875−9.0)2+(9.3750−10.0)2]=21.5051\text{MSE}_{\text{uniform}} = \frac{1}{4} \left[ (0.4556 - 7.29)^2 + (2.5312 - 8.1)^2 + (6.1875 - 9.0)^2 + (9.3750 - 10.0)^2 \right] = \mathbf{21.5051}

The start state S0S_0 has barely registered that a goal exists (0.45560.4556 vs true 7.29007.2900) because updates were diluted across the entire state space.


Case B: Trajectory Sampling (4040 Updates)

The planner simulates trajectories starting from S0S_0 following policy π\pi:

S0→S1→S2→S3→TerminalS_0 \to S_1 \to S_2 \to S_3 \to \text{Terminal}

Each simulated rollout executes 44 state updates. Within the 4040-update budget, the planner completes 1010 full trajectories (40/4=1040 / 4 = 10).

  1. Reachable states (S0…S3S_0 \dots S_3): Each state receives 1010 focused updates (2.5×2.5\times more than uniform sweeping).
  2. Unreachable states (S4…S9S_4 \dots S_9): Absorb 00 updates (0%0\% wasted compute).

After 1010 simulated rollouts, the value estimates are:

  • V(S3)=9.9902V(S_3) = 9.9902
  • V(S2)=8.9033V(S_2) = 8.9033
  • V(S1)=7.6570V(S_1) = 7.6570
  • V(S0)=6.0370V(S_0) = 6.0370

Mean Squared Error (MSE) on the task states:

MSEtrajectory=14[(6.0370−7.29)2+(7.6570−8.1)2+(8.9033−9.0)2+(9.9902−10.0)2]=0.4439\text{MSE}_{\text{trajectory}} = \frac{1}{4} \left[ (6.0370 - 7.29)^2 + (7.6570 - 8.1)^2 + (8.9033 - 9.0)^2 + (9.9902 - 10.0)^2 \right] = \mathbf{0.4439}

Conclusion: For the exact same computational budget (4040 updates), trajectory sampling achieves a 48×48\times reduction in prediction error (MSE 0.4439\text{MSE } 0.4439 vs 21.505121.5051) and brings the start state value close to convergence.

Code

from typing import Dict, List, Tuple

def evaluate_planning_convergence(    num_total_states: int,    reachable_chain: List[int],    gamma: float = 0.9,    alpha: float = 0.5,    terminal_reward: float = 10.0,    total_budget: int = 40,) -> Tuple[Dict[str, float], Dict[str, float]]:    """Compare Uniform Sweeping vs Trajectory Sampling on a fixed computational budget.
    Args:        num_total_states: Total size of discrete state space |S|.        reachable_chain: Sequential state ids forming the task trajectory.        gamma: Discount factor in [0, 1].        alpha: Planning update step-size.        terminal_reward: Reward achieved upon reaching terminal state.        total_budget: Fixed number of planning backups allowed.
    Returns:        Tuple of (uniform_results_summary, trajectory_results_summary).    """    chain_len = len(reachable_chain)
    # 1. Uniform Sweeps (Exhaustive round-robin across all states)    v_uniform: Dict[int, float] = {s: 0.0 for s in range(num_total_states)}    rounds = total_budget // num_total_states    for _ in range(rounds):        for s in range(num_total_states):            if s in reachable_chain:                idx = reachable_chain.index(s)                if idx == chain_len - 1:                    target = terminal_reward                else:                    next_s = reachable_chain[idx + 1]                    target = gamma * v_uniform[next_s]            else:                target = gamma * v_uniform[s]  # Irrelevant self-looping state            v_uniform[s] += alpha * (target - v_uniform[s])
    # 2. Trajectory Sampling (Simulated on-policy rollouts starting from S0)    v_traj: Dict[int, float] = {s: 0.0 for s in range(num_total_states)}    trajectories = total_budget // chain_len    for _ in range(trajectories):        for idx, s in enumerate(reachable_chain):            if idx == chain_len - 1:                target = terminal_reward            else:                next_s = reachable_chain[idx + 1]                target = gamma * v_traj[next_s]            v_traj[s] += alpha * (target - v_traj[s])
    # Compute Ground Truth V* on reachable chain    true_v: Dict[int, float] = {}    curr_val = terminal_reward    for s in reversed(reachable_chain):        true_v[s] = curr_val        curr_val *= gamma
    mse_uniform = sum((v_uniform[s] - true_v[s]) ** 2 for s in reachable_chain) / chain_len    mse_traj = sum((v_traj[s] - true_v[s]) ** 2 for s in reachable_chain) / chain_len
    res_uniform = {        "mse": round(mse_uniform, 4),        "v_start": round(v_uniform[reachable_chain[0]], 4),        "wasted_updates": total_budget - (rounds * chain_len),    }    res_traj = {        "mse": round(mse_traj, 4),        "v_start": round(v_traj[reachable_chain[0]], 4),        "wasted_updates": 0,    }    return res_uniform, res_traj

# Execute simulation matching the worked numerical comparisonu_res, t_res = evaluate_planning_convergence(    num_total_states=10,    reachable_chain=[0, 1, 2, 3],    gamma=0.9,    alpha=0.5,    terminal_reward=10.0,    total_budget=40,)
# Automated verificationassert u_res["wasted_updates"] == 24assert t_res["wasted_updates"] == 0assert abs(u_res["v_start"] - 0.4556) < 1e-4assert abs(t_res["v_start"] - 6.0370) < 1e-4assert abs(u_res["mse"] - 21.5051) < 1e-4assert abs(t_res["mse"] - 0.4439) < 1e-4
print(f"Uniform Sweeps    | Start V(S0): {u_res['v_start']:6.4f} | MSE: {u_res['mse']:7.4f} | Wasted Updates: {u_res['wasted_updates']}")print(f"Trajectory Sample | Start V(S0): {t_res['v_start']:6.4f} | MSE: {t_res['mse']:7.4f} | Wasted Updates: {t_res['wasted_updates']}")
# -> Uniform Sweeps    | Start V(S0): 0.4556 | MSE: 21.5051 | Wasted Updates: 24# -> Trajectory Sample | Start V(S0): 6.0370 | MSE:  0.4439 | Wasted Updates: 0

Watch Out For

The Trajectory Sampling Myopia and Exploration Trap

While trajectory sampling dramatically outperforms uniform sweeping by focusing on on-policy states, purely greedy trajectory sampling (ϵ=0\epsilon = 0) creates a severe failure mode: policy lock-in.

The Failure Mode: If the behavior policy during simulated rollouts is purely greedy with respect to initial, inaccurate value estimates, the planner repeatedly simulates the exact same suboptimal trajectory.

Because states off this chosen path are never visited in simulation, their values are never updated. Even if a neighboring branch contains a massive positive reward, the planner remains completely blind to it. The agent becomes trapped in a self-fulfilling prophecy: it only plans along paths it believes are good, and it only updates paths it plans along.

Concrete Fix:

  1. Always use an exploratory rollout policy: During model simulation, select actions using ϵ\epsilon-greedy exploration (ϵ∈[0.1,0.2]\epsilon \in [0.1, 0.2]) or Boltzmann softmax exploration. This guarantees that simulated trajectories occasionally branch into unvisited states, allowing the model to discover shortcut paths.
  2. Combine with Prioritized Sweeping: In deterministic or tabular domains, pair trajectory sampling with a priority queue (such as Prioritized Sweeping) that tracks states with large Bellman error δ\delta. If an exploratory rollout uncovers a large reward, the priority queue immediately propagates that error backward across all predecessor states, preventing lock-in.

The Quick Version

  • Uniform sweeps waste over 90%90\% of planning computation in large state spaces by updating unreachable or irrelevant states.
  • Trajectory sampling simulates rollouts using an internal environment model, distributing updates according to the on-policy state distribution dπ(s)d^\pi(s).
  • States along realistic task trajectories receive dense, concentrated planning updates, achieving near-optimal policies in orders of magnitude fewer operations.
  • Rollout action selection must remain exploratory (ϵ\epsilon-greedy) to avoid myopic lock-in on early suboptimal trajectories.