PUCT: Predictor + Upper Confidence bounds for Trees
PUCT
Definition
PUCT stands for Predictor + Upper Confidence bounds applied to Trees. It is a move-selection rule used inside Monte Carlo Tree Search (MCTS) to decide which move (child node) to explore next. PUCT blends two signals:
- A learned prediction (the “Predictor”): a policy prior P(s, a) from a neural network that estimates which moves are promising in position s.
- An exploration bonus (the “Upper Confidence” part): a term that favors less-visited moves to ensure the search does not miss hidden resources.
In practical terms, each candidate move a from a position s gets a score that combines: Q(s, a) — the current value estimate of that move based on previous simulations, and U(s, a) — an exploration term typically proportional to P(s, a) × sqrt(N_parent) / (1 + N(s, a)), scaled by a constant c_puct. The search selects the move with the highest Q + U to traverse next.
How it is used in chess
Neural-network engines such as Leela Chess Zero (Lc0)—inspired by DeepMind’s AlphaZero—use PUCT in their MCTS. The workflow is:
- Selection: Starting from the root (the current position), repeatedly pick the child with the highest PUCT score Q + U until reaching a leaf or an unexpanded node.
- Expansion and evaluation: Query a neural network to obtain a policy prior over legal moves P(s, ·) and a value estimate V(s).
- Backup: Propagate the value estimate up the tree, updating Q and visit counts N.
- Move choice: After many simulations, play the move with the most visits at the root (often called the “visits policy”).
PUCT’s policy prior steers early search toward moves the network already “believes in,” while the confidence bonus ensures underexplored options still receive attention. This balance is critical for finding creative resources, sacrifices, and long-term plans that pure evaluation might overlook early in the search.
Strategic and historical significance
PUCT was a key ingredient in the breakthroughs of AlphaGo (2016), AlphaGo Zero (2017), and AlphaZero (2017), which achieved superhuman play without human-crafted evaluation functions or opening books. In chess, AlphaZero vs. Stockfish (2017) showcased dynamic, sacrifice-friendly play arising from PUCT-guided MCTS with neural networks. The success of PUCT-based engines motivated the open-source Lc0 project and influenced top-level engine competitions such as TCEC (e.g., Lc0’s Superfinal victory in 2019).
PUCT also changed how engines “think”: rather than brute-forcing tactical trees with handcrafted heuristics (alpha–beta search as in Stockfish), PUCT leverages learned priors to search efficiently and often produces human-like, strategic moves at modest depth.
Comparison to UCT
UCT (Upper Confidence bounds applied to Trees) is a classic MCTS selection formula that balances exploitation and exploration using statistics alone. PUCT augments this with a learned policy prior:
- UCT: The exploration term typically grows like sqrt(ln N_parent / N_child), independent of any learned guidance.
- PUCT: Replaces the log term with sqrt(N_parent) and weights exploration by the neural net’s policy prior P(s, a), strongly guiding search toward promising moves while still exploring alternatives.
Because of the policy prior, PUCT tends to be more sample-efficient when good learned guidance is available.
Worked example: root selection from the starting position
Imagine an engine at the initial position with these network policy priors (for illustration):
- P(1. e4) = 0.31
- P(1. d4) = 0.30
- P(1. Nf3) = 0.18
- P(1. c4) = 0.12
- All others share 0.09
After 480 simulations, suppose we have:
- 1. e4: N = 250, Q = +0.10
- 1. d4: N = 140, Q = +0.12
- 1. Nf3: N = 60, Q = +0.08
- 1. c4: N = 30, Q = +0.09
With c_puct = 1.5, the exploration term U roughly scales like P × sqrt(N_parent) / (1 + N_child). That means the underexplored move 1. c4 (N = 30) receives a larger U than 1. e4 (N = 250), despite a similar Q. The combined PUCT scores might yield:
- 1. e4: Q + U ≈ 0.141
- 1. d4: Q + U ≈ 0.190
- 1. Nf3: Q + U ≈ 0.177
- 1. c4: Q + U ≈ 0.217 (highest)
So the search would likely explore 1. c4 next—even though it currently has fewer visits—because PUCT encourages checking promising but underexplored moves. After enough simulations, the root move finally chosen is usually the one with the most visits. For instance:
Engine behavior and tuning
- c_puct: The exploration constant. Higher values = broader exploration; lower values = more “greedy” exploitation of current Q estimates. Many engines expose this as a user-tunable option.
- FPU (First Play Urgency): The initial Q assigned to unexplored moves. Adjusting FPU biases how optimistic the engine is about new branches, interacting with PUCT.
- Dirichlet noise at the root: Added to the policy prior P(s, ·) during self-play to force variety and prevent collapse into a narrow repertoire.
- Temperature: Controls how deterministically the engine chooses among moves by visit count; analysis mode commonly uses low or zero temperature.
- Dynamic cpuct schedules: Some implementations vary cpuct with total visits to balance early exploration and later exploitation.
Examples and references in practice
- AlphaZero vs. Stockfish, 2017: AlphaZero used PUCT-driven MCTS with learned priors and values to produce strategic, often sacrificial play.
- Lc0 in TCEC Superfinals (e.g., 2019): Lc0’s PUCT-based search found long-term compensation and novel plans that traditional alpha–beta sometimes undervalued initially.
Interesting facts
- PUCT lets the engine pursue human-like plans early because the policy prior provides directional “intuition” before deep tactical verification.
- Raising c_puct can make the engine’s opening play more diverse; lowering it narrows the repertoire and can look more “pragmatic.”
- Unlike alpha–beta, MCTS with PUCT does not require handcrafted pruning rules; the learned policy naturally prunes search by allocating fewer visits to low-prior moves.
Related terms
See also: MCTS, UCT, Policy network, Value network, Dirichlet noise, Leela Chess Zero, AlphaZero.