Epsilon-Greedy Action Distribution
Problem Statement
Given action-value estimates for one state, compute the probability distribution that an epsilon-greedy policy induces over the actions. Do not sample — return the exact probabilities.
Background
Epsilon-greedy is the standard answer to the exploration/exploitation dilemma: with probability 1 - epsilon take the action that currently looks best, and with probability epsilon pick uniformly at random among all actions (the greedy action included). So for a state with n actions:
The detail that trips people up is ties. If k actions share the maximum value, the greedy mass 1 - epsilon is split evenly among all k of them, so each tied action gets (1 - epsilon)/k + epsilon/n. Handing the whole greedy mass to argmax (which returns only the first index) silently biases the policy — and later, when you write Expected SARSA, that same distribution appears inside the update target, so the bug becomes a wrong learning signal rather than just an odd action choice.
Your Task
Implement:
def epsilon_greedy_probs(q, epsilon):
...
- q — a list of floats, the action values Q(s, a) for the current state.
- epsilon — a float in [0.0, 1.0].
Return a list of floats of the same length as q, summing to 1.
Input / Output Format
Input is a list of floats and a float. Output is a list of floats; the grader rounds each entry to 4 decimals.
Sample
print([round(p, 4) for p in epsilon_greedy_probs([1.0, 5.0, 3.0], 0.3)])
Output:
[0.1, 0.8, 0.1]
Every action gets 0.3/3 = 0.1, and the greedy action (index 1) additionally gets 1 - 0.3 = 0.7.
Example
epsilon_greedy_probs([1.0, 5.0, 3.0], 0.3)
[0.1, 0.8, 0.1]
Uniform exploration gives every action epsilon/n = 0.1. Action 1 is the unique greedy action, so it additionally receives 1 - epsilon = 0.7, giving 0.8.
Constraints
1 <= len(q) <= 1000.0 <= epsilon <= 1.0- Ties for the maximum value must split the greedy probability
1 - epsilonevenly among all tied actions. - The returned probabilities must sum to 1 (up to floating point error).