我尝试用字典理解和for循环来实现一种算法,我相信这两种算法都可以达到相同的结果。
for i in range(num_iter):
new_state_values = {s: get_new_state_value(mdp, state_values, s, gamma) for s in mdp.get_all_states()}
for i in range(num_iter):
for s in mdp.get_all_states():
new_state_values[s] = get_new_state_value(mdp, state_values, s, gamma)
在我的算法运行时,这些实现了截然不同的结果。有人可以指出两个区别在哪里吗?
完整算法在下面
# parameters
gamma = 0.9 # discount for MDP
num_iter = 100 # maximum iterations, excluding initialization
min_difference = 0.001 # stop VI if new values are this close to old values (or closer)
# initialize V(s)
state_values = {s: 0 for s in mdp.get_all_states()}
for i in range(num_iter):
new_state_values = {s: get_new_state_value(mdp, state_values, s, gamma) for s in mdp.get_all_states()}
# Compute difference
diff = max(abs(new_state_values[s] - state_values[s]) for s in mdp.get_all_states())
state_values = new_state_values
if diff < min_difference:
print("Terminated")
break
“ for-loop”版本几乎不运行任何迭代,而字典理解则运行更多次迭代。
更新:以上代码可以正常工作并收敛(我想这是最Python的imo)。接受的答案可以很好地了解不同的方法。
答案 0 :(得分:3)
非综合版本会累积值,而不丢弃外部循环先前运行中的值。如果要使其等效,则需要更改:
for i in range(num_iter):
for s in mdp.get_all_states():
new_state_values[s] = get_new_state_value(mdp, state_values, s, gamma)
收件人:
for i in range(num_iter):
new_state_values = {} # NEW!!!
for s in mdp.get_all_states():
new_state_values[s] = get_new_state_value(mdp, state_values, s, gamma)
将new_state_values
重新初始化为干净的dict
。
在您的完整代码中,不理解的解决方案会将state_values
和new_state_values
都保留为 same dict
的别名(所以{{1} }会随着您的使用而发生变化),使问题更加严重; state_values
理解可以通过构建新的dict
来解决它,而无需在构建时修改dict
。