当前位置:   article > 正文

强化学习-DQN-走迷宫实战_强化学习 迷宫

强化学习 迷宫

强化学习

RL:面对一个不断变化的的状态空间,解决决策问题,找到在当前环境状态下最佳决策是什么。

即:最大折扣化奖励的平均值,预期效益。

输入一个动作状态,尝试输出关于s、a的动作状态值函数值。s——状态,a——动作。

其中最重要的特征:动作与状态、状态转移、奖励、策略、环境。

选择某策略来优化最大化折扣奖励平均值

强化学习的特点:

  • 没有监督数据、只有奖励信号。
  • 奖励信号不一定是实时的,而很可能是延后的,有时甚至延后很多。
  • 时间(序列)是一个重要因素。
  • 当前的行为影响后续接收到的数据。

应用:下棋、机器人、自动驾驶。

Q(s,a)=R1+\gamma * \frac{max(s{}',a{}')}{a'}

R1即现在走到的这个状态的奖励值。\gamma即折扣因子,\frac{max(s{}',a{}')}{a'}即找到使奖励最大化的状态a‘

QLearning,DQN-基于深度学习的Q-Learning算法

该算法核心原理是Q-Table,其行和列表示State和Action的值,Q-Table的值Q(s,a)是衡量当前States采取行动a的重要依据

由于机器会失误,所以我们在更新新的奖励状态时取之前的一部分与新的一部分。

具体步骤如下:

  1. 初始化Q表,学习率、折扣因子、贪婪策略取值、
  2. 执行以下循环:
    1. 初始化一个Q表格,Q表格的行表示状态,列表示动作,Q值表示某个状态下采取某个动作的价值估计。初始时,Q值可以设置为0或随机值。
    2. 针对每个时刻,根据当前状态s,选择一个动作a。可以根据当前状态的Q值和某种策略(如贪心策略)来选择动作。
    3. 执行选择的动作a,得到下一个状态s'和相应的奖励r$
    4. 基于下一个状态s',更新Q值。Q值的更新方式为:
      1. 初始化一个状态s。
      2. 根据当前状态s和Q表中的Q值,选择一个动作a。可以通过epsilon-greedy策略来进行选择,即有一定的概率随机选择动作,以便于探索新的状态,否则就选择Q值最大的动作。
      3. 执行选择的动作a,得到下一个状态s'和奖励r。
      4. 根据s'和Q表中的Q值,计算出最大Q值maxQ。
      5. 根据Q-learning的更新公式,更新Q值:Q(s, a) = Q(s, a) + alpha * (r + gamma * maxQ - Q(s, a)),其中alpha是学习率,gamma是折扣因子。
      6. 将当前状态更新为下一个状态:s = s'。
      7. 如果当前状态为终止状态,则转到步骤1;否则转到步骤2。
      8. 重复执行步骤1-7直到收敛,即Q值不再发生变化或者达到预定的最大迭代次数。最终得到的Q表中的Q值就是最优的策略。
    5. 重复执行2-4步骤,直到到达终止状态,或者达到预设的最大步数。
    6. 不断执行1-5步骤,直到Q值收敛。
    7. 在Q表格中根据最大Q值,选择一个最优的策略。
  1. import numpy as np
  2. import random
  3. #生成迷宫图像
  4. from matplotlib import pyplot as plt
  5. #实现QL
  6. class QLearningAgent:
  7. # 首先初始化动作空间,设置学习率,discount——factor折扣因子,epsilon-贪婪略取值,num_actions动作数
  8. def __init__(self,actions,size):
  9. self.actions=actions
  10. self.learning_rate=0.04
  11. self.discount_factor=0.9
  12. self.epsilon=0.1
  13. self.num_actions=len(actions)
  14. #初始化,q_table=动作状态.Q-Table的值Q(s,a)是衡量当前States采取行动a的重要依据
  15. self.q_table=np.zeros((size,size,self.num_actions))
  16. # 核心,给定当前动作,状态、奖励、下一状态去更新下一个Q表。
  17. def learn(self,state,action,reward,next_state):
  18. current_q=self.q_table[state][action]
  19. new_q=reward+self.discount_factor*max(self.q_table[next_state])
  20. self.q_table[state][action]+=self.learning_rate*(new_q-current_q)
  21. #新的q值要根据公式计算,更新时要与学习率相结合采取原q值的0.9+新q值的0.1
  22. #得到下一个动作
  23. def get_action(self,state):
  24. if np.random.rand()<self.epsilon:
  25. action=np.random.choice(self.actions)
  26. else:
  27. state_action=self.q_table[state]
  28. action=self.argmax(state_action)
  29. return action
  30. #从所有状态中选择最大奖励的那个。对于奖励相同的我们随机选择一个。
  31. # #获取最大值对应的动作,遍历q表中的所有动作,找到最大值对应的,最后从这些动作中随机选择一个为最终
  32. @staticmethod
  33. def argmax(state_action):
  34. max_index_list=[]
  35. max_value=state_action[0]
  36. for index,value in enumerate(state_action):
  37. if value>max_value:
  38. max_index_list.clear()
  39. max_value=value
  40. max_index_list.append(index)
  41. elif value==max_value:
  42. max_index_list.append(index)
  43. return random.choice(max_index_list)
  44. #定义迷宫环境
  45. class MazeEnv:
  46. def __init__(self,size):
  47. self.size=size
  48. self.actions=[0,1,2,3]
  49. self.maze,self.start,self.end=self.generate(size)
  50. #重置 状态
  51. def reset(self):
  52. self.state=self.start
  53. self.goal=self.end
  54. self.path=[self.start]
  55. self.solve=np.zeros_like(self.maze)
  56. self.solve[self.start]=1
  57. self.solve[self.end]=1
  58. return self.state
  59. def step(self,action):
  60. #执行动作
  61. next_state=None
  62. if action==0 and self.state[0]>0:
  63. next_state=(self.state[0]-1,self.state[1])
  64. elif action==1 and self.state[0]<self.size-1:
  65. next_state=(self.state[0]+1,self.state[1])
  66. elif action==2 and self.state[1]>0:
  67. next_state=(self.state[0],self.state[1]-1)
  68. elif action==3 and self.state[1]<self.size-1:
  69. next_state=(self.state[0],self.state[1]+1)
  70. else:
  71. next_state=self.state
  72. #坐标随方向变后,更改奖励
  73. if next_state==self.goal:
  74. reward=100
  75. elif self.maze[next_state] == -1:
  76. reward=-100
  77. else:
  78. reward=-1
  79. self.state=next_state
  80. self.path.append(self.state)
  81. self.solve[self.state]=1
  82. done=(self.state==self.goal)
  83. #判断是否结束
  84. return next_state,reward,done
  85. @staticmethod
  86. #生成迷宫图像
  87. def generate(size):
  88. maze=np.zeros((size,size))
  89. start=(random.randint(0,size-1),0)
  90. end=(random.randint(0,size-1),size-1)
  91. maze[start]=1
  92. maze[end]=1
  93. for i in range(size*size):
  94. x,y=random.randint(0,size-1),random.randint(0,size-1)
  95. if (x,y)==start or (x,y)==end:
  96. continue
  97. if random.random()<0.2:
  98. maze[x,y]=-1
  99. if np.sum(np.abs(maze))==size*size-2:
  100. break
  101. return maze,start,end
  102. #bfs求出路径
  103. @staticmethod
  104. def solve_maze(maze,start,end):
  105. size=maze.shape[0]
  106. visited=np.zeros((size,size))
  107. solve=np.zeros((size,size))
  108. queue=[start]
  109. visited[start[0],start[1]]=1
  110. while queue:
  111. x,y=queue.pop(0)
  112. if(x,y)==end:
  113. break
  114. for dx,dy in [(0,1),(1,0),(0,-1),(-1,0)]:
  115. nx,ny= x+ dx,y+dy
  116. if nx<0 or nx>=size or ny<0 or ny>=size or visited[nx,ny] or maze[nx,ny]==-1:
  117. continue
  118. queue.append((nx,ny))
  119. visited[nx,ny]=visited[x,y]+1
  120. if visited[end[0],end[1]]==0:
  121. return solve,[]
  122. path=[end]
  123. x,y=end
  124. while(x,y)!=start:
  125. for dx,dy in [(0,1),(0,-1),(1,0),(-1,0)]:
  126. nx,ny=x+dx,y+dy
  127. if nx<0 or nx>=size or ny<0 or ny>=size or visited[nx,ny]!=visited[x,y]-1:
  128. continue
  129. path.append((nx,ny))
  130. x,y=nx,ny
  131. break
  132. #倒序
  133. points=path[::-1]
  134. for point in points:
  135. solve[point[0]][point[1]]=1
  136. return solve,points
  137. #执行
  138. maze_size=32
  139. #创建环境
  140. env=MazeEnv(maze_size)
  141. #初始化QLerning智能体
  142. agent=QLearningAgent(actions=env.actions,size=maze_size)
  143. #进行30000次游戏
  144. for epoisode in range(30000):
  145. state =env.reset()
  146. while True:
  147. action=agent.get_action(state)
  148. next_state,reward,done=env.step(action)
  149. agent.learn(state,action,reward,next_state)
  150. state=next_state
  151. if done:
  152. break
  153. print(agent.q_table)
  154. #显示迷宫的路线
  155. from PIL import Image
  156. def maze_to_image(maze,path):
  157. size=maze.shape[0]
  158. img=Image.new('RGB',(size,size),(255,255,255))
  159. pixels=img.load()
  160. for i in range(size):
  161. for j in range(size):
  162. if maze[i,j]==-1:
  163. pixels[j,i]=(0,0,0)
  164. elif maze[i,j]==1:
  165. pixels[j,i]=(0,255,0)
  166. for x,y, in path:
  167. pixels[y,x]=(255,0,0)
  168. return np.array(img)
  169. #接着显示三个迷宫的图像:原图像、bfs求解图像,QLearning图像
  170. plt.figure(figsize=(16,10))
  171. image1=maze_to_image(env.maze,[])
  172. plt.subplot(3,1,1)
  173. plt.imshow(image1)
  174. plt.title('original maze')
  175. _,path=env.solve_maze(env.maze,env.start,env.end)
  176. image2=maze_to_image(env.maze,path)
  177. plt.subplot(3,1,2)
  178. plt.imshow(image2)
  179. plt.title('BFS')
  180. image3=maze_to_image(env.maze,env.path)
  181. plt.subplot(3,1,3)
  182. plt.imshow(image3)
  183. plt.title('QL')
  184. plt.show()

借鉴:基于RL(Q-Learning)的迷宫寻路算法 - N3ptune - 博客园 (cnblogs.com) 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/295917
推荐阅读
相关标签
  

闽ICP备14008679号