Monte Carlo Control
Monte Carlo control finds good actions without any model by finishing full episodes, averaging the returns each action earned, and switching to the winners.
Why Does This Exist?
Dynamic programming finds optimal policies only when the transition probabilities are known. In robotics, games, and trading systems they are not. Worse, improving a policy from state values alone still needs a one step lookahead through those unknown probabilities, so cannot pick actions by itself.
Monte Carlo control fixes both gaps at once. It evaluates action values directly from finished episodes, then makes the policy greedy in , which needs no model at all:
Unlike temporal difference learning, nothing here bootstraps from a guessed successor value. Every update uses a true sampled return , so there is no bootstrapping bias to diverge. The price is patience: learning waits for episodes to terminate. This page covers the control loop. Its building blocks are Monte Carlo action values and exploring starts.
The one idea you need first
Generalized policy iteration alternates evaluation with improvement: estimate how good the current policy is, then act greedily in those estimates. See generalized policy iteration for the full loop. Monte Carlo control is that loop with complete episode returns as the evaluator.
Think of It Like This
A golfer who only changes strategy at the clubhouse
A golfer tests a new swing by playing full 18 hole rounds with it. Mid fairway guesses do not count. Back at the clubhouse the scorecard shows the true total, and the golfer compares which club choices from which lies produced the lowest totals, then commits to the winners for the next round.
Two rounds can flip a decision: a safe layup strategy totals 4.6 over par while one bold drive totals 8.0 under the same scoring, so the bold drive becomes the new plan. Where it stops: golf lies are nearly repeatable, while stochastic environments need many rounds averaged before a total is trustworthy, plus deliberate experimentation so a mediocre first round does not lock in forever.
How It Actually Works
An episode under policy gives a discounted return per step:
Here is the reward after step , is the discount in , and is the true total from onward. First visit Monte Carlo keeps the from each pair's first appearance per episode and averages:
where counts visits. Improvement then sets to the action with the highest . By the policy improvement theorem this greedy step never hurts expected returns, so repeated evaluation plus greedification climbs toward the optimal policy. One guardrail is mandatory: every pair must keep being visited, through exploring starts or an epsilon greedy policy, or unvisited actions freeze at stale values.
Worked example
State offers and with . All values start at 0.
Episode 1 follows the safe route: then to termination. Working backward:
So and . The greedy policy at still picks safe, since risky sits at 0.
Episode 2 explores: straight to termination, giving and . Now beats , so switches from safe to risky on sampled evidence alone, with no transition model consulted.
Code
This snippet replays both episodes with first visit updates and prints the values and the policy after each one.
def backward_returns(rewards: list[float], gamma: float = 0.9) -> list[float]: g = 0.0 out = [] for r in reversed(rewards): g = r + gamma * g out.append(round(g, 2)) return list(reversed(out))
print(backward_returns([1.0, 4.0])) # -> [4.6, 4.0]print(backward_returns([8.0])) # -> [8.0]
q = {("s0", "safe"): 4.6, ("s0", "risky"): 8.0}print(max(["safe", "risky"], key=lambda a: q[("s0", a)])) # -> riskyThe first print shows for the safe route. The second shows for the risky episode. The greedy pick over the two values is risky, exactly the policy switch in the worked example.
Watch Out For
Episodes that never end stall all learning
Monte Carlo control updates only after termination, because is defined backward from the final step. In continuing tasks or loops that rarely terminate, transitions pile up in memory while the policy never changes.
Symptom: a growing trajectory buffer with zero updates and flat performance. Fix: cap episodes with an explicit horizon and reset, or switch to a bootstrapping method such as one step TD that updates every transition.
Greedy improvement locking onto a mediocre action
After one lucky episode a mediocre action can lead while better actions sit at 0, and a fully greedy policy then never samples the alternatives, freezing their values forever.
Symptom: fast early convergence to a policy that is clearly improvable yet never changes. Fix: keep exploration alive with exploring starts where simulators allow resets, or an epsilon greedy schedule that decays but never hits exactly zero during learning.
The Quick Version
- Monte Carlo control learns from finished episodes, so greedy action choice needs no transition model.
- Each update averages true sampled returns , which removes bootstrapping bias but forces waiting for termination.
- In the worked example, safe scores while risky scores , so the policy switches to risky.
- Evaluation plus greedification repeats as generalized policy iteration and climbs toward the optimal policy.
- Exploring starts or epsilon greedy exploration is mandatory, or unvisited actions never get corrected.