python中使用馬爾可夫決策過(guò)程(MDP)動(dòng)態(tài)編程來(lái)解決最短路徑強(qiáng)化學(xué)習(xí)問(wèn)題
原文鏈接:http://tecdat.cn/?p=11105
在強(qiáng)化學(xué)習(xí)中,我們有興趣確定一種最大化獲取獎(jiǎng)勵(lì)的策略。假設(shè)環(huán)境是馬爾可夫決策過(guò)程??(MDP)的理想模型? ,我們可以應(yīng)用動(dòng)態(tài)編程方法來(lái)解決強(qiáng)化學(xué)習(xí)問(wèn)題。
在這篇文章中,我介紹了可以在MDP上下文中使用的三種動(dòng)態(tài)編程算法。為了使這些概念更容易理解,我在網(wǎng)格世界的上下文中實(shí)現(xiàn)了算法,這是演示強(qiáng)化學(xué)習(xí)的流行示例。
在開始使用該應(yīng)用程序之前,我想快速提供網(wǎng)格世界上后續(xù)工作所需的理論背景。
MDP的關(guān)鍵強(qiáng)化學(xué)習(xí)術(shù)語(yǔ)
以下各節(jié)解釋了強(qiáng)化學(xué)習(xí)的關(guān)鍵術(shù)語(yǔ),即:
策略:??代理應(yīng)在哪種狀態(tài)下執(zhí)行哪些操作
狀態(tài)值函數(shù):??每個(gè)州關(guān)于未來(lái)獎(jiǎng)勵(lì)的期望值
行動(dòng)價(jià)值函數(shù):??在特定狀態(tài)下針對(duì)未來(lái)獎(jiǎng)勵(lì)執(zhí)行特定行動(dòng)的預(yù)期價(jià)值
過(guò)渡概率:??從一種狀態(tài)過(guò)渡到另一種狀態(tài)的概率
獎(jiǎng)勵(lì)功能:??代理在狀態(tài)之間轉(zhuǎn)換時(shí)獲得的獎(jiǎng)勵(lì)
?
狀態(tài)值函數(shù)
給定策略ππ,狀態(tài)值函數(shù)Vπ(s)Vπ(s)將每個(gè)狀態(tài)ss映射到代理在此狀態(tài)下可獲得的預(yù)期收益:
?

式中,stst表示時(shí)刻tt的狀態(tài)。參數(shù)γ∈[0,1]γ∈[0,1]稱為??折扣因子。它決定了未來(lái)獎(jiǎng)勵(lì)的影響。?
動(dòng)作值函數(shù)
給定策略ππ,動(dòng)作值函數(shù)Qπ(s,a)Qπ(s,a)確定在狀態(tài)ss中執(zhí)行動(dòng)作aa時(shí)的預(yù)期獎(jiǎng)勵(lì):
?
?

轉(zhuǎn)移概率
在狀態(tài)ss中執(zhí)行動(dòng)作aa可以將代理轉(zhuǎn)換為狀態(tài)s's'。通過(guò)Pass'Pss'a描述發(fā)生此過(guò)渡的可能性。
獎(jiǎng)勵(lì)函數(shù)
獎(jiǎng)勵(lì)函數(shù)Rass'Rss'a指定當(dāng)代理通過(guò)動(dòng)作aa從狀態(tài)ss過(guò)渡到狀態(tài)s's'時(shí)獲得的獎(jiǎng)勵(lì)。
Gridworld中的三種基本MDP算法的演示
在本文中,您將學(xué)習(xí)如何在網(wǎng)格世界中為MDP應(yīng)用三種算法:
策略評(píng)估:??給定策略ππ,與ππ相關(guān)的價(jià)值函數(shù)是什么?
策略迭代:??給定策略ππ,我們?nèi)绾握业阶罴巡呗驭?π??
值迭代:??如何從頭開始找到最佳策略π?π??
在gridworld中,代理的目標(biāo)是到達(dá)網(wǎng)格中的指定位置。該代理可以向北,向東,向南或向西移動(dòng)。這些動(dòng)作由集合{N,E,S,W} {N,E,S,W}表示。請(qǐng)注意,代理始終知道狀態(tài)(即其在網(wǎng)格中的位置)。
?網(wǎng)格中存在一些壁,代理無(wú)法通過(guò)這些壁。?
基本的Gridworld實(shí)施
我已經(jīng)以面向?qū)ο蟮姆绞綄?shí)現(xiàn)了gridworld。以下各節(jié)描述了我如何設(shè)計(jì)地圖和策略實(shí)體的代碼。
?Gridworld地圖
為了實(shí)現(xiàn)gridworld,我首先要做的是代表地圖的類。我定義了以下格式來(lái)表示各個(gè)網(wǎng)格單元:
#
?指示墻壁X
?表明目標(biāo)空白表示空塊
依靠這些符號(hào), 構(gòu)造??了下面的map?:
###################
# ? ? ? ? ? ? ? ?X#
# ? ########### ? #
# ? # ? ? ? ? # ? #
# ? # ####### # ? #
# ? # # ? ? # # ? #
# ? ? # ?# ?# ? ? #
# ? ? ? ?# ? ? ? ?#
# ? ? ? ? ? ? ? ? #
### ? ? ? ? ? ? ###
# ? ? ? ? ? ? ? ? #
###################
??
?
我實(shí)現(xiàn)了??MapParser,它生成一個(gè)??Map對(duì)象。地圖對(duì)象控制? ?對(duì)gridworld?單元的訪問(wèn)。單個(gè)單元格子類定義特定單元格的行為,例如空單元格,墻和目標(biāo)單元格??梢允褂闷湫泻土兴饕齺?lái)標(biāo)識(shí)每個(gè)單元格。
通過(guò)此設(shè)置,可以方便地加載地圖:
parser = MapParser()
gridMap = parser.parseMap("../data/map01.grid")
載入?
對(duì)于強(qiáng)化學(xué)習(xí),我們需要能夠處理一個(gè)策略π(s,a)π(s,a)。在gridworld中,每個(gè)狀態(tài)ss代表代理的位置。這些動(dòng)作將代理移動(dòng)到四個(gè)地理方向之一。我們將使用以下符號(hào)將策略映射到地圖上:
N為動(dòng)作?
GO_NORTH
E為行動(dòng)?
GO_EAST
S為動(dòng)作?
GO_SOUTH
W為行動(dòng)?
GO_WEST
未知符號(hào)被映射到??NONE
?操作??,以獲得完整的策略。
使用這些定義,我定義??了以下策略:
###################
#EESWWWWWWWWWWWWWX#
#EES###########SWN#
#EES#EEEEEEEES#SWN#
#EES#N#######S#SWN#
#EES#N#SSWWW#S#SWN#
#EEEEN#SS#NN#SWSWN#
#EENSSSSS#NNWWWWWN#
#EENWWWWEEEEEEEEEN#
###NNNNNNNNNNNNN###
#EENWWWWWWWWWWWWWW#
###################
請(qǐng)注意,策略文件保留了圍墻和目標(biāo)單元,以提高可讀性。該政策的制定有兩個(gè)目標(biāo):
代理應(yīng)該能夠達(dá)到目標(biāo)。?對(duì)于未實(shí)現(xiàn)此屬性的策略,策略評(píng)估將不會(huì)給出合理的結(jié)果,因?yàn)橛肋h(yuǎn)不會(huì)獲得目標(biāo)回報(bào)。
該策略應(yīng)該不是最理想的。這意味著在某些狀態(tài)下,業(yè)務(wù)代表沒(méi)有采取最短的路徑達(dá)到目標(biāo)。這樣的策略使我們可以看到嘗試改進(jìn)初始策略的算法的效果。
為了加載該策略,我實(shí)現(xiàn)了一個(gè)??策略解析器,該解析器將策略存儲(chǔ)為??策略對(duì)象。使用這些對(duì)象,我們可以像這樣加載初始策略:
policyParser = PolicyParser()
policy = policyParser.parsePolicy("../data/map01.policy")
策略對(duì)象具有用于建模π(s,a)π(s,a)的功能:
def pi(self, cell, action):
if len(self.policy) == 0:
# no policy: try all actions (for value iteration)
return 1
if self.policyActionForCell(cell) == action:
# policy allows this action
return ?1
else:
# policy forbids this action
return 0
強(qiáng)化學(xué)習(xí)的準(zhǔn)備
為了準(zhǔn)備實(shí)施強(qiáng)化學(xué)習(xí)算法,我們?nèi)匀恍枰峁┻^(guò)渡和獎(jiǎng)勵(lì)功能。
過(guò)渡函數(shù)
要定義轉(zhuǎn)換函數(shù)Pass'Pss'a,我們首先需要區(qū)分非法行為和法律行為。在gridworld中,有兩種方法可以使動(dòng)作不合法:
如果該動(dòng)作會(huì)使代理脫離網(wǎng)格
如果該動(dòng)作會(huì)使代理人陷入困境
這為我們提供了轉(zhuǎn)換函數(shù)的第一條規(guī)則:
1. When an action is illegal, the agent should remain in its previous state.
此外,我們還必須要求:
2. When an action is illegal, transitions to states other than its previous state should be forbidden.
?當(dāng)然,狀態(tài)轉(zhuǎn)換對(duì)于所選動(dòng)作必須有效。由于每個(gè)動(dòng)作僅將代理移動(dòng)一個(gè)位置,因此建議狀態(tài)s's'必須在與狀態(tài)ss相鄰的單元格中具有代理:
3. Only allow transitions through actions that would lead the agent to an adjacent cell.
對(duì)于此規(guī)則,我們假設(shè)有一個(gè)謂詞adj(s,s')adj(s,s')來(lái)指示主體從ss到s's'的過(guò)渡是否涉及相鄰單元格。
最后,一旦達(dá)到目標(biāo)狀態(tài)s ? s ?,我們就不希望代理再次離開。為了說(shuō)明這一點(diǎn),我們引入了最終規(guī)則:
4. Don't transition from the goal cell.
基于這四個(gè)規(guī)則,我們可以定義轉(zhuǎn)換函數(shù)如下:
?

所提供的Python實(shí)現(xiàn)??getTransitionProbability
?并不像數(shù)學(xué)公式那樣明確 :
def getTransitionProbability(self, oldState, newState, action, gridWorld):
proposedCell = gridWorld.proposeMove(action)
if proposedCell is None:
# Rule 1 and 2: illegal move
return transitionProbabilityForIllegalMoves(oldState, newState)
if oldState.isGoal():
# Rule 4: stay at goal
return 0
if proposedCell != newState:
# Rule 3: move not possible
return 0
else:
# Rule 3: move possible
return 1
請(qǐng)注意,它??proposeMove
?模擬了操作的成功執(zhí)行,并返回了代理的新網(wǎng)格單元。
獎(jiǎng)勵(lì)函數(shù)
在gridworld中,我們想找到到達(dá)終端狀態(tài)的最短路徑。我們要最大化獲得的獎(jiǎng)勵(lì),因此目標(biāo)狀態(tài)s ? s ?的獎(jiǎng)勵(lì)應(yīng)高于其他狀態(tài)的獎(jiǎng)勵(lì)。對(duì)于gridworld,我們將使用以下簡(jiǎn)單函數(shù):
?

?
?評(píng)估
策略評(píng)估算法的目標(biāo)? ?是評(píng)估策略π(s,a)π(s,a),即根據(jù)V(s)?sV(s)?s確定所有狀態(tài)的值。該算法基于Bellman方程:
?

對(duì)于迭代k + 1k + 1,該方程式通過(guò)以下公式得出狀態(tài)ss的值:
π(s,a)π(s,a):在狀態(tài)ss中選擇動(dòng)作aa的概率
Pass'Pss'a:使用動(dòng)作aa從狀態(tài)ss過(guò)渡到狀態(tài)s's'的概率
Rass'Rss'a:使用動(dòng)作aa從狀態(tài)ss過(guò)渡到狀態(tài)s's'時(shí)的預(yù)期獎(jiǎng)勵(lì)
γγ:貼現(xiàn)率
Vπk(s')Vkπ(s'):在給定策略ππ的情況下,步驟kk中狀態(tài)s's'的值
為了更好地理解方程式,讓我們?cè)趃ridworld的上下文中逐一考慮:
π(s,a)π(s,a):由于我們處于確定性環(huán)境中,因此策略僅指定一個(gè)動(dòng)作aa,其中π(s,a)=1π(s,a)= 1,而所有其他動(dòng)作a'a'具有π(s,a')=0π(s,a')= 0。因此,乘以π(s,a)π(s,a)只會(huì)選擇策略指定的操作。
∑s′∑s′:該和是所有狀態(tài)s′s′的總和,可以從當(dāng)前狀態(tài)ss得到。在gridworld中,我們只需要考慮相鄰像元和當(dāng)前像元本身,即s'∈{x | adj(x,s)∨x= s}s'∈{x | adj(x,s)∨x= s }。
Pass'Pss'a:這是通過(guò)動(dòng)作aa從狀態(tài)ss過(guò)渡到s's'的概率。
Rass'Rss'a:這是通過(guò)aa從ss過(guò)渡到s's'的獎(jiǎng)勵(lì)。請(qǐng)注意,在gridworld中,獎(jiǎng)勵(lì)僅由下一個(gè)狀態(tài)s's'確定。
γγ:折現(xiàn)因子調(diào)節(jié)預(yù)期獎(jiǎng)勵(lì)的影響。
Vk(s')Vk(s'):在提議狀態(tài)s's'的預(yù)期獎(jiǎng)勵(lì)。該術(shù)語(yǔ)的存在是政策評(píng)估是動(dòng)態(tài)編程的原因:我們正在使用先前計(jì)算的值來(lái)更新當(dāng)前值。
我們將使用γ=1γ= 1,因?yàn)槲覀兲幵谝粋€(gè)情景 中,在達(dá)到目標(biāo)狀態(tài)時(shí)學(xué)習(xí) 停止。因此,值函數(shù)表示到達(dá)目標(biāo)單元格的最短路徑的長(zhǎng)度。更準(zhǔn)確地說(shuō),讓d(s,s ?)d(s,s ?)表示從狀態(tài)ss到目標(biāo)的最短路徑。然后,對(duì)于s≠s ? s≠s ?,Vπ(s)=-d(s,s ?)+1Vπ(s)=-d(s,s ?)+ 1。
為了實(shí)施策略評(píng)估,我們通常將對(duì)狀態(tài)空間進(jìn)行多次掃描。每次掃描都需要前一次迭代中的值函數(shù)。新值和舊值函數(shù)之間的差異通常用作算法的終止條件:
def findConvergedCells(self, V_old, V_new, theta = 0.01):
diff = abs(V_old-V_new)
return np.where(diff < theta)[0]
該函數(shù)確定值函數(shù)差異小于θθ的網(wǎng)格單元的索引。當(dāng)所有狀態(tài)的值都收斂到穩(wěn)定值時(shí),我們可以停止。由于情況并非總是如此(例如,如果策略指定狀態(tài)的動(dòng)作不會(huì)導(dǎo)致目標(biāo),或者過(guò)渡概率/獎(jiǎng)勵(lì)配置不當(dāng)),我們還要指定最大迭代次數(shù)。
達(dá)到停止條件后,??evaluatePolicy
?返回最新的狀態(tài)值函數(shù):
def evaluatePolicy(self, gridWorld, gamma = 1):
if len(self.policy) != len(gridWorld.getCells()):
# sanity check whether policy matches dimension of gridWorld
raise Exception("Policy dimension doesn't fit gridworld dimension.")
maxIterations = 500
V_old = None
V_new = initValues(gridWorld) # sets value of 0 for viable cells
iter = 0
convergedCellIndices = np.zeros(0)
while len(ConvergedCellIndices) != len(V_new):
V_old = V_new
iter += 1
V_new = self.evaluatePolicySweep(gridWorld, V_old, gamma, convergedCellIndices)
convergedCellIndices = self.findConvergedCells(V_old, V_new)
if iter > maxIterations:
break
print("Policy evaluation converged after iteration: " + str(iter))
return V_new
該evaluatePolicySweep
?功能執(zhí)行一次策略評(píng)估掃描? 。該函數(shù)遍歷網(wǎng)格中的所有單元并確定狀態(tài)的新值.
請(qǐng)注意,該??ignoreCellIndices
?參數(shù)表示后續(xù)掃描未更改值函數(shù)的像元索引。這些單元在進(jìn)一步的迭代中將被忽略以提高性能。這對(duì)于我們的gridworld示例來(lái)說(shuō)很好,因?yàn)槲覀冎皇窍胝业阶疃痰穆窂健R虼?,狀態(tài)值函數(shù)第一次不變時(shí),這是其最佳值。
使用該evaluatePolicyForState
?函數(shù)計(jì)算狀態(tài)值? 。該函數(shù)的核心實(shí)現(xiàn)了我們先前討論的Bellman方程。此函數(shù)的重要思想是,在計(jì)算狀態(tài)ss的值函數(shù)時(shí),我們不想掃描所有狀態(tài)s's'。這就是為什么??狀態(tài)生成器??僅生成可能實(shí)際發(fā)生的狀態(tài)(即,轉(zhuǎn)換概率大于零)的原因。
?評(píng)估結(jié)果
有了適當(dāng)?shù)膶?shí)現(xiàn)后,我們可以通過(guò)執(zhí)行以下命令找到策略的狀態(tài)值函數(shù).
為了將值函數(shù)與策略一起繪制,我們可以在將用于表示地圖的一維數(shù)組轉(zhuǎn)換為二維數(shù)組后,使用matplotlib中的pyplot:
def drawValueFunction(V, gridWorld, policy):
fig, ax = plt.subplots()
im = ax.imshow(np.reshape(V, (-1, gridWorld.getWidth())))
for cell in gridWorld.getCells():
p = cell.getCoords()
i = cell.getIndex()
if not cell.isGoal():
text = ax.text(p[1], p[0], str(policy[i]),
ha="center", va="center", color="w")
if cell.isGoal():
text = ax.text(p[1], p[0], "X",
ha="center", va="center", color="w")
plt.show()
使用該函數(shù),我們可以可視化策略的狀態(tài)值函數(shù):

?
對(duì)于非目標(biāo)單元,將使用策略指定的操作對(duì)圖進(jìn)行注釋。X
?標(biāo)簽上方表示右上方單元格中的目標(biāo)? 。?
其他單元格的值由顏色指示。最差的狀態(tài)(具有最低的獎(jiǎng)勵(lì))以紫色顯示,壞的狀態(tài)以藍(lán)色顯示,藍(lán)綠色的中間狀態(tài)以綠色顯示,良好的狀態(tài)以綠色顯示,非常好的狀態(tài)(具有最高的獎(jiǎng)勵(lì))顯示為黃色。
查看這些值,我們可以看到結(jié)果與策略規(guī)定的操作相匹配。例如,直接位于目標(biāo)西側(cè)的狀態(tài)的值非常低,因?yàn)樵摖顟B(tài)的動(dòng)作(GO_WEST
)會(huì)導(dǎo)致較長(zhǎng)的彎路。位于目標(biāo)正南方的單元格具有很高的價(jià)值,因?yàn)槠渥饔茫?code>GO_NORTH)直接導(dǎo)致目標(biāo)。
請(qǐng)注意,在以后的工作中,的性能??evaluatePolicy
?至關(guān)重要,因?yàn)槲覀儠?huì)多次調(diào)用它。對(duì)于計(jì)算的示例,該函數(shù)需要進(jìn)行61次迭代,這在我的筆記本電腦上大約轉(zhuǎn)換了半秒鐘。請(qǐng)注意,對(duì)于更接近最佳策略的策略,策略評(píng)估將需要較少的迭代,因?yàn)橹祵⒏斓貍鞑ァ?/p>
能夠確定狀態(tài)值函數(shù)非常好-現(xiàn)在我們可以量化所提議策略的優(yōu)點(diǎn)了。但是,我們尚未解決尋找最佳政策的問(wèn)題。這就是策略迭代起作用的地方。
策略迭代
現(xiàn)在我們已經(jīng)能夠計(jì)算狀態(tài)值函數(shù),我們應(yīng)該能夠??改進(jìn)現(xiàn)有的策略。一種簡(jiǎn)單的策略是貪婪算法,該算法遍歷網(wǎng)格中的所有單元格,然后根據(jù)值函數(shù)選擇使預(yù)期獎(jiǎng)勵(lì)最大化的操作。
?其定義為

?
?improvePolicy
?函數(shù)確定策略的值函數(shù) ,然后調(diào)用??findGreedyPolicy
?以標(biāo)識(shí)每種狀態(tài)的最佳操作.
要做的??findGreedyPolicy
?是考慮每個(gè)單元并選擇使預(yù)期獎(jiǎng)勵(lì)最大化的動(dòng)作,從而構(gòu)造輸入策略的改進(jìn)版本。例如,執(zhí)行??improvePolicy
?一次并重新評(píng)估策略后,我們得到以下結(jié)果:

?
與原始值函數(shù)相比,目標(biāo)旁邊的所有單元格現(xiàn)在都給了我們很高的回報(bào),因?yàn)椴僮饕训玫絻?yōu)化。但是,我們可以看到這些改進(jìn)僅僅是局部的。那么,我們?nèi)绾潍@得最優(yōu)政策呢?
策略迭代算法的思想? ?是,我們可以通過(guò) 迭代評(píng)估新策略的狀態(tài)值函數(shù)來(lái)找到最優(yōu)策略,并使用貪心算法對(duì)該策略進(jìn)行改進(jìn),直到達(dá)到最優(yōu):
def policyIteration(policy, gridWorld):
lastPolicy = copy.deepcopy(policy)
lastPolicy.resetValues() # reset values to force re-evaluation of policy
improvedPolicy = None
while True:
improvedPolicy = improvePolicy(lastPolicy, gridWorld)
if improvedPolicy == lastPolicy:
break
improvedPolicy.resetValues() # to force re-evaluation of values on next run
lastPolicy = improvedPolicy
return(improvedPolicy)
策略迭代的結(jié)果
在gridworld上運(yùn)行該算法可以在20次迭代中找到最佳解決方案-在我的筆記本上大約需要4.5秒。20次迭代后的終止并不令人驚訝:gridworld貼圖的寬度為19。因此,我們需要進(jìn)行19次迭代才能優(yōu)化水平走廊的值。然后,我們需要進(jìn)行一次額外的迭代來(lái)確定該算法可以終止,因?yàn)樵摬呗晕锤摹?/p>
理解策略迭代的一個(gè)很好的工具是可視化每個(gè)迭代:

?
下圖顯示了使用策略迭代構(gòu)造的最優(yōu)值函數(shù):

?
目視檢查表明值函數(shù)正確,因?yàn)樗鼮榫W(wǎng)格中的每個(gè)單元格選擇了最短路徑。
價(jià)值迭代
借助我們迄今為止探索的工具,出現(xiàn)了一個(gè)新問(wèn)題:為什么我們根本需要考慮初始策略??jī)r(jià)值迭代算法的思想? ?是我們可以在沒(méi)有策略的情況下計(jì)算價(jià)值函數(shù)。與其讓政策ππ指示選擇了哪些操作,我們不選擇那些使預(yù)期獎(jiǎng)勵(lì)最大化的操作:

?
因?yàn)閮r(jià)值迭代的計(jì)算與策略評(píng)估非常相似,所以我已經(jīng)實(shí)現(xiàn)了將價(jià)值迭代evaluatePolicyForState
?用于我先前定義的方法中的功能? 。?
只要沒(méi)有可用的策略,此函數(shù)就會(huì)執(zhí)行值迭代算法。在這種情況下,??len(self.policy)
?將為零,從而??pi
?始終返回一個(gè)值,并且??V
?被確定為所有動(dòng)作的預(yù)期獎(jiǎng)勵(lì)的最大值。
因此,要實(shí)現(xiàn)值迭代,我們不必做很多編碼。我們只需要evaluatePolicySweep
?在Policy
?對(duì)象的值函數(shù)未知的情況下迭代調(diào)用該? 函數(shù),? 直到該過(guò)程為我們提供最佳結(jié)果為止。然后,要確定相應(yīng)的策略,我們只需調(diào)用findGreedyPolicy
?我們先前定義的? 函數(shù).
價(jià)值迭代的結(jié)果
?
當(dāng)執(zhí)行值迭代時(shí),獎(jiǎng)勵(lì)(高:黃色,低:黑暗)從目標(biāo)的最終狀態(tài)(右上方??X
)擴(kuò)展到其他狀態(tài):

?
摘要
我們已經(jīng)看到了如何在MDP中應(yīng)用強(qiáng)化學(xué)習(xí)。我們的工作假設(shè)是我們對(duì)環(huán)境有全面的了解,并且代理完全了解環(huán)境?;诖?,我們能夠促進(jìn)動(dòng)態(tài)編程來(lái)解決三個(gè)問(wèn)題。首先,我們使用策略評(píng)估來(lái)確定給定策略的狀態(tài)值函數(shù)。接下來(lái),我們應(yīng)用策略迭代算法來(lái)優(yōu)化現(xiàn)有策略。第三,我們應(yīng)用價(jià)值迭代從頭開始尋找最佳策略。
?