伯克利吃豆人编程作业——深度优先搜索
本文章内容作为课上内容归纳和个人编程学习的记录,有关代码来自编程作业文件和B站图文专栏 https://www.bilibili.com/opus/410980451283542691?spm_id_from=333.1007.0.0
应用背景:单状态问题
- 初始状态
- 可能行动
- 转移函数
- 目标测试:判断给定状态是不是目标状态
- 路径耗散:为每条路径赋一个耗散值
解就是从初始状态导向目标状态的行动序列
深度优先搜索
一、深度优先策略的定义
在搜索过程中,优先扩展最新产生的(即最深的)节点,深度相等的节点顺序任意,符合上述特征的搜索被称为深度优先搜索。这种后进先出(Last In First Out,LIFO)的特点与栈一致,因此在编程实现中使用栈来放置待扩展节点。
二、题目信息
- 已提供的函数
getStartState(self):返回搜索问题的初始状态,状态通常是坐标形式(x,y)
isGoalState(self, state):判断当前状态state是否为目标状态,返回布尔值
getSuccessors(self, state):对于状态state,返回一个三元组(后续状态,行动,代价),,后续状态通常为坐标形式(x,y) - 待编辑函数
depFirstSearch(problem)
三、代码实现
点击查看代码
def depthFirstSearch(problem):
"""
// ... 原有注释保持不变 ...
"""
# 初始化已访问集合和栈
exploredNodes = set()
fringe = util.Stack()
startState = problem.getStartState()
# 如果起始状态就是目标,直接返回
if problem.isGoalState(startState):
return []
# 修改初始路径的存储格式,不再存储'Start'动作
fringe.push([(startState, None, 0)])
while not fringe.isEmpty():
currentPath = fringe.pop()#pop函数的作用:弹出栈顶并作为函数返回值,等效于在栈中去除该节点
currentState = currentPath[-1][0]#currentPath是
# 如果当前状态已经访问过,继续下一个
if currentState in exploredNodes:
continue
# 标记当前状态为已访问
exploredNodes.add(currentState)
# 如果找到目标,返回动作序列
if problem.isGoalState(currentState):
# 只返回实际的移动动作(排除None)
return [x[1] for x in currentPath if x[1] is not None]
# 获取后继状态并加入栈中
for successor in problem.getSuccessors(currentState):
if successor[0] not in exploredNodes:
nextPath = currentPath[:]
nextPath.append(successor)
fringe.push(nextPath)
return []#只有在没有找到目标节点才会运行到这里

浙公网安备 33010602011771号