为什么我的值字典需要浅拷贝才能正确更新?

我在使用Python 2.7.11开发一个Agent类,该类使用马尔可夫决策过程(MDP)在GridWorld中搜索最优策略π。我正在实现一个基本的价值迭代,用于对所有GridWorld状态进行100次迭代,使用以下贝尔曼方程:

enter image description here

  • T(s,a,s’)是从当前状态s通过采取行动a成功过渡到后续状态s’的概率函数。
  • R(s,a,s’)是从s过渡到s’的奖励。
  • γ(gamma)是折扣因子,其中0 ≤ γ ≤ 1
  • Vk(s’)是在达到s’后重复计算的递归调用。
  • Vk+1(s)表示经过足够的k次迭代后,Vk迭代值将收敛并与Vk+1等价。

这个方程是从取Q值函数的最大值中得出的,这是我在程序中使用的:

enter image description here

在构建我的Agent时,会传入一个MDP,这是一个包含以下方法的抽象类:

# 返回GridWorld中的所有状态def getStates()# 返回给定当前状态下代理可以采取的所有合法行动def getPossibleActions(state)# 返回从当前状态通过给定行动可以过渡到的所有可能的后续状态,以及采取该行动达到每个状态的概率def getTransitionStatesAndProbs(state, action)# 返回从当前状态到后续状态的奖励def getReward(state, action, nextState)

我的Agent还被传入一个折扣因子和迭代次数。我还使用了一个字典来跟踪我的值。以下是我的代码:

class IterationAgent:    def __init__(self, mdp, discount = 0.9, iterations = 100):        self.mdp = mdp        self.discount = discount        self.iterations = iterations        self.values = util.Counter() # Counter是一个默认值为0的字典        for transition in range(0, self.iterations, 1):            states = self.mdp.getStates()            valuesCopy = self.values.copy()            for state in states:                legalMoves = self.mdp.getPossibleActions(state)                convergedValue = 0                for move in legalMoves:                    value = self.computeQValueFromValues(state, move)                    if convergedValue <= value or convergedValue == 0:                        convergedValue = value                valuesCopy.update({state: convergedValue})            self.values = valuesCopy    def computeQValueFromValues(self, state, action):        successors = self.mdp.getTransitionStatesAndProbs(state, action)        reward = self.mdp.getReward(state, action, successors)        qValue = 0        for successor, probability in successors:            # Q值方程:Q*(a,s) = T(s,a,s')[R(s,a,s') + gamma(V*(s'))]            qValue += probability * (reward + (self.discount * self.values[successor]))        return qValue

这个实现是正确的,但我不知道为什么需要valuesCopy来成功更新我的self.values字典。我尝试了以下方法来省略拷贝,但它不起作用,因为它返回了略有错误的值:

for i in range(0, self.iterations, 1):    states = self.mdp.getStates()    for state in states:        legalMoves = self.mdp.getPossibleActions(state)        convergedValue = 0        for move in legalMoves:            value = self.computeQValueFromValues(state, move)            if convergedValue <= value or convergedValue == 0:                convergedValue = value        self.values.update({state: convergedValue})

我的问题是,为什么在每次迭代中valuesCopy = self.values.copy()都会对字典进行拷贝的情况下,还需要包含self.values字典的拷贝来正确更新我的值?难道在原始字典中更新值不会产生相同的更新结果吗?


回答:

是否使用拷贝在算法上是有区别的:

# 你在这里更新你的拷贝,所以原始的将保持不变,这与没有拷贝的情况不同valuesCopy.update({state: convergedValue})# 如果你有拷贝,你将在这里使用存储在self.value中的旧值,而不是更新后的值qValue += probability * (reward + (self.discount * self.values[successor]))

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注