迷宫问题 深度优先搜索 广度优先搜索 宽度优先搜索【python】
文章目录
- 一、实验内容
- 二、深度优先搜索和广度优先搜索总结
- 1.深度优先搜索算法
- 2.广度优先搜索算法
- 三、实验代码和用于测试的迷宫
- 1.实验代码
- 2.测试迷宫
- 2.1 maze1.txt
- 2.2 maze2.txt
- 2.3 maze3.txt
- 四、实验结果
- 1. maze1.txt
- 2. maze2.txt
- 3. maze3.txt
- 五、结果分析
- 总结
一、实验内容
- 下载mymaze.py文件maze1.txt,maze2.txt,maze3.txt以及requirements.txt几个文件,将它们放于同一个文件夹中,安装相应的环境定义。
- 读懂文件中所给的类和函数,请按照mymaze.py中的提示,补全代码,执行深度优先搜索和广度优先搜索的代码并对结果进行记录。
二、深度优先搜索和广度优先搜索总结
1.深度优先搜索算法
- 总是先扩展frontier表中最深的结点
- Frontier是一个栈结构——后进先出
2.广度优先搜索算法
- 总是先扩展frontier表中最浅的结点
- Frontier是一个队列结构——先进先出
三、实验代码和用于测试的迷宫
1.实验代码
#!/usr/bin/python
# -*- coding:utf-8 -*-class Node():def __init__(self, state, parent, action):self.state = stateself.parent = parentself.action = actionclass StackFrontier():def __init__(self):self.frontier = []def add(self, node):self.frontier.append(node)def contains_state(self, state):return any(node.state == state for node in self.frontier)def empty(self):return len(self.frontier) == 0def remove(self):if self.empty():raise Exception("empty frontier")else:#please add your code here to get a node from the frontier, according to FIBO#请在下面添加你的代码,从frontier表中按照后进先出的顺序移除一个结点,并将移除的结点给nodenode = self.frontier[-1]#after remove a node ,your frontier should adaptive accordingly#在移除了一个结点后,你的frontier表应该相应的更新del self.frontier[-1]return nodeclass QueueFrontier(StackFrontier):def remove(self):if self.empty():raise Exception("empty frontier")else:#请添加你的代码,按照先进先出的顺序移除结点node = self.frontier[0]#请更新frontier表,使得frontier表为移除了一个结点剩下的结点组成del self.frontier[0]return nodeclass Maze():def __init__(self, filename):# Read file and set height and width of mazewith open(filename) as f:contents = f.read()# Validate start and goalif contents.count("A") != 1:raise Exception("maze must have exactly one start point")if contents.count("B") != 1:raise Exception("maze must have exactly one goal")# Determine height and width of mazecontents = contents.splitlines()self.height = len(contents)self.width = max(len(line) for line in contents)# Keep track of wallsself.walls = []for i in range(self.height):row = []for j in range(self.width):try:if contents[i][j] == "A":self.start = (i, j)row.append(False)elif contents[i][j] == "B":self.goal = (i, j)row.append(False)elif contents[i][j] == " ":row.append(False)else:row.append(True)except IndexError:row.append(False)self.walls.append(row)self.solution = Nonedef print(self):solution = self.solution[1] if self.solution is not None else Noneprint()for i, row in enumerate(self.walls):for j, col in enumerate(row):if col:print("#", end="")elif (i, j) == self.start:print("A", end="")elif (i, j) == self.goal:print("B", end="")elif solution is not None and (i, j) in solution:print("*", end="")else:print(" ", end="")print()print()def neighbors(self, state):row, col = statecandidates = [("up", (row - 1, col)),("down", (row + 1, col)),("left", (row, col - 1)),("right", (row, col + 1))]result = []for action, (r, c) in candidates:if 0 <= r < self.height and 0 <= c < self.width and not self.walls[r][c]:result.append((action, (r, c)))return resultdef solve(self):"""Finds a solution to maze, if one exists."""# Keep track of number of states exploredself.num_explored = 0# Initialize frontier to just the starting positionstart = Node(state=self.start, parent=None, action=None)#please add the frontier of stackfroniter or queuefrontier#请声明栈结构或者队列的frontier实例"""每一次都改的地方!!!"""frontier = QueueFrontier()#frontier = StackFrontier()frontier.add(start)# Initialize an empty explored setself.explored = set()# Keep looping until solution foundwhile True:# If nothing left in frontier, then no pathif frontier.empty():raise Exception("no solution")# Choose a node from the frontier,please finish the sentencenode = frontier.remove()self.num_explored += 1# If node is the goal, then we have a solutionif node.state == self.goal:actions = []cells = []while node.parent is not None:actions.append(node.action)cells.append(node.state)node = node.parentactions.reverse()cells.reverse()self.solution = (actions, cells)return# Mark node as exploredself.explored.add(node.state)# Add neighbors to frontierfor action, state in self.neighbors(node.state):if not frontier.contains_state(state) and state not in self.explored:child = Node(state=state, parent=node, action=action)frontier.add(child)def output_image(self, filename, show_solution=True, show_explored=False):from PIL import Image, ImageDrawcell_size = 50cell_border = 2# Create a blank canvasimg = Image.new("RGBA",(self.width * cell_size, self.height * cell_size),"black")draw = ImageDraw.Draw(img)solution = self.solution[1] if self.solution is not None else Nonefor i, row in enumerate(self.walls):for j, col in enumerate(row):# Wallsif col:fill = (40, 40, 40)# Startelif (i, j) == self.start:fill = (255, 0, 0)# Goalelif (i, j) == self.goal:fill = (0, 171, 28)# Solutionelif solution is not None and show_solution and (i, j) in solution:fill = (220, 235, 113)# Exploredelif solution is not None and show_explored and (i, j) in self.explored:fill = (212, 97, 85)# Empty cellelse:fill = (237, 240, 252)# Draw celldraw.rectangle(([(j * cell_size + cell_border, i * cell_size + cell_border),((j + 1) * cell_size - cell_border, (i + 1) * cell_size - cell_border)]),fill=fill)img.save(filename)"""if len(sys.argv) != 2:sys.exit("Usage: python maze.py maze.txt")"""m = Maze("maze3.txt")
print("Maze:")
m.print()
print("Solving...")
m.solve()
print("States Explored:", m.num_explored)
print("Solution:")
m.print()
m.output_image("maze3_广度优先.png", show_explored=True)
2.测试迷宫
2.1 maze1.txt
#####B#
##### #
#### #
#### ####
A######
2.2 maze2.txt
### #########
# ################### # #
# #### # # # #
# ################### # # # #
# # # # #
##################### # # # #
# ## # # # #
# # ## ### ## ######### # # #
# # # ##B# # # #
# # ## ################ # # #
### ## #### # # #
### ############## ## # # # #
### ## # # # #
###### ######## ####### # # #
###### #### # #
A ######################
2.3 maze3.txt
## #
## ## #
#B # #
# ## ####
A######
四、实验结果
下图中黑色格子代表迷宫中的墙,深红色代表起点,深绿色代表终点,浅红色代表走过的错路,浅绿色代表走到正确的路线。
1. maze1.txt
- 深度优先算法结果
- 广度优先算法结果
2. maze2.txt
- 深度优先算法结果
- 广度优先算法结果
3. maze3.txt
- 深度优先算法结果
- 广度优先算法结果
五、结果分析
- 从完备性角度上分析:深度优先搜索和广度优先搜索都可以找到解。
- 从最优性角度上分析:深度优先搜索不一定能找到最优解,而广度优先搜索可以找到最优解。
- 从时间复杂度角度上分析:深度优先搜索跑了更多的结点所以它的时间复杂度比广度优先搜索高。
- 从空间复杂度角度上分析:广度优先搜索在找到最终结点之前需要记录所有已经走过的结点,所以空间复杂度要高一些。
总结
算法引自——人工智能 一种现代的方法(第3版)
代码源自网络,仅用于教学实验
本文来源于实验报告
迷宫问题 深度优先搜索 广度优先搜索 宽度优先搜索【python】相关推荐
- 广度优先搜索 宽度优先搜索 迷宫问题 最短路径 最少操作 由近及远 队列
广度优先搜索,也叫宽度优先搜索,从开始状态,到第一次能到达的状态,再从第一次能到达的状态到下一个能到达的状态,直到探索所有可到达的状态,其时间复杂度为O(状态数×转移的方式). 广度优先搜索使用了队列 ...
- 层层递进——宽度优先搜索(BFS)
问题引入 我们接着上次"解救小哈"的问题继续探索,不过这次是用宽度优先搜索(BFS). 注:问题来源可以点击这里 http://www.cnblogs.com/OctoptusLi ...
- 深度优先搜索和宽度优先搜索
深度优先搜索和宽度优先搜索 bfs和dfs都是遍历图的方法.dfs是不撞南墙不回头,bfs慢慢来,一层一层来. 类型 空间(h为高度) 时间(h为高度) 采用的数据结构 特点 DFS O(h) O( ...
- BFS(宽度优先搜索、广度优先搜索)
宽度优先搜索算法(又称广度优先搜索)是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型.Dijkstra单源最短路径算法和Prim最小生成树算法都采用了和宽度优先搜索类似的思想.其别名又 ...
- 宽度优先搜索与深度优先搜索
宽度优先搜索算法顺序:1-2-3-4-5-6-7 深度优先搜索算法顺序:1-2-4-5-3-6-7 宽度优先搜索算法(又称广度优先搜索)BFS,属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点 ...
- 深度优先搜索与宽度优先搜索
深度优先搜索 简称:DFS 基本思路 深度优先遍历图的方法是,从图中某顶点v出发: (1)访问顶点v: (2)依次从v的未被访问的邻接点出发,对图进行深度优先遍历:直至图中和v有路径相通的顶点都被访问 ...
- 生成图-深度优先搜索/宽度优先搜索
问题提出: 考虑如下图所示的简单图所表示的缅因州的道路系统.在冬天里保持道路通路通畅的唯一方式就是经常扫雪.高速公路部分希望只扫尽可能少的道路上的雪,而确保总是存在连接任何两个乡镇的干净道路.如何才能 ...
- 广度优先搜索 - 宽度优先搜索 - 横向优先搜索 (breadth-first search,BFS)
广度优先搜索 - 宽度优先搜索 - 横向优先搜索 (breadth-first search,BFS) 1. 广度优先搜索 - 宽度优先搜索 - 横向优先搜索 (breadth-first searc ...
- ACM算法笔记(十)深度优先搜索与宽度优先搜索
深度优先搜索 事实上,深度优先搜索属于图算法的一种,英文缩写为DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次. 下面 ...
- 算法笔记01——深度优先搜索(DFS)/宽度优先搜索(BFS)
深度优先搜索(DFS) 从某个状态开始,不断地转移状态直到无法转移,然后回退到前一步的状态,继续转移到其他状态,如此不断重复,直至找到最终的解.深度优先搜索从最开始的状态出发,遍历所有可以到达的状态. ...
最新文章
- R语言与数据分析(6)-R包的安装
- Linux之Vmware编码
- mysql添加表字段_mysql命令添加表字段
- 微生物 研究_微生物监测如何工作,为何如此重要
- Dubbo 新增本地 IDE 插件,快速创建样例工程
- Keil(MDK-ARM-STM32)系列教程(六)Configuration(Ⅱ)
- jsp,jstl checkbox 回显方法
- 试图将驱动程序添加到存储区_云存储——终于等到你,还好没放弃
- vue 使用 ueditor uparse_vue手把手教学~搭建web聊天室
- 利用DBMS_ROWID.ROWID_CREATE来找出事务等待的行数据
- Delphi的TDataSetProvider、TDataSet、TAdoQuery、TDataSource、TDataModule控件的组合使用
- 【工具用法】Linux登录吉林大学校园网教程(以deepin为例)
- 计算机键盘重复设置,教你操作win10系统电脑键盘打字时总是出现重复字符的方案...
- 实现B站弹幕很难么?这个开源项目了解一下
- 黄褐斑的食疗用什么,姬净美效果不错
- Pycharm下载地址、汉化方法与常用快捷键
- 月薪2千到年薪百万,厂妹到高盛程序员,她书写了一个女孩的史诗
- 国内物联网平台(8):中移物联网开放平台OneNet
- 软碟通UltraISO 9.65.3237官方注册版
- access2000 性能