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.
Why Does This Exist?
In reinforcement learning, policy evaluation seeks to estimate the state-value function —the expected cumulative discounted reward an agent receives when starting in state and following policy 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 multiple times within a single episode.
This recurring visit creates a fundamental algorithmic question: when state appears at time step and again at time step in the same trajectory, which downstream returns should update ?
- First-Visit MC considers only the return observed after the initial arrival at state during that episode, discarding subsequent visits.
- Every-Visit MC treats every arrival at state 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 .
How It Actually Works
Mathematical Formulation and Return Estimation
Consider an episodic Markov Decision Process. Under policy , an episode generates a sequence of states, actions, and scalar rewards terminating at time step :
The discounted return following time step is the sum of future rewards discounted by factor :
The true state-value function is defined as the conditional expectation:
1. First-Visit Monte Carlo Prediction
In first-visit MC, we record the return if and only if time step is the first time state appears in that specific episode. Let denote the earliest time step state was visited in episode :
If state never appears in episode , the set is empty. Over a collection of episodes, the first-visit estimate is the average of returns following these first visits:
where is an indicator function equal to if episode visited state , and otherwise.
- Statistical Property: Because each episode contributes at most one return to , and trajectories generated across independent episodes are mutually independent, the sampled returns are independent and identically distributed (i.i.d.) random variables.
- Unbiasedness: for any number of sampled episodes.
- Asymptotic Convergence: By the Strong Law of Large Numbers, as . The variance of the estimate scales as .
2. Every-Visit Monte Carlo Prediction
In every-visit MC, we record the return for every time step where state occurs, regardless of whether it has been visited earlier in that same episode:
The every-visit estimate averages all sampled returns across all visits:
- Statistical Property: When state occurs multiple times in episode at times , the returns and share downstream rewards: Because directly contains , the returns are statistically correlated.
- Transient Bias: Due to intra-episode correlation, is a biased estimator for finite sample sizes ().
- Consistency: Despite finite-sample bias, every-visit MC is asymptotically consistent ( as ). 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 with return :
For non-stationary tasks where policy or environment dynamics drift, the sample-average step size is replaced by a fixed learning rate :
Worked numerical example
Consider an environment with states and undiscounted returns (). Value functions and visit counters are initialized to zero: , and .
Episode 1
An agent executes policy and generates the following trajectory:
- : Starts in , takes an action, receives reward , transitions to .
- : In , takes an action, receives reward , transitions back to .
- : In (second visit!), takes an action, receives reward , transitions to Terminal state .
Computing returns working backward from termination:
- At (, second visit):
- At (, first visit):
- At (, first visit):
First-Visit Updates for Episode 1:
- State : First visit occurs at with . The second visit at is ignored.
- State : First visit occurs at with .
Every-Visit Updates for Episode 1:
- State : Updates on both occurrences ( and ).
- First occurrence ():
- Second occurrence ():
- Equivalent batch average:
- State : Updates on the single visit at .
Episode 2
The agent collects a second trajectory:
- : Starts in , receives reward , transitions to .
- : In , receives reward , transitions to Terminal state .
Computing returns working backward:
- At ():
- At ():
First-Visit Updates after Episode 2:
- State : First visit in Episode 2 is at with .
- State : First visit in Episode 2 is at with .
Every-Visit Updates after Episode 2:
- State : One visit occurs at with .
- Batch verification:
- State : One visit occurs at with .
Notice how evaluates to identically in both methods because was never revisited within either episode. In contrast, diverges ( vs ) because Every-Visit incorporated the intermediate sub-trajectory return .
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.00Watch Out For
High variance of Monte Carlo returns requiring hundreds of complete episodes before values stabilize
Because Monte Carlo estimation computes return as the raw sum of all rewards from step until the terminal state without any intermediate bootstrapping, every random transition and stochastic reward along the rest of the trajectory compounds into .
In tasks with long horizons () 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 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 .
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 (), recurring states display severe overestimation or underestimation bias, deviating significantly from the true expected value .
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 per episode, yielding a strictly unbiased estimator () with i.i.d. return samples.
- Every-Visit MC averages returns from all occurrences of state 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 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.