我正在为(PO)MDP 编写一个工具箱,并且看到出现了一个不好的模式。尤其是在实施强化学习算法时,我倾向于重复自己。请参阅以下伪算法:
arguments: epsilon
v <- initial V values
c <- initial C values
while not good-enough
delta <- 0.0
if in-place
v_old <- copy(v)
else
v_old <- reference to v
for s in ss
a = some_value(s,old_v)
old_v <- v_old[s]
v[s] = c*a*v_old[s]
delta = max(delta,old_v-v[s])
if delta < epsilon
good-enough <- true
return v
现在看看这个几乎相同的算法:
arguments: epsilon,gamma
v <- initial V values
c <- initial C values
while not good-enough
delta <- 0.0
if in-place
v_old <- copy(v)
else
v_old <- reference to v
for s in ss
a,o = get_a_and_o(s)
old_v <- v_old[s]
v[s] = c*v_old[s]*exp(o-a)
delta = max(delta,old_v-v[s])
if delta < epsilon(/1-gamma)
good-enough <- true
return v
这些算法之间有一些简单的区别,但我重复了很多次。现在我的问题是:你如何抽象出这两个示例算法之间的共同部分(适用于实际算法)?
我看过一种方法(在 python 中),你给算法一个 pre、一个 post 和一个循环函数,它们分别在每次迭代之前、之后和为每个迭代调用,并传递一个算法状态字典来保存变量。但是这种方法似乎不是很好。有什么建议么?