Skip to content
AI360Xpert
Beta

First-Visit vs Every-Visit MC Prediction

First-visit Monte Carlo averages returns only from the first time a state occurs in each episode to ensure strictly unbiased value estimates, whereas every-visit Monte Carlo averages returns from every appearance to harvest more data at the cost of transient bias.

First-visit Monte Carlo estimates state values using only the return after state S first appears in an episode, whereas every-visit Monte Carlo records returns after every occurrence.
First-visit Monte Carlo estimates state values using only the return after state S first appears in an episode, whereas every-visit Monte Carlo records returns after every occurrence.

Why Does This Exist?

In reinforcement learning, policy evaluation seeks to estimate the state-value function Vπ(s)V^\pi(s)—the expected cumulative discounted reward an agent receives when starting in state ss and following policy π\pi thereafter. Monte Carlo (MC) prediction solves this model-free by simulating complete trajectories through the environment, accumulating the observed rewards, and computing empirical sample averages.

However, in any realistic episodic environment featuring loops, cycles, or recurring conditions (such as grid navigation, robot locomotion, or financial trading sessions), an agent frequently revisits the same state ss multiple times within a single episode.

This recurring visit creates a fundamental algorithmic question: when state ss appears at time step t1t_1 and again at time step t2t_2 in the same trajectory, which downstream returns should update V(s)V(s)?

  • First-Visit MC considers only the return observed after the initial arrival at state ss during that episode, discarding subsequent visits.
  • Every-Visit MC treats every arrival at state ss as a valid sample point, averaging all corresponding returns across the trajectory.

Without this distinction, practitioners risk misinterpreting convergence guarantees, sample independence, and estimation variance. First-visit yields an independent, strictly unbiased estimator, while every-visit harvests more sample points per trajectory, trading finite-sample bias for reduced initial mean squared error (MSE).

Think of It Like This

Surveying Patient Hospital Stays

Imagine a regional healthcare director surveying patient satisfaction across various departments to evaluate quality of care. Some chronic patients check into the same specialized clinic multiple times during a single hospital stay (for example, triage upon arrival, a medication review at midday, and a final check-in before discharge).

In a First-Visit survey protocol, the clinic gives the patient an evaluation questionnaire only once: during their very first arrival. That single score reflects their entire subsequent hospital journey. Because each admitted patient contributes at most one survey response per admission, each entry comes from a separate, independent individual. The resulting average is a strictly unbiased metric of patient satisfaction, free from duplicate response skew.

In an Every-Visit survey protocol, the clinic hands the patient a feedback tablet at every single check-in counter throughout the day. If a patient visits the clinic three times, they submit three separate satisfaction ratings, all tied to the same overall stay. The hospital gathers three times as much data in the first week, but those three responses are not independent—an unusually pleasant or terrible discharge event correlates with and colors every response submitted during that stay.

Where the analogy stops: In a hospital survey, patient psychology, fatigue, or mood may evolve across check-ins. In reinforcement learning, the environment remains a Markov Decision Process (MDP): state transitions satisfy the Markov property, and the returns following each state visit are exact discounted sums of future rewards generated by the environment's transition dynamics and the stationary policy π\pi.

How It Actually Works

Mathematical Formulation and Return Estimation

Consider an episodic Markov Decision Process. Under policy π\pi, an episode generates a sequence of states, actions, and scalar rewards terminating at time step TT:

S0,A0,R1,S1,A1,R2,…,ST−1,AT−1,RT,STS_0, A_0, R_1, S_1, A_1, R_2, \dots, S_{T-1}, A_{T-1}, R_T, S_T

The discounted return GtG_t following time step tt is the sum of future rewards discounted by factor γ∈[0,1]\gamma \in [0, 1]:

Gt=∑k=0T−t−1γkRt+k+1=Rt+1+γRt+2+γ2Rt+3+⋯+γT−t−1RTG_t = \sum_{k=0}^{T - t - 1} \gamma^k R_{t + k + 1} = R_{t+1} + \gamma R_{t+2} + \gamma^2 R_{t+3} + \dots + \gamma^{T-t-1} R_T

The true state-value function is defined as the conditional expectation:

Vπ(s)=Eπ[Gt  |  St=s]V^\pi(s) = \mathbb{E}_\pi \left[ G_t \;\middle|\; S_t = s \right]

1. First-Visit Monte Carlo Prediction

In first-visit MC, we record the return GtG_t if and only if time step tt is the first time state ss appears in that specific episode. Let T1(e)(s)\mathcal{T}_1^{(e)}(s) denote the earliest time step state ss was visited in episode ee:

T1(e)(s)=min⁡{t∈{0,1,…,T(e)−1}:St(e)=s}\mathcal{T}_1^{(e)}(s) = \min \{ t \in \{0, 1, \dots, T^{(e)}-1\} : S_t^{(e)} = s \}

If state ss never appears in episode ee, the set is empty. Over a collection of MM episodes, the first-visit estimate VFV(s)V_{\text{FV}}(s) is the average of returns following these first visits:

VFV(s)=∑e=1MI(s∈τ(e))GT1(e)(s)(e)∑e=1MI(s∈τ(e))V_{\text{FV}}(s) = \frac{\sum_{e=1}^M \mathbb{I}(s \in \tau^{(e)}) G_{\mathcal{T}_1^{(e)}(s)}^{(e)}}{\sum_{e=1}^M \mathbb{I}(s \in \tau^{(e)})}

where I(s∈τ(e))\mathbb{I}(s \in \tau^{(e)}) is an indicator function equal to 11 if episode ee visited state ss, and 00 otherwise.

  • Statistical Property: Because each episode contributes at most one return to V(s)V(s), and trajectories generated across independent episodes are mutually independent, the sampled returns {GT1(e)(s)(e)}\{G_{\mathcal{T}_1^{(e)}(s)}^{(e)}\} are independent and identically distributed (i.i.d.) random variables.
  • Unbiasedness: E[VFV(s)]=Vπ(s)\mathbb{E}[V_{\text{FV}}(s)] = V^\pi(s) for any number of sampled episodes.
  • Asymptotic Convergence: By the Strong Law of Large Numbers, VFV(s)→a.s.Vπ(s)V_{\text{FV}}(s) \xrightarrow{a.s.} V^\pi(s) as M→∞M \to \infty. The variance of the estimate scales as O(1/M)\mathcal{O}(1 / M).

2. Every-Visit Monte Carlo Prediction

In every-visit MC, we record the return GtG_t for every time step tt where state ss occurs, regardless of whether it has been visited earlier in that same episode:

Tall(e)(s)={t∈{0,1,…,T(e)−1}:St(e)=s}\mathcal{T}_{\text{all}}^{(e)}(s) = \{ t \in \{0, 1, \dots, T^{(e)}-1\} : S_t^{(e)} = s \}

The every-visit estimate VEV(s)V_{\text{EV}}(s) averages all sampled returns across all visits:

VEV(s)=∑e=1M∑t∈Tall(e)(s)Gt(e)∑e=1M∣Tall(e)(s)∣V_{\text{EV}}(s) = \frac{\sum_{e=1}^M \sum_{t \in \mathcal{T}_{\text{all}}^{(e)}(s)} G_t^{(e)}}{\sum_{e=1}^M |\mathcal{T}_{\text{all}}^{(e)}(s)|}

  • Statistical Property: When state ss occurs multiple times in episode ee at times ta<tbt_a < t_b, the returns GtaG_{t_a} and GtbG_{t_b} share downstream rewards: Gta=∑k=0tb−ta−1γkRta+k+1+γtb−taGtbG_{t_a} = \sum_{k=0}^{t_b - t_a - 1} \gamma^k R_{t_a + k + 1} + \gamma^{t_b - t_a} G_{t_b} Because GtaG_{t_a} directly contains GtbG_{t_b}, the returns are statistically correlated.
  • Transient Bias: Due to intra-episode correlation, VEV(s)V_{\text{EV}}(s) is a biased estimator for finite sample sizes (E[VEV(s)]≠Vπ(s)\mathbb{E}[V_{\text{EV}}(s)] \neq V^\pi(s)).
  • Consistency: Despite finite-sample bias, every-visit MC is asymptotically consistent (VEV(s)→a.s.Vπ(s)V_{\text{EV}}(s) \xrightarrow{a.s.} V^\pi(s) as M→∞M \to \infty). Because it extracts more return samples per trajectory, its Mean Squared Error (MSE) is often lower than first-visit MC during early iterations.

3. Incremental Implementation

Both algorithms can be implemented incrementally without storing complete lists of returns in memory. At each recorded visit to state ss with return GtG_t:

N(s)←N(s)+1N(s) \leftarrow N(s) + 1

V(s)←V(s)+1N(s)[Gt−V(s)]V(s) \leftarrow V(s) + \frac{1}{N(s)} \left[ G_t - V(s) \right]

For non-stationary tasks where policy π\pi or environment dynamics drift, the sample-average step size 1/N(s)1 / N(s) is replaced by a fixed learning rate α∈(0,1]\alpha \in (0, 1]:

V(s)←V(s)+α[Gt−V(s)]V(s) \leftarrow V(s) + \alpha \left[ G_t - V(s) \right]

Worked numerical example

Consider an environment with states {S1,S2,Terminal}\{S_1, S_2, \text{Terminal}\} and undiscounted returns (γ=1.0\gamma = 1.0). Value functions and visit counters are initialized to zero: V(S1)=0,V(S2)=0V(S_1) = 0, V(S_2) = 0, and N(S1)=0,N(S2)=0N(S_1) = 0, N(S_2) = 0.

Episode 1

An agent executes policy π\pi and generates the following trajectory:

  • t=0t=0: Starts in S1S_1, takes an action, receives reward R1=+2R_1 = +2, transitions to S2S_2.
  • t=1t=1: In S2S_2, takes an action, receives reward R2=+3R_2 = +3, transitions back to S1S_1.
  • t=2t=2: In S1S_1 (second visit!), takes an action, receives reward R3=+5R_3 = +5, transitions to Terminal state TT.

Computing returns working backward from termination:

  • At t=2t=2 (S1S_1, second visit): G2=R3=5.0G_2 = R_3 = 5.0
  • At t=1t=1 (S2S_2, first visit): G1=R2+G2=3.0+5.0=8.0G_1 = R_2 + G_2 = 3.0 + 5.0 = 8.0
  • At t=0t=0 (S1S_1, first visit): G0=R1+G1=2.0+8.0=10.0G_0 = R_1 + G_1 = 2.0 + 8.0 = 10.0

First-Visit Updates for Episode 1:

  • State S1S_1: First visit occurs at t=0t=0 with G0=10.0G_0 = 10.0. The second visit at t=2t=2 is ignored. NFV(S1)←0+1=1N_{\text{FV}}(S_1) \leftarrow 0 + 1 = 1 VFV(S1)←0.0+11(10.0−0.0)=10.0V_{\text{FV}}(S_1) \leftarrow 0.0 + \frac{1}{1}(10.0 - 0.0) = 10.0
  • State S2S_2: First visit occurs at t=1t=1 with G1=8.0G_1 = 8.0. NFV(S2)←0+1=1N_{\text{FV}}(S_2) \leftarrow 0 + 1 = 1 VFV(S2)←0.0+11(8.0−0.0)=8.0V_{\text{FV}}(S_2) \leftarrow 0.0 + \frac{1}{1}(8.0 - 0.0) = 8.0

Every-Visit Updates for Episode 1:

  • State S1S_1: Updates on both occurrences (t=0t=0 and t=2t=2).
    • First occurrence (t=0t=0): NEV(S1)←1,VEV(S1)←0.0+11(10.0−0.0)=10.0N_{\text{EV}}(S_1) \leftarrow 1, \quad V_{\text{EV}}(S_1) \leftarrow 0.0 + \frac{1}{1}(10.0 - 0.0) = 10.0
    • Second occurrence (t=2t=2): NEV(S1)←2,VEV(S1)←10.0+12(5.0−10.0)=7.5N_{\text{EV}}(S_1) \leftarrow 2, \quad V_{\text{EV}}(S_1) \leftarrow 10.0 + \frac{1}{2}(5.0 - 10.0) = 7.5
    • Equivalent batch average: 10.0+5.02=7.5\frac{10.0 + 5.0}{2} = 7.5
  • State S2S_2: Updates on the single visit at t=1t=1. NEV(S2)←1,VEV(S2)←8.0N_{\text{EV}}(S_2) \leftarrow 1, \quad V_{\text{EV}}(S_2) \leftarrow 8.0

Episode 2

The agent collects a second trajectory:

  • t=0t=0: Starts in S2S_2, receives reward R1=+4R_1 = +4, transitions to S1S_1.
  • t=1t=1: In S1S_1, receives reward R2=+2R_2 = +2, transitions to Terminal state TT.

Computing returns working backward:

  • At t=1t=1 (S1S_1): G1=R2=2.0G_1 = R_2 = 2.0
  • At t=0t=0 (S2S_2): G0=R1+G1=4.0+2.0=6.0G_0 = R_1 + G_1 = 4.0 + 2.0 = 6.0

First-Visit Updates after Episode 2:

  • State S1S_1: First visit in Episode 2 is at t=1t=1 with G1=2.0G_1 = 2.0. NFV(S1)←1+1=2N_{\text{FV}}(S_1) \leftarrow 1 + 1 = 2 VFV(S1)←10.0+12(2.0−10.0)=6.0V_{\text{FV}}(S_1) \leftarrow 10.0 + \frac{1}{2}(2.0 - 10.0) = 6.0
  • State S2S_2: First visit in Episode 2 is at t=0t=0 with G0=6.0G_0 = 6.0. NFV(S2)←1+1=2N_{\text{FV}}(S_2) \leftarrow 1 + 1 = 2 VFV(S2)←8.0+12(6.0−8.0)=7.0V_{\text{FV}}(S_2) \leftarrow 8.0 + \frac{1}{2}(6.0 - 8.0) = 7.0

Every-Visit Updates after Episode 2:

  • State S1S_1: One visit occurs at t=1t=1 with G1=2.0G_1 = 2.0. NEV(S1)←2+1=3N_{\text{EV}}(S_1) \leftarrow 2 + 1 = 3 VEV(S1)←7.5+13(2.0−7.5)=7.5−1.833=5.67V_{\text{EV}}(S_1) \leftarrow 7.5 + \frac{1}{3}(2.0 - 7.5) = 7.5 - 1.833 = 5.67
    • Batch verification: 10.0+5.0+2.03=17.03≈5.67\frac{10.0 + 5.0 + 2.0}{3} = \frac{17.0}{3} \approx 5.67
  • State S2S_2: One visit occurs at t=0t=0 with G0=6.0G_0 = 6.0. NEV(S2)←1+1=2N_{\text{EV}}(S_2) \leftarrow 1 + 1 = 2 VEV(S2)←8.0+12(6.0−8.0)=7.0V_{\text{EV}}(S_2) \leftarrow 8.0 + \frac{1}{2}(6.0 - 8.0) = 7.0

Notice how V(S2)V(S_2) evaluates to identically 7.07.0 in both methods because S2S_2 was never revisited within either episode. In contrast, V(S1)V(S_1) diverges (6.006.00 vs 5.675.67) because Every-Visit incorporated the intermediate sub-trajectory return G2=5.0G_2 = 5.0.

Code

from typing import Dict, List, Tuple

def first_visit_mc_prediction(    episodes: List[List[Tuple[str, float]]],    gamma: float = 1.0,) -> Dict[str, float]:    """Estimate state values using First-Visit Monte Carlo prediction.
    Args:        episodes: List of trajectories, where each trajectory is a list of            (state, reward) tuples representing (S_t, R_{t+1}) up to termination.        gamma: Discount factor in [0, 1].
    Returns:        Dictionary mapping each visited state to its estimated value V(s).    """    returns_sum: Dict[str, float] = {}    returns_count: Dict[str, int] = {}
    for episode in episodes:        # Step 1: Work backward to calculate return G_t for each step        G = 0.0        T = len(episode)        step_returns: List[Tuple[str, float]] = []
        for t in reversed(range(T)):            state, reward = episode[t]            G = gamma * G + reward            step_returns.append((state, G))
        # Reverse back to forward chronological order (t = 0 ... T-1)        step_returns.reverse()
        # Step 2: Track states visited in this episode; update on first occurrence only        visited_in_episode = set()        for state, G_t in step_returns:            if state not in visited_in_episode:                visited_in_episode.add(state)                returns_sum[state] = returns_sum.get(state, 0.0) + G_t                returns_count[state] = returns_count.get(state, 0) + 1
    return {s: returns_sum[s] / returns_count[s] for s in returns_sum}

def every_visit_mc_prediction(    episodes: List[List[Tuple[str, float]]],    gamma: float = 1.0,) -> Dict[str, float]:    """Estimate state values using Every-Visit Monte Carlo prediction.
    Args:        episodes: List of trajectories, where each trajectory is a list of            (state, reward) tuples representing (S_t, R_{t+1}) up to termination.        gamma: Discount factor in [0, 1].
    Returns:        Dictionary mapping each visited state to its estimated value V(s).    """    returns_sum: Dict[str, float] = {}    returns_count: Dict[str, int] = {}
    for episode in episodes:        # Step 1: Work backward to calculate return G_t for each step        G = 0.0        T = len(episode)
        # In every-visit, every step update can accumulate directly        for t in reversed(range(T)):            state, reward = episode[t]            G = gamma * G + reward            returns_sum[state] = returns_sum.get(state, 0.0) + G            returns_count[state] = returns_count.get(state, 0) + 1
    return {s: returns_sum[s] / returns_count[s] for s in returns_sum}

if __name__ == "__main__":    # Trajectories matching the worked numerical example:    # Episode 1: S1 -(r=2)-> S2 -(r=3)-> S1 -(r=5)-> Terminal    # Episode 2: S2 -(r=4)-> S1 -(r=2)-> Terminal    sample_episodes: List[List[Tuple[str, float]]] = [        [("S1", 2.0), ("S2", 3.0), ("S1", 5.0)],        [("S2", 4.0), ("S1", 2.0)],    ]
    v_first = first_visit_mc_prediction(sample_episodes, gamma=1.0)    v_every = every_visit_mc_prediction(sample_episodes, gamma=1.0)
    print("--- First-Visit MC Value Estimates ---")    for state in sorted(v_first):        print(f"V_FV({state}) = {v_first[state]:.2f}")
    print("\n--- Every-Visit MC Value Estimates ---")    for state in sorted(v_every):        print(f"V_EV({state}) = {v_every[state]:.2f}")
--- First-Visit MC Value Estimates ---V_FV(S1) = 6.00V_FV(S2) = 7.00
--- Every-Visit MC Value Estimates ---V_EV(S1) = 5.67V_EV(S2) = 7.00

Watch Out For

High variance of Monte Carlo returns requiring hundreds of complete episodes before values stabilize

Because Monte Carlo estimation computes return GtG_t as the raw sum of all rewards from step tt until the terminal state without any intermediate bootstrapping, every random transition and stochastic reward along the rest of the trajectory compounds into GtG_t.

In tasks with long horizons (T>100T > 100) or noisy rewards, returns exhibit extreme sample variance. If an agent attempts to perform control (policy iteration) using value estimates built from only a few dozen episodes, noisy return fluctuations will corrupt the greedy policy improvements, locking the policy into suboptimal behaviors.

Symptom: Value functions swing wildly between evaluation batches, and policy improvement steps fail to stabilize or repeatedly oscillate.

Concrete Fix: Either collect hundreds to thousands of episodes before updating policies, incorporate discount factors γ<1.0\gamma < 1.0 to damp distant reward noise, or switch to bootstrapping Temporal Difference methods such as TD(0) or n-step TD which replace distal stochasticity with value estimates V(St+1)V(S_{t+1}).

Correlated intra-episode returns introducing transient bias in small datasets

Every-visit Monte Carlo incorporates multiple returns from the same episode when states recur. If a small dataset contains an outlier episode where an agent gets trapped in a cycle before receiving a large penalty or reward, every-visit MC counts that single anomalous trajectory multiple times for each recurring state.

Symptom: In small-sample regimes (M<30M < 30), recurring states display severe overestimation or underestimation bias, deviating significantly from the true expected value Vπ(s)V^\pi(s).

Concrete Fix: When evaluating policies on small historical logs where strict unbiasedness is required, use First-Visit MC. Reserve Every-Visit MC for high-throughput environments where sample volume is large enough for asymptotic consistency to dominate.

The Quick Version

  • First-Visit MC averages the return following only the initial visit to state ss per episode, yielding a strictly unbiased estimator (E[V(s)]=Vπ(s)\mathbb{E}[V(s)] = V^\pi(s)) with i.i.d. return samples.
  • Every-Visit MC averages returns from all occurrences of state ss in an episode; although intra-episode correlation introduces finite-sample bias, it is asymptotically consistent and often lowers early mean squared error.
  • Both algorithms converge to the true value function Vπ(s)V^\pi(s) as the number of sampled episodes approaches infinity by the Law of Large Numbers.
  • Because both methods rely on complete episodic returns without bootstrapping, they require terminating environments and experience higher sample variance than Temporal Difference learning.