MediumReinforcement Learning

ε-Greedy Action Selection

Reinforcement Learning

Medium

Problem

Select an action with an epsilon-greedy policy. Draw one random value u from a generator initialized with seed:

a=\begin{cases}\text{uniform random action},&u<\varepsilon\\\arg\max_j q_j,&u\ge\varepsilon\end{cases}

Here, \varepsilon is the exploration probability and q_j is the value of action j. NumPy argmax resolves greedy ties by choosing the first maximum. Return the selected action index as a Python integer.

Theory

Epsilon-greedy is an action selection strategy that balances exploration and exploitation in reinforcement learning. It selects the best-known action most of the time, but occasionally takes a random action to discover potentially better options.

The parameter \epsilon controls the exploration rate.


The Exploration-Exploitation Dilemma

In reinforcement learning, an agent faces a fundamental tradeoff:

Exploitation: Choose actions that have yielded high rewards in the past. This maximizes short-term reward based on current knowledge.

Exploration: Choose actions that have not been tried much. This gathers information that might lead to higher long-term rewards.

Pure exploitation may miss better actions. Pure exploration wastes time on bad actions. Good strategies balance both.


The Epsilon-Greedy Policy

With probability 1 - \epsilon: Choose the greedy action (highest estimated value)

With probability \epsilon: Choose a random action uniformly

Mathematically:

\pi(a|s) = \begin{cases} 1 - \epsilon + \frac{\epsilon}{|A|} & \text{if } a = \arg\max_{a'} Q(s, a') \\ \frac{\epsilon}{|A|} & \text{otherwise} \end{cases}

where |A| is the number of available actions.


Understanding the Probabilities

For a state with 4 possible actions and \epsilon = 0.1:

Greedy action probability:

P(a^*) = 1 - \epsilon + \frac{\epsilon}{|A|} = 1 - 0.1 + \frac{0.1}{4} = 0.9 + 0.025 = 0.925

Non-greedy action probability (each):

P(a \neq a^*) = \frac{\epsilon}{|A|} = \frac{0.1}{4} = 0.025

Verification:

0.925 + 3 \times 0.025 = 0.925 + 0.075 = 1.0 \checkmark


Algorithm

Input: Q-values Q(s, a), exploration rate \epsilon, current state s

Output: Action a

  1. Generate random number r \sim \text{Uniform}(0, 1)

  2. If r < \epsilon:

    • Return random action from available actions
  3. Else:

    • Return \arg\max_a Q(s, a)

Worked Example

Setup:

Greedy action: B (highest Q-value of 3.0)

Action probabilities:

If random number r = 0.15:

Since 0.15 < 0.2 (epsilon), explore: pick random action

If random number r = 0.75:

Since 0.75 \geq 0.2, exploit: pick action B


Choosing Epsilon

High \epsilon (e.g., 0.5):

Low \epsilon (e.g., 0.01):

Typical values: \epsilon \in [0.01, 0.3]


Epsilon Decay

A common strategy is to start with high exploration and gradually reduce it:

Linear decay:

\epsilon_t = \max(\epsilon_{min}, \epsilon_0 - \text{decay\_rate} \times t)

Exponential decay:

\epsilon_t = \max(\epsilon_{min}, \epsilon_0 \times \text{decay}^t)

Inverse decay:

\epsilon_t = \frac{1}{1 + \text{decay\_rate} \times t}

This allows broad exploration initially, then fine-tuning of the policy.


Epsilon Decay Example

Setup:

After 100 episodes:

\epsilon_{100} = \max(0.01, 1.0 \times 0.995^{100}) = \max(0.01, 0.606) = 0.606

After 500 episodes:

\epsilon_{500} = \max(0.01, 1.0 \times 0.995^{500}) = \max(0.01, 0.082) = 0.082

After 1000 episodes:

\epsilon_{1000} = \max(0.01, 1.0 \times 0.995^{1000}) = \max(0.01, 0.0067) = 0.01


Handling Ties in Greedy Selection

When multiple actions have the same maximum Q-value:

Option 1: Random selection among tied actions

Option 2: Fixed selection (e.g., first action)

Option 3: Ordered preference


Epsilon-Greedy in Q-Learning

Q-learning uses epsilon-greedy for action selection during learning:

While learning:

  1. Observe state s
  2. Select action a using epsilon-greedy from Q(s, \cdot)
  3. Execute a, observe reward r and next state s'
  4. Update: Q(s,a) \leftarrow Q(s,a) + \alpha[r + \gamma \max_{a'} Q(s',a') - Q(s,a)]
  5. s \leftarrow s'

The epsilon-greedy exploration ensures all state-action pairs are visited.


Epsilon-Greedy in SARSA

SARSA also uses epsilon-greedy, but for both selection and update:

  1. Observe state s
  2. Select action a using epsilon-greedy
  3. Execute a, observe reward r and next state s'
  4. Select next action a' using epsilon-greedy from Q(s', \cdot)
  5. Update: Q(s,a) \leftarrow Q(s,a) + \alpha[r + \gamma Q(s',a') - Q(s,a)]
  6. s \leftarrow s', a \leftarrow a'

SARSA learns the value of the epsilon-greedy policy itself.


Properties of Epsilon-Greedy

1. GLIE (Greedy in the Limit with Infinite Exploration):

With decaying \epsilon where \sum_t \epsilon_t = \infty and \lim_{t \to \infty} \epsilon_t = 0, epsilon-greedy satisfies GLIE conditions for convergence.

2. All actions have non-zero probability:

Every action can be selected, ensuring exploration of the entire state-action space.

3. Simple and effective:

Easy to implement and works well in practice.


Comparison with Other Exploration Strategies

Greedy (\epsilon = 0):

Random (\epsilon = 1):

Softmax (Boltzmann):

\pi(a|s) = \frac{e^{Q(s,a)/\tau}}{\sum_{a'} e^{Q(s,a')/\tau}}


Softmax vs Epsilon-Greedy

Epsilon-greedy:

Softmax:

Example: Q-values [10.0, 9.9, 1.0]

Epsilon-greedy: Actions 2 and 3 equally likely when exploring

Softmax: Action 2 much more likely than action 3


Upper Confidence Bound (UCB)

Another exploration strategy that considers uncertainty:

a_t = \arg\max_a \left[ Q(a) + c\sqrt{\frac{\ln t}{N(a)}} \right]

where N(a) is the count of times action a was selected.

UCB favors actions with high Q-values OR high uncertainty (low visit count).


Epsilon-Greedy in Deep RL

In deep reinforcement learning (e.g., DQN):


Implementing Epsilon-Greedy Correctly

Common mistakes:

  1. Forgetting to decay epsilon
  2. Not handling action ties
  3. Using epsilon for evaluation (should use greedy)
  4. Decaying too fast (insufficient exploration)

Best practices:

  1. Start with high epsilon (0.5 to 1.0)
  2. Decay gradually based on environment complexity
  3. Keep minimum epsilon > 0 for robustness
  4. Use greedy policy for final evaluation

Evaluation vs Training

During training:

During evaluation:

This separation is important for fair evaluation of learned policies.

Examples

Example 1

Input
q_values = [1, 2, 0.5], epsilon = 0, seed = 0
Output
1
Explanation
With zero exploration probability, the action with the largest value is selected.

Example 2

Input
q_values = [1, 2, 0.5], epsilon = 1, seed = 42
Output
1

Hints

  1. Create the generator with rng = np.random.default_rng(seed).
  2. Use rng.integers(values.size) for exploration and np.argmax(values) otherwise.

Requirements

Constraints

Starter Code

import numpy as np

def epsilon_greedy(q_values: list, epsilon: float, seed: int = 0) -> int:
    """
    Returns the action index as an integer.
    """
    # Write code here
    pass

Test Cases

CaseMatches
Greedy (ε=0)public
Random (ε=1)public