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.
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:
π(a∣s)={1−ε+nεa=argmaxa′Q(s,a′)$6pt]nεotherwise
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.
Implement:
def epsilon_greedy_probs(q, epsilon):
...
Return a list of floats of the same length as q, summing to 1.
Input is a list of floats and a float. Output is a list of floats; the grader rounds each entry to 4 decimals.
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.
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.
1 <= len(q) <= 1000.0 <= epsilon <= 1.01 - epsilon evenly among all tied actions.