这是我在一个网站上看到的大神写的程序! 这个程序是基于Q学习的方法。
我发的这个帖子其实是有几个问题想问问大家,也希望这段源代码对需要的初学者有一点点帮助。
问题一:正常Q学习中所建立的Q表都是表格状,而这个程序是字典的形式,并且x、y的范围是(-SIZE+1,SIZE)后面还有left,right,up,down,direction,为什么要加这些方向动作?
问题二:第159行q_table的键的索引‘obs’和196行’new_observation’中都有(python.x - food.x,python.y - food.y),为什么是python.x-food.x 和python.y - food.y?
问题三:在这个程序中不断地更新q_table,每次有奖励或者惩罚都对q表进行更新,但是当迟到食物之后,food的位置会发生改变,为什么‘蛇’依然能很快的找到食物的位置?原来的q表我认为不一定很适用于新的食物啊!
希望大神能在闲暇之余帮忙解决下问题,感激不尽!
以下为程序源代码:
import numpy as np
import pickle
import pygame as pg
SW = 500
SH = 500
pg.init() #初始化所有导入的 pygame 模块
clock = pg.time.Clock() #创建一个对象来帮助跟踪时间
win = pg.display.set_mode((SW, SH)) #初始化一个准备显示的窗口
SIZE = 15
EPOCHS = 160000
LOSE_PENALTY = 601
EAT_REWARD = 60
MOVE_PENALTY = 3
EPS = 0.7
EPS_DECAY = 0.9997
SHOW_WHEN = 2000
STEPS = 220
LEARNING_RATE = 0.8
DISCOUNT = 0.99
FPS = 30
SCALING = SW // SIZE
starting_q_table = None
class Snake:
def __init__(self):
self.x = 8
self.y = 7
self.size = 4
self.dir = 1 #directions are 0-up, 1-right, 2-down, 3-left
self.ate = False
self.body = []
for i in range(self.size):
self.body.append((self.x-i, self.y-i))
def move(self):
if self.dir % 2 == 0:
if self.dir > 0:
self.y += 1
else:
self.y -= 1
else:
if self.dir > 1:
self.x += 1
else:
self.x -= 1
if self.x >= SIZE: # no walls, snake will go through
self.x = 0
elif self.x < 0:
self.x = SIZE - 1
if self.y >= SIZE:
self.y = 0
elif self.y < 0:
self