SearchAgent
SearchAgent
初始化时包含三个参数:
fn='depthFirstSearch'
搜索算法prob='PositionSearchProblem'
解决的搜索问题heuristic='nullHeuristic'
是否使用启发式函数
init中有个if else的结构,有无启发信息直接返回searchfunction, 否则定义一个lambda表达式把启发函数作为参数加进去:self.searchFunction = lambda x: func(x, heuristic=heur)
在registerInitialState
函数中,根据输入初始状态,调用搜索方法函数,返回actions,并计算actions对应的path的cost值。
SearchProblem
SearchProblem类中,定义了如下几个方法,写搜索算法的时候主要也依赖于这几个函数,先弄清楚比较好:
getStartState()
:返回searchproblem的初始状态
isGoalState(state)
:state是否是目标状态(是否到达(1,1)位置)
getSuccessors(state)
:获得state的后继状态,返回三元组(successor, action, stepcost), action是到达后继状态的行动,stepcost是扩展到后继状态的损失
getCostOfActions(actions)
:获得行动序列的总体损失
PositionSearchProblem(search.SearchProblem)
目标:给定棋盘上的一个点Point(x,y), 求到达目标点的路径
定义了:
state space
状态空间的定义start state
goal test
successor function
cost function
__init__
函数中的参数:
gameState 定义在pacman.py中的一个object
costFn = lambda x: 1 costfunction定义了一个最简单的返回1
goal=(1,1) 目标是左下角的一个点
start=None 初始状态是一开始的位置,gameState.getPacmanPosition()
warn=True
visualize=True
def getSuccessors(self, state):
# 返回三元组(successor, action ,cost )的列表
# 三元组格式, 例如((3,4),“north”, 1)代表下一步要移动到(3,4),是原始点向北移动了一步,这一步cost=1
successors = []
# 所谓的action,其实就是向东南西北四个方向移动
# 遍历一遍四个方向,排除是墙的动作,其他的加入到successor列表中
for action in [Directions.NORTH, Directions.SOUTH, Directions.EAST, Directions.WEST]:
x,y = state # state为当前所在的位置
# directinToVector函数会根据action是东南西北返回一个元组,比如(0,1),就是x,y的增加值
dx, dy = Actions.directionToVector(action)
nextx, nexty = int(x + dx), int(y + dy)
if not self.walls[nextx][nexty]: # 如果不是墙
nextState = (nextx, nexty)
cost = self.costFn(nextState) # 计算到达这个状态的cost
successors.append( ( nextState, action, cost) )
# Bookkeeping for display purposes
self._expanded += 1 # DO NOT CHANGE
if state not in self._visited:
self._visited[state] = True
self._visitedlist.append(state)
return successors
def getCostOfActions(self, actions):
"""
Returns the cost of a particular sequence of actions. If those actions
include an illegal move, return 999999.
"""
if actions == None: return 999999
x,y= self.getStartState()
cost = 0
# 不向墙移动的action的cost都是1
for action in actions:
# Check figure out the next state and see whether its' legal
dx, dy = Actions.directionToVector(action)
x, y = int(x + dx), int(y + dy)
if self.walls[x][y]: return 999999 #墙的cost的值巨大,一定会排除
cost += self.costFn((x,y))
return cost
SearchAlgorithm
返回值格式:[s, s, w, s, w, w, s, w], s = Directions.SOUTH
,其实就是一个东南西北字符串的列表,告诉我们要向走到(1,1)的动作序列。