TAI BUI
Back to curriculum
BuildPython

Monte Carlo Methods — Learning from Complete Episodes

Dynamic programming needs a model. Monte Carlo needs nothing but episodes: run the policy, watch the returns, average them. It's the simplest idea in RL, and the one that unlocks everything downstream.

TIME: ~75 minutesPREREQUISITES: Phase 9 · 01 (MDPs), Phase 9 · 02 (Dynamic Programming)

Learning Objectives

  • Explain why Monte Carlo methods only need the ability to sample from an environment, not a known transition model, and state the variance-for-applicability tradeoff versus dynamic programming.
  • Distinguish first-visit from every-visit Monte Carlo, derive the incremental mean update, and explain how swapping in a constant step size α turns the sample-average estimator into the bridge from MC to TD.
  • Implement first-visit MC policy evaluation and ε-greedy MC control from raw episode rollouts in code, and validate the result against Lesson 02's dynamic-programming baseline.
  • Explain why exploration becomes a problem under MC but not DP, and describe the three fixes, exploring starts, ε-greedy, and off-policy importance sampling, including why importance-sampling variance grows with episode horizon.

The Problem

Dynamic programming is elegant, but it assumes you can query P(s' | s, a) for every state and action. Almost nothing in the real world offers that. A robot can't analytically compute the distribution over camera pixels after a joint torque. A pricing algorithm can't integrate over every possible customer reaction. An LLM can't enumerate every possible continuation after a token.

What you need instead is a method that only requires the ability to sample from the environment: run the policy, collect a trajectory s_0, a_0, r_1, s_1, a_1, r_2, …, s_T, and use it to estimate values. That's Monte Carlo.

The shift from DP to MC matters philosophically: you trade a known model with exact backups for sampled rollouts averaged into a return. Variance goes up, but applicability explodes. Every RL algorithm after this lesson (TD, Q-learning, REINFORCE, PPO, GRPO) is a Monte Carlo estimator at heart, sometimes with bootstrapping layered on top.

Warm-up0/3
1. In dynamic programming on an MDP, what does each value backup use to update a state's value?Warm-up
A 4 by 4 GridWorld table of state values after two sweeps of policy evaluation for the uniform-random policy with gamma 0.99, with the cell (1,1) outlined as the next one to be updated and shown as new V(1,1) equals a question mark.
Values computed here by synchronous sweeps over the lesson's GridWorld.
2. The rewards received after step t are 1, 1, 1 and the discount factor is 0.5. What is the discounted return from step t?Warm-up
Three boxes in a row for the rewards received after step t, each equal to 1, with a discount factor of 0.5 and a highlighted box reading return from step t equals a question mark.
3. You estimate an average by drawing independent samples from a distribution. What happens to the estimate as you draw more samples?Warm-up
Twelve independent rolls of a fair die shown as small boxes with their mean 2.83, above a table of sample means for 12 rolls, 120 rolls and 12,000 rolls where the last two are question marks.
Rolls drawn here with numpy (seed 3).
Check: The Problem0/2
1. What capability do Monte Carlo methods require that dynamic programming does not?Explain
Two code panels: a dynamic programming sweep over all states that sums P(s2|s,a) times reward plus gamma V(s2), and a Monte Carlo evaluation loop that calls rollout, returns_from and updates V.
Typed sketches of both methods, not captured output.
2. What does moving from DP to MC trade away, and what does it gain?Explain
A line chart of the Monte Carlo running-average estimate of V(0,0) over 3000 episodes, wandering around a flat green line at the dynamic programming value -39.41.
Real run of the lesson's rollout and returns_from. DP value from the lesson (Lesson 02).

The Concept

Monte Carlo: rollout, compute returns, average; first-visit vs every-visit

The core idea, in one line: V^π(s) = E_π[G_t | s_t = s] ≈ (1/N) Σ_i G^{(i)}(s) where G^{(i)}(s) are observed returns following visits to s under policy π.

First-visit vs every-visit MC. Given an episode that visits state s multiple times, first-visit MC counts only the return from the first visit; every-visit MC counts all of them. Both are unbiased in the limit. First-visit is easier to analyze, since the samples are iid. Every-visit uses more data per episode and typically converges faster in practice.

Incremental mean. Instead of storing all returns, update the running average:

V_n(s) = V_{n-1}(s) + (1/n) [G_n - V_{n-1}(s)]

Reorganize that into V_new = V_old + α · (target - V_old) with α = 1/n. Swap the 1/n for a constant step-size α ∈ (0, 1) and you get a non-stationary MC estimator that tracks a moving π. That single substitution is the entire jump from MC to TD, and from there to every modern RL algorithm.

Exploration is now a problem. DP touched every state by enumeration; MC only sees states the policy actually visits. If π is deterministic, whole regions of the state space never get sampled, and their value estimates sit at zero forever. Three fixes, in historical order:

  1. Exploring starts. Start each episode from a random (s, a) pair. This guarantees coverage, but it's unrealistic in practice: you can't reset a robot into an arbitrary state.
  2. ε-greedy. Act greedy with respect to the current Q, but with probability ε pick a random action instead. All state-action pairs get sampled asymptotically.
  3. Off-policy MC. The first two fixes are on-policy: the same policy you're improving is the one generating the data. Off-policy MC drops that constraint. Collect data under a behavior policy μ, then learn about a different target policy π by reweighting each observed return by the probability ratio π(a|s)/μ(a|s), a correction called importance sampling. Variance is high, but this is the bridge to replay-buffer methods like DQN.

Monte Carlo Control. Evaluate → improve → evaluate, the same loop as policy iteration, except evaluation is now sampling-based:

  1. Run π, get an episode.
  2. Update Q(s, a) from the observed returns.
  3. Make π ε-greedy with respect to Q.
  4. Repeat.

It converges to Q* and π* with probability 1 under mild conditions: every pair visited infinitely often, and α satisfying Robbins-Monro.

Check: The Concept0/18
1. What does 'Monte Carlo' mean as an estimation method?Define
A table of six episodes started at cell (0,0) of the GridWorld under the uniform-random policy with gamma 0.99, listing each episode's number of steps and observed return, followed by the line estimate of V(0,0) from these six equals a question mark.
Episodes run here with the lesson's rollout and returns_from functions.
2. What is the return G_t in reinforcement learning?Define
An episode of five steps drawn as boxes holding rewards r1 = -1, r2 = 0, r3 = 2, r4 = -1 and r5 = 3, with a dashed marker at step t = 2 between r2 and r3 and a label G_2 equals a question mark.
Reward values are illustrative.
3. What is every-visit Monte Carlo?Define
A table of one episode with gamma 1: steps t = 0 to 3 in states A, B, A, C with rewards 1, 0, 2, 1 and returns 4, 3, 3, 1, so state A appears twice.
Illustrative episode.
4. What is importance sampling in off-policy Monte Carlo?Define
A table of one three-step episode generated by following the behavior policy mu, listing for each step the state, the action taken and the probabilities pi(a|s) and mu(a|s), plus an observed return of 5.0 and a question about how to use it to estimate V under pi.
Probabilities and the return are illustrative.
5. What makes a Monte Carlo method on-policy?Define
A diagram of a Monte Carlo control loop with a box for the policy being improved, a box for the policy that generates the episodes marked with a question mark, and a box of episodes with s, a, r that feeds a dashed arrow back to the policy being improved.
6. What is off-policy learning?Define
A 4 by 4 GridWorld with one wandering blue path for a random policy mu and an orange dashed path along the top row then down the right column for a second policy pi.
Illustrative. The blue path is a real rollout of the uniform-random policy; the orange route is drawn by hand.
7. What is the difference between first-visit and every-visit Monte Carlo as defined in this lesson?Define
A 4 by 4 GridWorld where one episode's visited cells are labelled with their time steps, cells (1,1) at t = 2 and 4 and (1,2) at t = 3 and 5 outlined as visited twice, next to a table of returns G_t at those four steps.
Real episode from the lesson's rollout, returns with gamma 0.99.
8. How does epsilon-greedy action selection work, as this lesson describes it?Define
Four boxes for the actions up, down, left and right in one state with Q values -4.1, -2.3, -3.6 and -3.0 and epsilon equal to 0.1, above a highlighted box reading action taken next equals a question mark.
Q values are illustrative.
9. In the incremental mean update V_new = V_old + α(target - V_old), what happens when you swap the sample-average step size 1/n for a constant α?Explain
Two update rules, V += (G - V)/n and V += 0.3 (G - V), and ten returns for one state, five zeros followed by five ones, as the policy improves, with a question about V after the tenth return.
Return sequence is illustrative.
10. Which exploration fix guarantees coverage but is unrealistic in practice, since you can't reset a robot into an arbitrary state?Explain
A 4 by 4 grid of visit counts after 100 episodes of a deterministic policy that moves down then right, with the cells on the path showing counts, every other cell showing 0 and the terminal cell marked end, next to a card saying the robot can only be reset to (0,0).
Counts from a real run of the lesson's GridWorld.
11. What is the Monte Carlo Control loop as this lesson defines it?Explain
Three cards from epsilon-greedy MC control after 500 episodes: the policy at (0,0) with its greedy action and 10 percent random action, the four Q values at (0,0), and the first four (state, action, reward) steps of the latest episode, with a question about how they feed each other.
Real run of the lesson's control logic, seed 1.
12. Under what conditions does MC control converge to Q* and π* with probability 1?Explain
Two cards: the number of visits to each of the four actions in state (0,0) after 5000 epsilon-greedy episodes, and the step size alpha_n = 1/n for n from 1 to 5 with values 1.000, 0.500, 0.333, 0.250 and 0.200.
Visit counts from a real run of epsilon-greedy MC control (seed 3).
13. Why write the sample average as V_old + (1/n)(G - V_old) instead of storing every return?Explain
Two code versions of a running average, Version 1 appends G to a list and divides the sum by its length, Version 2 does n += 1 and V += (G - V)/n, above a table for returns 2, 6, 4 and 8 giving V equal to 2, 4, 4 and 5 after each.
Both versions give the same V in every row.
14. Why is first-visit MC easier to analyze than every-visit MC?Explain
Three episodes with gamma 1 listing the return after each visit to state A: episode 1 has two visits with returns 4 and 3, episode 2 has one visit with return 3, episode 3 has three visits with returns 5, 4 and 3.
Illustrative episodes.
15. Why does exploration become a problem for MC but not for DP?Explain
A 4 by 4 GridWorld showing a deterministic policy as arrows, right along every row until the last column then down, with the terminal cell marked end, next to a card saying every episode starts from reset at (0,0) and that V^pi is wanted for all 16 cells.
16. Why is each off-policy return multiplied by pi(a|s)/mu(a|s)?Explain
A table for one state with mu(a|s) 0.5 for left and right, pi(a|s) 0.1 for left and 0.9 for right, and how many times each action was taken in 1000 logged steps (493 left, 507 right), above two bars for the share of steps taking right: 0.51 in the logs and 0.90 under pi.
Probabilities are illustrative. The 1000 logged actions were sampled here with numpy.
17. The target policy takes the observed action with probability 1.0 and the behavior policy takes it with probability 0.25, at each of 3 steps. What is the importance weight for the trajectory?Apply
A table of three steps of one trajectory, each with pi(a|s) of 1.0 and mu(a|s) of 0.25 for the observed action, and a line asking for the importance weight of the trajectory.
18. You train on a real robot that cannot be reset to arbitrary states, but every state-action pair must still get sampled eventually. Which design fits?Design
A card describing a real robot setup, reset cannot put it in an arbitrary state, every state-action pair must be sampled eventually, above a chain of boxes from the start pose to state-action pairs marked with question marks.

Build It

Step 1: rollout → list of (s, a, r)

python
def rollout(env, policy, max_steps=200):
    trajectory = []
    s = env.reset()
    for _ in range(max_steps):
        a = policy(s)
        s_next, r, done = env.step(s, a)
        trajectory.append((s, a, r))
        s = s_next
        if done:
            break
    return trajectory

No model, only env.reset() and env.step(s, a). Same interface as a gym environment but stripped down.

Step 2: compute returns (reverse sweep)

python
def returns_from(trajectory, gamma):
    returns = []
    G = 0.0
    for _, _, r in reversed(trajectory):
        G = r + gamma * G
        returns.append(G)
    return list(reversed(returns))

One pass, O(T). The backward recurrence G_t = r_{t+1} + γ G_{t+1} avoids re-summing.

Step 3: first-visit MC evaluation

python
def mc_policy_evaluation(env, policy, episodes, gamma=0.99):
    V = defaultdict(float)
    counts = defaultdict(int)
    for _ in range(episodes):
        trajectory = rollout(env, policy)
        returns = returns_from(trajectory, gamma)
        seen = set()
        for t, ((s, _, _), G) in enumerate(zip(trajectory, returns)):
            if s in seen:
                continue
            seen.add(s)
            counts[s] += 1
            V[s] += (G - V[s]) / counts[s]
    return V

Three lines do the work: mark state as seen on first visit, increment count, update running mean.

Step 4: ε-greedy MC control (on-policy)

python
def mc_control(env, episodes, gamma=0.99, epsilon=0.1):
    Q = defaultdict(lambda: {a: 0.0 for a in ACTIONS})
    counts = defaultdict(lambda: {a: 0 for a in ACTIONS})
 
    def policy(s):
        if random() < epsilon:
            return choice(ACTIONS)
        return max(Q[s], key=Q[s].get)
 
    for _ in range(episodes):
        trajectory = rollout(env, policy)
        returns = returns_from(trajectory, gamma)
        seen = set()
        for (s, a, _), G in zip(trajectory, returns):
            if (s, a) in seen:
                continue
            seen.add((s, a))
            counts[s][a] += 1
            Q[s][a] += (G - Q[s][a]) / counts[s][a]
    return Q, policy

Step 5: compare to DP gold standard

Your MC estimate of V^π should agree with the DP result from Lesson 02 as episodes → ∞. In practice, 50,000 episodes on 4×4 GridWorld gets you within ~0.1 of the DP answer.

Check: Build It0/7
1. You have written first-visit MC evaluation for 4x4 GridWorld. What is the right way to validate your V^π estimate?Explain
A call to mc_policy_evaluation with the uniform-random policy and gamma 0.99, and a table of the V(0,0) estimate read after 100, 1000, 10,000 and 50,000 episodes of one run.
Real run of the lesson's mc_policy_evaluation logic.
2. Why does returns_from sweep the trajectory in reverse using G = r + gamma * G?Explain
The returns_from function with its reversed loop G = r + gamma * G, called on a trajectory of four steps with every reward equal to -1 and gamma 0.9.
3. returns_from runs on a trajectory whose rewards are 0, 0, 1 in order, with gamma = 0.5. What list does it return?Apply
The returns_from function and a Python session calling it on a trajectory with rewards 0, 0, 1 and gamma 0.5, with the output shown as a question mark.
Session typed, not captured.
4. mc_policy_evaluation gets one episode with (state, reward) pairs (A,1), (B,0), (A,2) and gamma = 1. After the episode, what is V[A]?Apply
An episode table with three steps in states A, B, A with rewards 1, 0, 2 and gamma 1, next to the seen-set and running-mean lines of the first-visit loop, with a question asking for V[A].
5. Q[s][a] is the average of 3 returns and equals 4.0. A fourth return G = 8.0 arrives, and counts[s][a] becomes 4. What is Q[s][a] after Q[s][a] += (G - Q[s][a]) / counts[s][a]?Apply
Two cards, one showing Q[s][a] equal to 4.0 as the average of three returns, and one showing a fourth return G equal to 8.0 with counts becoming 4, above the update line Q[s][a] += (G - Q[s][a])/counts[s][a] with the result as a question mark.
6. In mc_control, Q['s0'] is {'left': 0.0, 'right': 0.0}, inserted in that order, and random() returns 0.5 with epsilon = 0.1. What does policy('s0') return?Apply
The policy function from mc_control with its epsilon check and max over Q[state], and a card stating Q['s0'] is {'left': 0.0, 'right': 0.0} in that order, epsilon is 0.1, random() returns 0.5, and policy('s0') is a question mark.
7. rollout is called with max_steps=200 and a policy that never reaches the terminal state. How many (s, a, r) tuples does it return?Apply
The rollout loop with max_steps 200, append of one (state, action, reward) tuple per step and a break on done, and a call with a policy that always goes up and never reaches the terminal cell, with the length of the result as a question mark.

Pitfalls

  • Infinite episodes. MC requires episodes to terminate. If your policy can loop forever, cap max_steps and treat hitting that cap as an implicit failure. GridWorld with a random policy routinely times out, and that's normal as long as you count it correctly.
  • Variance. MC uses full returns, so on long episodes the variance is huge: one unlucky reward at the end shifts V(s_0) by the same amount. TD methods (Lesson 04) cut this down by bootstrapping.
  • State coverage. Greedy MC on a fresh Q with ties will only ever try one action. You have to explore, whether through ε-greedy, exploring starts, or UCB.
  • Non-stationary policies. If π changes, as it does in MC control, old returns come from a different policy. Constant-α MC handles that; sample-average MC does not.
  • Off-policy importance sampling. The weights π(a|s)/μ(a|s) multiply across a trajectory, so variance explodes with horizon. Per-decision IS reweights each reward individually instead of the whole return, and weighted IS normalizes by the sum of weights instead of the episode count; both cut variance relative to plain IS. Cap it with one of those, or switch to TD.
Check: Pitfalls0/7
1. Why does MC have high variance on long episodes compared with TD?Explain
A strip plot of the returns G_0 of 40 episodes started at (0,0) under the uniform-random policy, spread from -86.6 to -10.5, with episode lengths between 11 and 200 steps.
Real rollouts of the lesson's GridWorld. Every reward is -1, so the return depends on the episode length.
2. Your off-policy MC estimate barely moves between runs on short episodes, but on a 500-step episode the estimator swings wildly between runs even after thousands of episodes. What is the most likely cause?Analyze
Two strip plots of six off-policy Monte Carlo estimates divided by the true value: for 5-step episodes all six sit within 0.04 of each other near 1.0, for 500-step episodes they spread from 0.79 to 1.25.
Toy simulation, not the lesson's GridWorld: two-action steps, mu picks right with probability 0.5, pi with 0.55, reward 1 per right, plain importance sampling.
3. You run MC evaluation with a random policy and some rollouts never reach the terminal state, they just wander. What should you do?Analyze
A bar chart of how many of 2000 uniform-random GridWorld rollouts took 1-20, 21-50, 51-100, 101-200 and 201-500 steps to reach the terminal cell (418, 740, 521, 271, 50).
Real rollouts of the lesson's GridWorld with the step cap lifted (none ran past 500 steps).
4. You initialize Q to all zeros and run purely greedy MC control with no exploration. After thousands of episodes the agent has only ever taken one action from the start state. What is going on?Analyze
Code for purely greedy MC control with epsilon 0 and a fresh Q table, above a table showing Q at the start state (0,0) equal to 0.0 for up, down, left and right, with a note that after thousands of episodes only one action has been taken there.
5. Your MC estimate of V(0,0) will not settle near the DP answer even after a very large episode budget. Which check comes first?Analyze
The 4 by 4 dynamic programming value table for the uniform-random policy with the cell (0,0) outlined at -39.41, next to a card saying the Monte Carlo estimate of V(0,0) keeps missing that target even with a very large episode budget.
DP values computed here, matching the lesson's -39.41.
6. MC control uses sample-average updates (alpha = 1/n) while the policy keeps improving. Early returns came from weak policies. What goes wrong?Analyze
A line chart of the 50-episode average return of epsilon-greedy MC control over 3000 episodes, starting very negative and rising as the policy improves, with a note that Q is updated with alpha equal to 1/n throughout.
Real run of the lesson's control logic (seed 23).
7. You must evaluate a new target policy from 500-step trajectories logged under an older behavior policy, and plain importance sampling swings wildly. Which approach fits?Design
A strip plot of the importance weights of 12 logged 500-step trajectories on a power-of-ten axis, spread from about 10^-2.7 to 10^0.5.
Toy simulation, not the lesson's GridWorld: pi takes right with probability 0.55, mu with 0.5, weight is the product of ratios over 500 steps.

Use It

The 2026 role of Monte Carlo methods:

Use caseWhy MC
Short-horizon games (blackjack, poker)Episodes terminate naturally; returns are clean.
Offline evaluation of a logged policyAverage discounted returns over stored trajectories.
Monte Carlo Tree Search (AlphaZero)MC rollouts from tree leaves guide selection.
LLM RL evaluationCompute average reward over sampled completions for a given policy.
Baseline estimation in PPOThe advantage target A_t = G_t - V(s_t) uses an MC G_t.
Teaching RLSimplest algorithm that actually works: strip out bootstrapping and you see the core.

Modern deep-RL algorithms (PPO, SAC) interpolate between pure MC (full returns) and pure TD (one-step bootstrap) via n-step returns or GAE. Both endpoints are instances of the same estimator.

Check: Use It0/2
1. Why are short-horizon games like blackjack and poker a natural fit for Monte Carlo?Explain
A blackjack hand drawn as three boxes: state 13 versus dealer 10 with action hit and reward 0, state 19 versus 10 with action stand and reward +1, then hand over with the dealer busting.
Typed example, not captured from a game.
2. You hold stored trajectories generated by the very policy you want to evaluate. Which is the simplest sound method?Design
Three stored trajectories of rewards, (-1, -1, 5), (-1, 3) and (-1, -1, -1, 5), all generated by the policy being evaluated with gamma 0.9, and a question about estimating the start value from them.
Rewards are illustrative.

Ship It

Save as outputs/skill-mc-evaluator.md:

markdown
---
name: mc-evaluator
description: Evaluate a policy via Monte Carlo rollouts and produce a convergence report with DP-comparison if available.
version: 1.0.0
phase: 9
lesson: 3
tags: [rl, monte-carlo, evaluation]
---
 
Given an environment (episodic, with reset+step API) and a policy, output:
 
1. Method. First-visit vs every-visit MC. Reason.
2. Episode budget. Target number, variance diagnostic, expected standard error.
3. Exploration plan. ε schedule (if needed) or exploring starts.
4. Gold-standard comparison. DP-optimal V* if tabular; otherwise a bound from a Q-learning / PPO baseline.
5. Termination check. Max-step cap, timeouts, handling of non-terminating trajectories.
 
Refuse to run MC on non-episodic tasks without a finite horizon cap. Refuse to report V^π estimates from fewer than 100 episodes per state for tabular tasks. Flag any policy with zero-variance actions as an exploration risk.
Author's Note

The first time this clicked for me wasn't the math, it was watching the numbers converge. Run a few thousand episodes of the random policy against the DP answer from Lesson 02, and V(0,0) crawls toward the exact value: noisy at first, then unmistakably heading somewhere specific. That's the moment Monte Carlo stops being an abstract idea about sampling and turns into something you can watch happen in real time. If your estimate refuses to settle, don't reach for a bigger episode budget first. Check that your policy actually reaches every state you're trying to evaluate. Most 'MC isn't converging' bugs I've run into turn out to be exploration bugs wearing a variance costume.

Exercises

  1. Easy. Implement first-visit MC evaluation of the uniform-random policy on 4×4 GridWorld. Run 10,000 episodes. Plot V(0,0) as a function of episode count against the DP answer.
  2. Medium. Implement ε-greedy MC control with ε ∈ {0.01, 0.1, 0.3}. Compare mean return after 20,000 episodes. What does the curve look like? Where does the bias-variance tradeoff live?
  3. Hard. Implement off-policy MC with importance sampling: collect data under uniform-random policy μ, estimate V^π for the deterministic optimal policy π. Compare plain IS vs per-decision IS vs weighted IS. Which has lowest variance?

Key Terms

TermWhat people sayWhat it actually means
Monte Carlo"Random sampling"Estimate expectations by averaging over iid samples from the distribution.
Return G_t"Future reward"Sum of discounted rewards from step t to episode end: Σ_{k≥0} γ^k r_{t+k+1}.
First-visit MC"Count each state once"Only the first visit in an episode contributes to the value estimate.
Every-visit MC"Use all visits"Every visit contributes; slightly biased but more sample-efficient.
ε-greedy"Exploration noise"Pick greedy action with prob 1-ε; random action with prob ε.
Importance sampling"Correcting for sampling from the wrong distribution"Reweight returns by π(a|s)/μ(a|s) products to estimate V^π from μ data.
On-policy"Learn from my own data"Target policy = behavior policy. Vanilla MC, PPO, SARSA.
Off-policy"Learn from someone else's data"Target policy ≠ behavior policy. Importance-sampled MC, Q-learning, DQN.

Further Reading

Code

Ships With