CSE-41XX
CS-4101 AI

Lecture 06.3: Monte Carlo Tree Search (MCTS)

Scaling adversarial search to massive state spaces using randomness and the UCB1 algorithm in Monte Carlo Tree Search.

While Alpha-Beta pruning is highly effective for games like Chess, it still relies on exploring an exponentially growing tree. For incredibly complex games like Go, brute-force search—even with pruning—is computationally infeasible.

Monte Carlo Tree Search (MCTS) is a best-first search algorithm that uses random simulations to make decisions in massive state spaces. It prioritizes nodes that are more likely to lead to an optimal solution, drastically reducing unnecessary exploration without needing complex domain-specific heuristic knowledge.

The Four Steps of MCTS

MCTS figures out the best move by repeating a four-step process until computation time runs out. It learns the policy of the game iteratively.

1. Selection

Starting at the root, the algorithm traverses down the tree by selecting child nodes that maximize a specific policy formula (usually UCB1). It continues until it reaches a leaf node (a node that hasn't been fully expanded yet).

2. Expansion

If the selected leaf node does not represent a terminal state (game over), the algorithm expands the tree by adding one (or more) valid child nodes corresponding to available actions.

3. Simulation (Rollout)

From the newly expanded node, the algorithm plays out a completely random game (a "rollout") all the way to a terminal state to evaluate the outcome.

4. Backpropagation

The result of the random simulation (e.g., Win = 1, Loss = 0) is backpropagated up the exact path taken during Selection. Every node on that path updates its statistics:

  • tit_i: Total value/reward of the node increases.
  • nin_i: Number of visits to the node increases by 1.

The UCB1 Formula: Balancing Exploration and Exploitation

During the Selection phase, MCTS must decide which node to traverse. It uses the Upper Confidence Bound applied to Trees (UCB1) formula to strike a balance between exploiting known winning paths and exploring unvisited nodes:

UCB1(Si)=tini+Cln(N)ni\text{UCB1}(S_i) = \frac{t_i}{n_i} + C \sqrt{\frac{\ln(N)}{n_i}}

Where:

  • tit_i: Total reward from child node SiS_i.
  • nin_i: Number of times child node SiS_i has been visited.
  • NN: Total number of visits to the parent node.
  • CC: Exploration constant (frequently set to 2\sqrt{2}).

Breaking Down the Formula

  1. Exploitation Term: tini\frac{t_i}{n_i}
    This represents the average reward of choosing node SiS_i. It guides the algorithm to prefer actions that have performed well in past simulations.

  2. Exploration Term: Cln(N)niC \sqrt{\frac{\ln(N)}{n_i}}
    This acts as an uncertainty bonus for less-visited nodes:

    • Because nin_i is in the denominator, nodes visited infrequently receive a large score boost, encouraging exploration.
    • Because ln(N)\ln(N) is in the numerator, the exploration pressure gradually grows as the parent node receives more visits.

[!NOTE] If a node has never been visited (ni=0n_i = 0), its UCB1 value is considered \infty, guaranteeing that MCTS evaluates unvisited children before exploiting existing high-performing branches.


Step-by-Step Example of MCTS

Let's walk through a concrete execution trace of MCTS, demonstrating how the tree expands and how UCB1 values are calculated.

Initial State

We start with a root node S0S_0 and two child nodes S1S_1 and S2S_2:

  • Root S0S_0: visited n0=2n_0 = 2 times, total reward t0=43t_0 = 43.
  • Child S1S_1: visited n1=1n_1 = 1 time, total reward t1=25t_1 = 25.
  • Child S2S_2: visited n2=1n_2 = 1 time, total reward t2=18t_2 = 18.

Step 1: Rollout 1 (Playout Outcome = 40)

1. Selection (at Root S0S_0)

To choose between S1S_1 and S2S_2, we calculate their UCB1 scores (using exploration constant C=2C = 2 and parent visits N=n0=2N = n_0 = 2):

  • UCB1(S1)=251+2ln(2)125+2(0.832)26.66\text{UCB1}(S_1) = \frac{25}{1} + 2\sqrt{\frac{\ln(2)}{1}} \approx 25 + 2(0.832) \approx 26.66
  • UCB1(S2)=181+2ln(2)118+2(0.832)19.66\text{UCB1}(S_2) = \frac{18}{1} + 2\sqrt{\frac{\ln(2)}{1}} \approx 18 + 2(0.832) \approx 19.66

Since UCB1(S1)>UCB1(S2)\text{UCB1}(S_1) > \text{UCB1}(S_2), we select and traverse to S1S_1.

2. Expansion (at S1S_1)

  • Because S1S_1 has been visited (n1=1>0n_1 = 1 > 0) and is a leaf, we expand it.
  • We expand S1S_1 by adding three children: S3S_3 (left), S4S_4 (middle), and S5S_5 (right). All are initialized to ti=0,ni=0t_i = 0, n_i = 0.

3. Tie-Breaking

  • Since all three children have ni=0n_i = 0, their UCB1 scores are infinite.
  • By tie-breaking rule (prefer rightmost node), we select S5S_5.

4. Rollout & Backpropagation

  • A random playout from S5S_5 yields outcome 40.
  • We backpropagate the reward of 40 up the path S5S1S0S_5 \rightarrow S_1 \rightarrow S_0:
    • t540,n51t_5 \leftarrow 40, n_5 \leftarrow 1
    • t125+40=65,n12t_1 \leftarrow 25 + 40 = 65, n_1 \leftarrow 2
    • t043+40=83,n03t_0 \leftarrow 43 + 40 = 83, n_0 \leftarrow 3

Step 2: Rollout 2 (Playout Outcome = 20)

1. Selection (at Root S0S_0)

We evaluate UCB1 with parent visits N=n0=3N = n_0 = 3:

  • UCB1(S1)=652+2ln(3)232.5+2(0.741)33.98\text{UCB1}(S_1) = \frac{65}{2} + 2\sqrt{\frac{\ln(3)}{2}} \approx 32.5 + 2(0.741) \approx 33.98
  • UCB1(S2)=181+2ln(3)118+2(1.048)20.10\text{UCB1}(S_2) = \frac{18}{1} + 2\sqrt{\frac{\ln(3)}{1}} \approx 18 + 2(1.048) \approx 20.10

Since UCB1(S1)>UCB1(S2)\text{UCB1}(S_1) > \text{UCB1}(S_2), we traverse to S1S_1.

2. Selection (at S1S_1)

For S1S_1's children (N=n1=2N = n_1 = 2):

  • UCB1(S3)=\text{UCB1}(S_3) = \infty (n3=0n_3 = 0)
  • UCB1(S4)=\text{UCB1}(S_4) = \infty (n4=0n_4 = 0)
  • UCB1(S5)=401+2ln(2)140+2(0.832)41.66\text{UCB1}(S_5) = \frac{40}{1} + 2\sqrt{\frac{\ln(2)}{1}} \approx 40 + 2(0.832) \approx 41.66

Breaking the tie between S3S_3 and S4S_4 by preferring the right node selects S4S_4.

3. Rollout & Backpropagation

  • A random playout from S4S_4 yields outcome 20.
  • Backpropagating 20 up S4S1S0S_4 \rightarrow S_1 \rightarrow S_0:
    • t420,n41t_4 \leftarrow 20, n_4 \leftarrow 1
    • t165+20=85,n13t_1 \leftarrow 65 + 20 = 85, n_1 \leftarrow 3
    • t083+20=103,n04t_0 \leftarrow 83 + 20 = 103, n_0 \leftarrow 4

On this page