-
Notifications
You must be signed in to change notification settings - Fork 25
Expand file tree
/
Copy pathqlearning.py
More file actions
95 lines (79 loc) · 2.77 KB
/
Copy pathqlearning.py
File metadata and controls
95 lines (79 loc) · 2.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
from collections import defaultdict
import random
import typing as t
import numpy as np
import gymnasium as gym
Action = int
State = int
Info = t.TypedDict("Info", {"prob": float, "action_mask": np.ndarray})
QValues = t.DefaultDict[int, t.DefaultDict[Action, float]]
class QLearningAgent:
def __init__(
self,
learning_rate: float,
epsilon: float,
gamma: float,
legal_actions: t.List[Action],
):
"""
Q-Learning Agent
You shoud not use directly self._qvalues, but instead of its getter/setter.
"""
self.legal_actions = legal_actions
self._qvalues: QValues = defaultdict(lambda: defaultdict(int))
self.learning_rate = learning_rate
self.epsilon = epsilon
self.gamma = gamma
def get_qvalue(self, state: State, action: Action) -> float:
"""
Returns Q(state,action)
"""
return self._qvalues[state][action]
def set_qvalue(self, state: State, action: Action, value: float):
"""
Sets the Qvalue for [state,action] to the given value
"""
self._qvalues[state][action] = value
def get_value(self, state: State) -> float:
"""
Compute your agent's estimate of V(s) using current q-values
V(s) = max_a Q(s, a) over possible actions.
"""
value = 0.0
# BEGIN SOLUTION
# END SOLUTION
return value
def update(
self, state: State, action: Action, reward: t.SupportsFloat, next_state: State
):
"""
You should do your Q-Value update here:
TD_target(s, a, r, s') = r + gamma * V(s')
TD_error(s, a, r, s') = TD_target(s, a, r, s') - Q_old(s, a)
Q_new(s, a) := Q_old(s, a) + learning_rate * TD_error(s, a, R(s, a), s')
"""
q_value = 0.0
# BEGIN SOLUTION
# END SOLUTION
self.set_qvalue(state, action, q_value)
def get_best_action(self, state: State) -> Action:
"""
Compute the best action to take in a state (using current q-values).
"""
possible_q_values = [
self.get_qvalue(state, action) for action in self.legal_actions
]
index = np.argmax(possible_q_values)
best_action = self.legal_actions[index]
return best_action
def get_action(self, state: State) -> Action:
"""
Compute the action to take in the current state, including exploration.
Note: To pick randomly from a list, use random.choice(list).
To pick True or False with a given probablity, generate uniform number in [0, 1]
and compare it with your probability
"""
action = self.legal_actions[0]
# BEGIN SOLUTION
# END SOLUTION
return action