Optimistic Initial Values
Start every action value absurdly high, and a purely greedy agent will still tour each option once, because every real reward feels like a letdown that sinks the tried below the untried.
Why Does This Exist?
A purely greedy agent picks whatever currently ranks highest, and with all values starting at zero it locks on fast. The first arm to pay anything positive jumps above the untried zeros, so the agent replays it forever and never learns the neighbor pays four times more. That lock-in is the whole exploration problem in miniature.
Random exploration fixes it with a permanent tax: epsilon-greedy keeps pulling losing arms at rate for the rest of time. Optimistic initialization buys the early exploration without the tax. Set every starting estimate above anything the environment can pay, , and each pull disappoints by construction. The tried arm sinks below the pristine untried ones, so pure greed tours the whole set before repeating anything.
This page is the bandit-scale version. For the problem class it lives in, see multi-armed bandits. For the randomized alternative, see epsilon-greedy. For optimism that never burns out, see upper confidence bound.
The one idea you need first
A constant step-size update moves the estimate a fraction toward each observed reward. Unroll it and the starting value decays geometrically: after pulls of one arm its weight is , so the initial bias washes out and settles near the arm's true mean. Optimism is a prior with an expiry date, which is both its charm and its limit.
Think of It Like This
The critic who assumes five stars everywhere
A food critic moves to a new city convinced every restaurant is a five-star masterpiece until proven otherwise. Monday she tries place A expecting 5.0 and gets a 3.0 meal. Disappointed, she marks A down to 4.2. Tuesday she asks where to eat: A sits at 4.2 while B, C, and D still hold their untouched 5.0, so pure greed walks past A into B. B is a 1.0 dive, which craters its score. Wednesday and Thursday go to C and D for the same reason.
No coin flips, no dithering. The optimism guarantees each early meal underwhelms, and the disappointment steering tours every kitchen in town before anything gets a second visit. The best kitchen wins in the end because it disappoints the least.
Where it stops: kitchens change chefs. A year later B hires a star and becomes the best table in town, but the critic's score for B is parked near 1.0 and she never walks in. Optimism burns once; it does not relight when the world shifts underneath it.
How It Actually Works
With for every arm and greedy selection , the first prediction error on any arm is negative by construction: . The update pushes the pulled arm down while untried arms sit untouched at , so the next greedy pick must be an untried arm. After arms each get pulled once, the ranking reflects real evidence: the arm that disappointed least ranks highest.
The bias decays as with pulls, so estimates converge to true means and the touring stops on its own. No schedule, no coin, no tuning beyond choosing somewhat above the best plausible reward.
Worked example
Three arms with true means 0.80, 0.40, 0.10. Start all at , step size , ties broken to the lowest index:
- Step 1: all tied at 5.0, pick arm 1, reward 0.80. . Table: .
- Step 2: arms 2 and 3 tied above arm 1, pick arm 2, reward 0.40. . Table: .
- Step 3: arm 3 alone on top, pick arm 3, reward 0.10. . Table: .
- Step 4: arm 1 leads because it disappointed least. Reward 0.80 again: . Table: , so step 5 turns back to arm 2.
Every arm got sampled once with zero randomness, and the best arm earned its lead honestly.
Code
This replay uses the exact fixture above and prints the picks plus the table:
def greedy_run(true_means: list[float], q0: float, alpha: float, steps: int) -> tuple[list[int], list[float]]: """Pure greedy bandit with constant step size; ties go to lowest index.""" q = [q0] * len(true_means) picks: list[int] = [] for _ in range(steps): best = 0 for arm in range(1, len(q)): if q[arm] > q[best]: best = arm picks.append(best) q[best] = q[best] + alpha * (true_means[best] - q[best]) return picks, [round(v, 3) for v in q]
print(greedy_run([0.8, 0.4, 0.1], 5.0, 0.1, 4)) # -> ([0, 1, 2, 0], [4.202, 4.54, 4.51])The picks tour all three arms before repeating, and the final table matches the hand computation.
Watch Out For
Optimism burns out in shifting environments
The touring works exactly once. After decays, every arm's estimate sits near its sampled mean and greed stops exploring. If payouts drift later, say a weak arm becomes the best one in week two, the agent never notices: that arm's score is parked low and nothing pulls it back up for a retest.
Never use optimism as the only exploration in a nonstationary problem. Pair it with a persistent floor like epsilon-greedy, a sliding window, or a UCB bonus that keeps questioning old scores.
A cartoonish Q0 wastes hundreds of pulls
If towers over reality, say 1000 against rewards near 1, the decay takes forever and the agent keeps sampling plainly bad arms because their scores are still inflated. The touring degenerates into a long parade of known losers.
Set modestly above the plausible ceiling, around 1.5 to 2 times the best reward you expect. The disappointment steering only needs untried arms to outrank tried ones, not to orbit the moon.
The Quick Version
- Optimistic initialization sets every above any achievable reward, so each pull disappoints and sinks below the untried arms.
- A purely greedy policy then tours every arm once with zero randomness; here 5.0 drops to 4.58, 4.54, and 4.51 across three picks.
- The starting bias decays as , so estimates converge to true means and the touring ends by itself.
- Optimism fires once only, so shifting environments need a persistent explorer alongside it.
- Keep modestly above the reward ceiling; a giant wastes pulls on obvious losers.