第3章给出了学习算法的基本思路:策略评估和策略改善。其中策略评估用到了以下的公式(4.1):
策略改善则用了最简单的贪婪策略(4.2):
为什么要用蒙特卡洛算法?先看公式4.1和4.2,如果状态转移概率已知,那么利用上面两式就可以得到最优策略。如果模型是未知的?式(4.1)不能再用,式(4.1)仍然可以用,因为该式与模型无关。
如果想要利用整个框架,必须找到一种方法来替代公式(4.1)的策略评估。
---->利用本章蒙特卡洛方法和第5章的时间差分方法。
4.1 蒙特卡洛算法原理
当模型是未知的,即智能体在状态s时并不知道转移到下一个状态s'的概率。但是,智能体在状态s通过动作a与环境进行交互,环境会根据根据状态转移给出下一个时刻的状态,但环境并不会直接给出状态转移的概率。也就是说,在模型未知时,我们只能通过一系列的动作,得到一系列的状态序列。
其中为终止状态。
至此,我们已经拥有当前的策略,以及根据策略Π得到的一连串数据,缺少状态转移概率,而想要评估策略Π的值函数,该怎么做?
既然不能使用式(4.1),那么回到值函数的定义式(4.3)
式4.3是期望的式子,其中表示一次实验数据,即为
G(τ)为累积折扣回报,为产生轨迹的概率分布,我们不知道值函数的概率分布,所以不能用积分公式来求值函数。但我们有数据就可以计算在策略Π的作用下,经过一次实验τ后状态St处的折扣累积回报G(τ)。
蒙特卡洛的方法就是用策略Π做很多次实验,从而可以的带状态处的很多个折扣累积回报,那么公式(4.3)的积分公式,就可以用代数平均来计算。即式(4.4):
那有了式4.4和式4.2,就可以进行策略评估和策略改善了吗?
还不行,因此公式4.2,我们只知道每个状态处的行为-值函数q(s,a),而不是状态值
行为值函数的定义为式(4.5):
当模型P已知时,值函数可以由式(4.5)计算出来。但模型未知时,该怎么办?
还是需要行为-值函数的原始定义,式(4.6):
式(4.6)的计算用前面的蒙特卡洛进行估计。即式(4.7):
对于无模型的强化学习算法,利用式4.7和式4.2就可以实现策略评估和策略改善。
1.关于值函数和行为值函数
值函数定义:
行为值函数定义:
即在状态,并采取了动作a之后折扣累积回报的期望。
举一个简单的例子,利用策略Π产生了如下两组数据:
那么状态值函数的计算公式为
行为值函数可以分为两个:
2.关于值函数的定义
注意:剩下的笔记我用手写笔记了,感觉手写笔记可以更多的思考,电子笔记时间全浪费在敲公式和字符那些上了,反而不利于思考。
4.2蒙特卡洛算法的代码实现
4.2.1 环境类的修改和蒙特卡洛算法类的声明
无模型的强化学习算法,需要评估的是行为-值函数,所以在渲染时,需要把行为值函数显示出来。得到形如图4.1的蒙特卡洛方法显示画面,在该画面上,每个方格表示一个状态,每个状态的4个值分别对应着4个动作的行为-值函数。
在原来的环境YuanYangEnv基础上修改:
gamma由原来的0.8设置为0.95,即增加后继回报对当前的影响。这是因为蒙特卡洛的方法利用整条轨迹的数据进行评估策略,如果gamma太小,后面回报的贡献会很快衰减。行为值函数声明为100x4的矩阵。
为了得到显示画面,在渲染子函数render()中进行修改:增加动作-值函数
除了对显示进行修改,对回报也进行修改。因为原来的回报只在找到目标点和碰撞障碍物的时候才会有回报,也就是说这些回报是稀疏回报,蒙特卡洛方法对于稀疏回报问题的估计方差无限大。为此,每一步都给出了回报,将稀疏回报问题变为稠密回报。代码修改transform()中
设置回报的规则是:如果碰到障碍物回报为-10,找到目标点回报为+10,如既没碰到障碍物又没找到目标点,每走一步回报为-2.
创建一个名为MC_RL.py的文件,在该文件下实现蒙特卡洛方法。首先,导入一些必要的库,然后命名为MC_RL的一个类,在初始化函数__init__中声明行为值函数,因为本例共100个状态,每个状态处有4个动作,因此,行为值函数是一个100x4的表格。用n来表示状态行为对被访问的次数。
定义e-greedy策略
找到动作所对应的序号
4.2.2 探索初始化蒙特卡洛算法实现
探索初始化蒙特卡洛算法实现的伪代码如下:
第1行:进行必要的初始化,包括初始化行为值函数及策略
第2行:初始化状态和动作由均匀随机概率分布函数生成,从该随机的状态-行为对出发生成一组数据,对该组数据中每个状态-行为计算折扣累计回报。
第3行:利用蒙特卡洛增量式学习方法,根据上一步计算的折扣累计回报更新相应的行为-值函数。
第4行:利用更新后的行为值函数更新策略,这里用的策略是贪婪策略。
代码:
定义类子函数mc_learning_ei来实现探索初始化蒙特卡洛方法。首先初始化行为值函数为0,初始化访问格状态-动作对的次数为0.初始化完成后便进入正式的迭代学习阶段。声明存放状态样本、动作样本、回报样本的变量,并随机初始化状态s和动作a.
下面调用mc_test()子函数,该子函数用来测试经过蒙特卡洛学习到的策略是否找到了目标。如果找到了,该子函数会返回1,否则返回0.因此,如果返回1则结束蒙特卡洛学习,否则继续学习。当找到目标时,将蒙特卡洛迭代学习的次数打印出来。
下面的程序用当前贪婪策略进行一次实验,并保存相应的数据到s_samples、r_sample、a_sample中。
下面的语句很关键,在实际的训练过程中,智能体可以会往回走,往回走其实是不合理的。所以在这里给回到当前实验中已经访问的状态的动作一个负的回报。
下面根据回报值计算折扣累计回报,先得到下一个状态处的值函数q(s‘,a),然后逆向求解前面状态-行为对的折扣累计回报,最后得到该次实验中第一个状态行为对的折扣累计回报。
下面从该次实验第1个状态开始,一次计算后继状态的折扣累计回报,并利用增量式的方法更新每个状态-行为对的值。
在上面的代码中,用到了测试子函数mc_test()。该子函数中初始状态为0,智能体通过贪婪策略与环境进行交互。如果结束时智能体找到了目标,则设置标志为1,否则为0.最后,返回标志位。
下图为探索初始化蒙特卡洛算法效果图。从图中可以看到,雄鸟最终可以找到雌鸟,但走了一些弯路,路线不是最短的。
这里截了还未到终点的图,(还是之前显示的问题,我的电脑显示屏1080,但整个画面1200*900,后面再修改尺寸吧)
4.2.3 同策略蒙特卡洛算法实现
同策略蒙特卡洛算法实现的伪代码如下:
第1行:进行必要的初始化,包括初始化行为值函数,e-greedy策略。
第2行:从初始化状态S0开始,利用e-greedy策略生成一次实验数据,并对该次实验的每个状态-行为对计算折扣累计回报。
第3行:利用增量式蒙特卡洛学习方法进行更新行为值函数。
第4行:利用更新的行为值函数更新e-greedy策略。
详细代码:
定义mc_learning_on_policy()子函数为同策略蒙特卡洛学习算法。首先初始化行为值函数qvalue为零矩阵,个状态-行为对的次数为0,进入迭代学习循环中。声明变量用于存储装填样本、动作样本、回报样本,固定初始化状态s=0,设置e-greecy策略的探索率随迭代次数衰减。
设置好基本变量,进入与环境的交互程序,根据当前策略不断采集数据。采集数据的过程为利用当前策略得到当前动作a,智能体在状态s处采用动作a与环境交互,从环境中得到下一个状态s_next,回报r,以及是否结束的标志位done。
此处很关键,智能体在探索的时候可能会往回走到之前经历过的状态,对于这样的动作我们给与一个小的负回报。
下面检测蒙特卡洛学习算法的效果,判断是否已经完成任务,如果完成则结束学习。
下面根据回报值计算折扣累计回报,先得到下一个状态处的值函数q(s',a),然后逆向求解前面状态-行为对的折扣累计回报,最后得到该次实验第1个状态行为对的折扣累计回报。
下面的代码:从该次实验第1个状态开始,依次计算后继状态的折扣累计回报,并利用增量式的方法更新每个状态-行为对的值。
至此,该算法全部实现。写一个主函数,进行测试。首先利用环境类YuanYangEnv()实例化一个智体,然后,用蒙特卡洛算法实例化一个学习算法brain,调用探索初始化蒙特卡洛算法mc_learning_ei,接着,调用同策略蒙特卡洛算法mc_learning_on_policy,将学习到的行为-值函数给环境,将其渲染出来;最后,对学习好的策略进行测试,并显示路径。
def mc_test(self):
s = 0
s_sample = []
done = False
flag = 0
step_num = 0
while False == done and step_num < 30:
a = self.greedy_policy(self.qvalue, s)
# 与环境交互
s_next, r, done = self.yuanyang.transform(s, a)
s_sample.append(s)
s = s_next
step_num += 1
if s == 9:
flag = 1
return flag
if __name__=="__main__":
yuanyang = YuanYangEnv()
brain = MC_RL(yuanyang)
# 探索初始化方法
qvalue1 = brain.mc_learning_ei(num_iter=10000)
#on-policy方法
qvalue2=brain.mc_learning_on_policy(num_iter=10000, epsilon=0.2)
print(qvalue2)
#将行为值函数渲染出来
yuanyang.action_value = qvalue2
#测试学到的策略
flag = 1
s = 0
# print(policy_value.pi)
step_num = 0
path = []
# 将最优路径打印出来
while flag:
#渲染路径点
path.append(s)
yuanyang.path = path
a = brain.greedy_policy(qvalue2,s)
# a = agent.bolzman_policy(qvalue,s,0.1)
print('%d->%s\t' % (s, a),qvalue2[s,0],qvalue2[s,1],qvalue2[s,2],qvalue2[s,3])
yuanyang.bird_male_position = yuanyang.state_to_position(s)
yuanyang.render()
time.sleep(0.25)
step_num += 1
s_, r, t = yuanyang.transform(s, a)
if t == True or step_num > 30:
flag = 0
s = s_
#渲染最后的路径点
yuanyang.bird_male_position = yuanyang.state_to_position(s)
path.append(s)
yuanyang.render()
while True:
yuanyang.render()
这里截了还未到终点的图,(还是之前显示的问题,我的电脑显示屏1080,但整个画面1200*900,后面再修改尺寸吧)
可以看终端具体的输出
中间的省略了一些
总项目如下:
还有resources文件夹下的游戏背景图片和小鸟图片。
yuanyang_env_mc.py
import pygame
from load import *
import math
import time
import random
import numpy as np
class YuanYangEnv:
def __init__(self):
self.states=[]
for i in range(0,100):
self.states.append(i)
self.actions = ['e', 's', 'w', 'n']
self.gamma = 0.95
self.action_value = np.zeros((100, 4))
self.viewer = None
self.FPSCLOCK = pygame.time.Clock()
#屏幕大小
self.screen_size=(1200,900)
self.bird_position=(0,0)
self.limit_distance_x=120
self.limit_distance_y=90
self.obstacle_size=[120,90]
self.obstacle1_x = []
self.obstacle1_y = []
self.obstacle2_x = []
self.obstacle2_y = []
self.path = []
for i in range(8):
#第一个障碍物
self.obstacle1_x.append(360)
if i <= 3:
self.obstacle1_y.append(90 * i)
else:
self.obstacle1_y.append(90 * (i + 2))
# 第二个障碍物
self.obstacle2_x.append(720)
if i <= 4:
self.obstacle2_y.append(90 * i)
else:
self.obstacle2_y.append(90 * (i + 2))
self.bird_male_init_position=[0,0]
self.bird_male_position = [0, 0]
self.bird_female_init_position=[1080,0]
#def step(self):
def collide(self,state_position):
flag = 1
flag1 = 1
flag2 = 1
# 判断第一个障碍物
dx = []
dy = []
for i in range(8):
dx1 = abs(self.obstacle1_x[i] - state_position[0])
dx.append(dx1)
dy1 = abs(self.obstacle1_y[i] - state_position[1])
dy.append(dy1)
mindx = min(dx)
mindy = min(dy)
if mindx >= self.limit_distance_x or mindy >= self.limit_distance_y:
flag1 = 0
# 判断第二个障碍物
second_dx = []
second_dy = []
for i in range(8):
dx2 = abs(self.obstacle2_x[i] - state_position[0])
second_dx.append(dx2)
dy2 = abs(self.obstacle2_y[i] - state_position[1])
second_dy.append(dy2)
mindx = min(second_dx)
mindy = min(second_dy)
if mindx >= self.limit_distance_x or mindy >= self.limit_distance_y:
flag2 = 0
if flag1 == 0 and flag2 == 0:
flag = 0
if state_position[0] > 1080 or state_position[0] < 0 or state_position[1] > 810 or state_position[1] < 0:
flag = 1
return flag
def find(self,state_position):
flag=0
if abs(state_position[0]-self.bird_female_init_position[0])<self.limit_distance_x and abs(state_position[1]-self.bird_female_init_position[1])<self.limit_distance_y:
flag=1
return flag
def state_to_position(self, state):
i = int(state / 10)
j = state % 10
position = [0, 0]
position[0] = 120 * j
position[1] = 90 * i
return position
def position_to_state(self, position):
i = position[0] / 120
j = position[1] / 90
return int(i + 10 * j)
def reset(self):
#随机产生初始状态
flag1=1
flag2=1
while flag1 or flag2 ==1:
#随机产生初始状态,0~99,randoom.random() 产生一个0~1的随机数
state=self.states[int(random.random()*len(self.states))]
state_position = self.state_to_position(state)
flag1 = self.collide(state_position)
flag2 = self.find(state_position)
return state
def transform(self,state, action):
#将当前状态转化为坐标
current_position=self.state_to_position(state)
next_position = [0,0]
flag_collide=0
flag_find=0
#判断当前坐标是否与障碍物碰撞
flag_collide=self.collide(current_position)
#判断状态是否是终点
flag_find=self.find(current_position)
if flag_collide==1:
return state, -10, True
if flag_find == 1:
return state, 10, True
#状态转移
if action=='e':
next_position[0]=current_position[0]+120
next_position[1]=current_position[1]
if action=='s':
next_position[0]=current_position[0]
next_position[1]=current_position[1]+90
if action=='w':
next_position[0] = current_position[0] - 120
next_position[1] = current_position[1]
if action=='n':
next_position[0] = current_position[0]
next_position[1] = current_position[1] - 90
#判断next_state是否与障碍物碰撞
flag_collide = self.collide(next_position)
#如果碰撞,那么回报为-10,并结束
if flag_collide==1:
return self.position_to_state(current_position),-10,True
#判断是否终点
flag_find = self.find(next_position)
if flag_find==1:
return self.position_to_state(next_position),10,True
return self.position_to_state(next_position), -2, False
def gameover(self):
for event in pygame.event.get():
if event.type == QUIT:
exit()
def render(self):
if self.viewer is None:
pygame.init()
#画一个窗口
self.viewer=pygame.display.set_mode(self.screen_size,0,32)
pygame.display.set_caption("yuanyang")
#下载图片
self.bird_male = load_bird_male()
self.bird_female = load_bird_female()
self.background = load_background()
self.obstacle = load_obstacle()
#self.viewer.blit(self.bird_male, self.bird_male_init_position)
#在幕布上画图片
self.viewer.blit(self.bird_female, self.bird_female_init_position)
self.viewer.blit(self.background, (0, 0))
self.font = pygame.font.SysFont('times', 15)
self.viewer.blit(self.background,(0,0))
#画直线
for i in range(11):
pygame.draw.lines(self.viewer, (255, 255, 255), True, ((120*i, 0), (120*i, 900)), 1)
pygame.draw.lines(self.viewer, (255, 255, 255), True, ((0, 90* i), (1200, 90 * i)), 1)
self.viewer.blit(self.bird_female, self.bird_female_init_position)
#画障碍物
for i in range(8):
self.viewer.blit(self.obstacle, (self.obstacle1_x[i], self.obstacle1_y[i]))
self.viewer.blit(self.obstacle, (self.obstacle2_x[i], self.obstacle2_y[i]))
#画小鸟
self.viewer.blit(self.bird_male, self.bird_male_position)
# 画动作值函数
for i in range(100):
y = int(i / 10)
x = i % 10
#往东行为值函数
surface = self.font.render(str(round(float(self.action_value[i,0]), 2)), True, (0, 0, 0))
self.viewer.blit(surface, (120 * x + 80, 90 * y + 45))
#往南的值函数
surface = self.font.render(str(round(float(self.action_value[i, 1]), 2)), True, (0, 0, 0))
self.viewer.blit(surface, (120 * x + 50, 90 * y + 70))
# 往西的值函数
surface = self.font.render(str(round(float(self.action_value[i, 2]), 2)), True, (0, 0, 0))
self.viewer.blit(surface, (120 * x + 10, 90 * y + 45))
# 往北的值函数
surface = self.font.render(str(round(float(self.action_value[i, 3]), 2)), True, (0, 0, 0))
self.viewer.blit(surface, (120 * x + 50, 90 * y + 10))
# 画路径点
for i in range(len(self.path)):
rec_position = self.state_to_position(self.path[i])
pygame.draw.rect(self.viewer, [255, 0, 0], [rec_position[0], rec_position[1], 120, 90], 3)
surface = self.font.render(str(i), True, (255, 0, 0))
self.viewer.blit(surface, (rec_position[0] + 5, rec_position[1] + 5))
pygame.display.update()
self.gameover()
# time.sleep(0.1)
self.FPSCLOCK.tick(30)
if __name__=="__main__":
yy=YuanYangEnv()
yy.render()
while True:
for event in pygame.event.get():
if event.type == QUIT:
exit()
# speed = 50
# clock = pygame.time.Clock()
# state=0
# for i in range(12):
# flag_collide = 0
# obstacle1_coord = [yy.obstacle1_x[i],yy.obstacle1_y[i]]
# obstacle2_coord = [yy.obstacle2_x[i],yy.obstacle2_y[i]]
# flag_collide = yy.collide(obstacle1_coord)
# print(flag_collide)
# print(yy.collide(obstacle2_coord))
# time_passed_second = clock.tick()/1000
# i= int(state/10)
# j=state%10
# yy.bird_male_position[0]=j*40
# yy.bird_male_position[1]=i*30
# time.sleep(0.2)
# pygame.display.update()
# state+=1
# yy.render()
# print(yy.collide())
MC_RL.py
import pygame
import time
import random
import numpy as np
import matplotlib.pyplot as plt
from yuanyang_env_mc import YuanYangEnv
class MC_RL:
def __init__(self, yuanyang):
#行为值函数的初始化
self.qvalue = np.zeros((len(yuanyang.states),len(yuanyang.actions)))*0.1
#次数初始化
#n[s,a]=1,2,3?? 求经验平均时,q(s,a)=G(s,a)/n(s,a)
self.n = 0.001*np.ones((len(yuanyang.states),len(yuanyang.actions)))
self.actions = yuanyang.actions
self.yuanyang = yuanyang
self.gamma = yuanyang.gamma
# 定义贪婪策略
def greedy_policy(self, qfun, state):
amax = qfun[state, :].argmax()
return self.actions[amax]
#定义e-贪婪策略,蒙特卡罗方法,要评估的策略时e-greedy策略,产生数据的策略。
def epsilon_greedy_policy(self, qfun, state, epsilon):
amax = qfun[state, :].argmax()
#概率部分
if np.random.uniform() < 1- epsilon:
#最优动作
return self.actions[amax]
else:
return self.actions[int(random.random()*len(self.actions))]
#找到动作所对应的序号
def find_anum(self, a):
for i in range(len(self.actions)):
if a == self.actions[i]:
return i
def mc_learning_on_policy(self, num_iter, epsilon):
self.qvalue = np.zeros((len(yuanyang.states), len(yuanyang.actions)))
self.n = 0.001 * np.ones((len(yuanyang.states), len(yuanyang.actions)))
#学习num_iter次
for iter1 in range(num_iter):
#采集状态样本
s_sample = []
#采集动作样本
a_sample = []
#采集回报样本
r_sample = []
# #随机初始化状态
# s = self.yuanyang.reset()
#固定初始状态
s = 0
done = False
step_num = 0
epsilon = epsilon*np.exp(-iter1/1000)
#采集数据s0-a1-s1-a2-s2...terminate state
#for i in range(5):
while False == done and step_num < 30:
a = self.epsilon_greedy_policy(self.qvalue, s, epsilon)
#与环境交互
s_next, r, done = self.yuanyang.transform(s, a)
a_num = self.find_anum(a)
#往回走给予惩罚
if s_next in s_sample:
r= -2
#存储数据,采样数据
s_sample.append(s)
r_sample.append(r)
a_sample.append(a_num)
step_num+=1
#转移到下一个状态,继续试验,s0-s1-s2
s = s_next
#任务完成结束条件
if s == 9:
print("同策略第一次完成任务需要的次数:", iter1)
break
#从样本中计算累计回报,g(s_0) = r_0+gamma*r_1+gamma^2*r_2+gamma^3*r3+v(sT)
a = self.epsilon_greedy_policy(self.qvalue, s,epsilon)
g = self.qvalue[s,self.find_anum(a)]
#计算该序列的第一状态的累计回报
for i in range(len(s_sample)-1, -1, -1):
g *= self.gamma
g += r_sample[i]
# print("episode number, trajectory", iter1, s_sample)
# print("first state", s_sample[0], g)
#g=G(s1,a),开始算其他状态处的累计回报
for i in range(len(s_sample)):
#计算状态-行为对(s,a)的次数,s,a1...s,a2
self.n[s_sample[i], a_sample[i]] += 1.0
#利用增量式方法更新值函数
self.qvalue[s_sample[i], a_sample[i]] = (self.qvalue[s_sample[i], a_sample[i]]*(self.n[s_sample[i],a_sample[i]]-1)+g)/ self.n[s_sample[i], a_sample[i]]
g -= r_sample[i]
g /= self.gamma
# print("s_sample,a",g)
# print("number",self.n)
return self.qvalue
def mc_learning_ei(self, num_iter):
# 学习num_iter次
self.qvalue=np.zeros((len(yuanyang.states), len(yuanyang.actions)))
self.n = 0.001 * np.ones((len(yuanyang.states), len(yuanyang.actions)))
for iter1 in range(num_iter):
# 采集状态样本
s_sample = []
# 采集动作样本
a_sample = []
# 采集回报样本
r_sample = []
# 随机初始化状态
s = self.yuanyang.reset()
a = self.actions[int(random.random()*len(self.actions))]
done = False
step_num = 0
if self.mc_test() == 1:
print("探索初始化第一次完成任务需要的次数:", iter1)
break
# 采集数据s0-a1-s1-a2-s2...terminate state
# for i in range(5):
while False == done and step_num < 30:
# 与环境交互
s_next, r, done = self.yuanyang.transform(s, a)
a_num = self.find_anum(a)
# 往回走给予惩罚
if s_next in s_sample:
r = -2
# 存储数据,采样数据
s_sample.append(s)
r_sample.append(r)
a_sample.append(a_num)
step_num += 1
# 转移到下一个状态,继续试验,s0-s1-s2
s = s_next
a = self.greedy_policy(self.qvalue, s)
# 从样本中计算累计回报,g(s_0) = r_0+gamma*r_1+gamma^2*r_2+gamma^3*r3+v(sT)
a = self.greedy_policy(self.qvalue, s)
g = self.qvalue[s, self.find_anum(a)]
# 计算该序列的第一状态的累计回报
for i in range(len(s_sample) - 1, -1, -1):
g *= self.gamma
g += r_sample[i]
# print("episode number, trajectory", iter1, s_sample)
# print("first state", s_sample[0], g)
# g=G(s1,a),开始算其他状态处的累计回报
for i in range(len(s_sample)):
# 计算状态-行为对(s,a)的次数,s,a1...s,a2
self.n[s_sample[i], a_sample[i]] += 1.0
# 利用增量式方法更新值函数
self.qvalue[s_sample[i], a_sample[i]] = (self.qvalue[s_sample[i], a_sample[i]] * (
self.n[s_sample[i], a_sample[i]] - 1) + g) / self.n[s_sample[i], a_sample[i]]
g -= r_sample[i]
g /= self.gamma
# print("s_sample,a",g)
# print("number",self.n)
return self.qvalue
def mc_test(self):
s = 0
s_sample = []
done = False
flag = 0
step_num = 0
while False == done and step_num < 30:
a = self.greedy_policy(self.qvalue, s)
# 与环境交互
s_next, r, done = self.yuanyang.transform(s, a)
s_sample.append(s)
s = s_next
step_num += 1
if s == 9:
flag = 1
return flag
if __name__=="__main__":
yuanyang = YuanYangEnv()
brain = MC_RL(yuanyang)
# 探索初始化方法
qvalue1 = brain.mc_learning_ei(num_iter=10000)
#on-policy方法
qvalue2=brain.mc_learning_on_policy(num_iter=10000, epsilon=0.2)
print(qvalue2)
#将行为值函数渲染出来
yuanyang.action_value = qvalue2
#测试学到的策略
flag = 1
s = 0
# print(policy_value.pi)
step_num = 0
path = []
# 将最优路径打印出来
while flag:
#渲染路径点
path.append(s)
yuanyang.path = path
a = brain.greedy_policy(qvalue2,s)
# a = agent.bolzman_policy(qvalue,s,0.1)
print('%d->%s\t' % (s, a),qvalue2[s,0],qvalue2[s,1],qvalue2[s,2],qvalue2[s,3])
yuanyang.bird_male_position = yuanyang.state_to_position(s)
yuanyang.render()
time.sleep(0.25)
step_num += 1
s_, r, t = yuanyang.transform(s, a)
if t == True or step_num > 30:
flag = 0
s = s_
#渲染最后的路径点
yuanyang.bird_male_position = yuanyang.state_to_position(s)
path.append(s)
yuanyang.render()
while True:
yuanyang.render()
load.py
import pygame
import os
from pygame.locals import *
from sys import exit
#得到当前工程目录
current_dir = os.path.split(os.path.realpath(__file__))[0]
print(current_dir)
#得到文件名
bird_file = current_dir+"/resources/bird.png"
obstacle_file = current_dir+"/resources/obstacle.png"
background_file = current_dir+"/resources/background.png"
#创建小鸟,
def load_bird_male():
bird = pygame.image.load(bird_file).convert_alpha()
return bird
def load_bird_female():
bird = pygame.image.load(bird_file).convert_alpha()
return bird
#得到背景
def load_background():
background = pygame.image.load(background_file).convert()
return background
#得到障碍物
def load_obstacle():
obstacle = pygame.image.load(obstacle_file).convert()
return obstacle