-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathrtdp.py
More file actions
148 lines (126 loc) · 4.12 KB
/
rtdp.py
File metadata and controls
148 lines (126 loc) · 4.12 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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
from collections import defaultdict
import numpy as np
from gym.envs.toy_text.frozen_lake import FrozenLakeEnv
MAP_20x20 = [
'SFFFFFFFHFFFFFFHFHFF',
'FFFFFFFFFFFHFFFFFHFF',
'FFHFFHFHFFFFFFHFFFFH',
'FFHFFHFFFFFFFFHFFHFF',
'FFFHFFFFFFFFFFFFFFHF',
'FFFFHFFFFFHFFFFHFFFH',
'FFFFFFFHFHFFHFFFFFFF',
'HFHFFFFFFFFFFHFFFFFF',
'HFFFFFFFFHHFHFFHHFFF',
'FFFFFFFFFHFHFFFFFFFF',
'FFFFFFFFFFFFHFFFFFFH',
'FFFFFFFHFFFFFFFFFFFH',
'FFFFFFHFFFFFFFFFHHFF',
'HFFHFFFHHFHFFFHHFFFF',
'FFFFFFFFFHFHFFHHHFFF',
'HFFFFFHFFFFFHFHFFFFF',
'HFFFFFFFFFFFFFFFHFFH',
'FHFFFFFFFHFFFFFFFFFF',
'FFHFFFFFFFHFFFFHFHFF',
'FFHFHFFFFFFFHHFFFFFG'
]
class RTDP:
def __init__(self, env):
self.env = env
self.iterations = 17000
self.gamma = 1.
self.goal_cost = -1.
self.hole_cost = .1
self.default_cost = .1
self.actions = [0, 1, 2, 3]
# FrozenLakeEnv gives us a transition matrix, the states and actions.
# But no costs. So let's set something up ourselves.
self._init_cost()
self.calc_policy()
def calc_policy(self):
# RTDP
V = defaultdict(lambda: 0.)
for i in range(self.iterations):
if i % 500 == 0:
print(i)
obs = self.env.reset()
while True:
action = np.argmin(
[
self.cost[obs][a] + self.gamma * sum(
item[0] * V[item[1]]
for item in self.env.P[obs][a]
)
for a in self.actions
]
)
V[obs] = self.cost[obs][action] + self.gamma * sum(
item[0] * V[item[1]]
for item in self.env.P[obs][action]
)
obs, reward, done, _ = self.env.step(action)
if done:
cost_ = -1
if reward == 0.0:
cost_ = 1
V[obs] = cost_ + self.gamma * sum(
item[0] * V[item[1]]
for item in self.env.P[obs][action]
)
break
print(' ')
print(V)
self.V = V
def _init_cost(self):
# TODO Code below kinda ugly.
cost = defaultdict(dict)
for state in range(self.env.nS):
for action in self.actions:
# why 1? its the action itself. Others are slippery outcomes.
if len(self.env.P[state][action]) == 1:
if self.env.P[state][action][0][2] == 1.0:
cost[state][action] = self.goal_cost
else:
cost[state][action] = self.hole_cost
continue
done = self.env.P[state][action][1][3]
if done and self.env.P[state][action][1][2] == 0.0:
cost[state][action] = self.hole_cost
else:
cost[state][action] = self.default_cost
if done and self.env.P[state][action][1][2] == 1.0:
cost[state][action] = self.goal_cost
self.cost = cost
def policy(self, state):
return np.argmin(
[
self.cost[state][a] + self.gamma * sum(
item[0] * self.V[item[1]]
for item in self.env.P[state][a]
)
for a in self.actions
]
)
def evaluate(rtdp, env):
rewards = 0.
state = env.reset()
done = False
steps = 0
while not done:
state, reward, done, _ = env.step(rtdp.policy(state))
rewards += reward
steps += 1
if steps > 1e4:
break
return rewards
def run():
env = FrozenLakeEnv(desc=MAP_20x20)
rtdp = RTDP(env)
tot_rewards = 0.
eval_iter = int(1e4)
for i in range(eval_iter):
if i % 100 == 0:
print(i)
tot_rewards += evaluate(rtdp, env)
print(tot_rewards / eval_iter)
if __name__ == '__main__':
run()