广度优先搜索的官方概念,请自行搜索查阅,这里仅做剖析帮助理解。
[1]意义
学习算法,首先一定要搞清楚每种算法使用的具体场景,主要解决什么问题的,这是学以致用的前提条件。广度优先搜索主要解决2个问题:
1.起点到终点是否有路径;2.起点到终点最短路径,这点需要简单说明下,所谓最短指的分段最少,而不考虑每段的距离多长,是假设每个分段距离相等而言。当然如果考虑分段距离,那属于另外一种算法,这里先提个概念:迪克斯拉特算法,是一种加权算法。
在实际应用中应用非常广发,比如计算网络跳点,人工智能跳棋设计等。广度优先搜索(Breadth-first search,简称BFS)是基于图这种数据结构的其中一种普通使用的算法。
[2]图(Grapth)
是对树的一种扩展。在计算机科学技术范畴中,图是一种应用非常广泛的数据结构,如人脉关系中一度,二度等人脉,族谱关系等。要了解和使用BFS解决实际问题,就要对图有个初步了解,图分无向图和有向图。图是有一系列的顶点和边组成。
图1:无向图:意味着三个城市之间可以互通,如果加了箭头,则为有向图,表明城市之间是无法往返的。
图2:有向图,带有箭头,表明师徒关系,如果去掉箭头就乱了辈分了
[3]图的Python实现
对图有个基本了解以后,那么怎么用计算机科学表示呢,看下面这个有向图。
现在我们通过Python的字典Dict类型来表示这个图,这里需要说明下,注意两点:1.要了解BFS,就要对队列有所了解,队列:先进先出,是有序的,广度优先搜索就是解决最短路径问题,当然要知道谁先到达终点;2.为什么要用字典呢,字典是无序的,这里无序是针对顶点的,初始化顶点是没有先后要求的。
代码片段如下:
from collections import deque
def data_ini():
grapth={}
grapth["A"]=["B","C"]
grapth["B"]=["D"]
grapth["C"]=["F"]
grapth["D"]=["E","F"]
grapth["E"]=["F","G"]
grapth["F"]=["H"]
grapth["G"]=["H"]
return grapth
if __name__=="__main__":
grapth=data_ini()
print(grapth)
如上2点所说,从A点出发B,C两点谁先谁后没有关系。
[4]BFS算法实现
逻辑思想:第一层(一度 A)从起点开始遍历每一条出去的顶点,至于先遍历B还是C则没有影响,如果找不到终点H,则把当前顶点推入待遍历队列尾部),例子中把起点一开始就推入队列中,因为起点肯定不是终点;第二层(二度B和C)遍历B点或C点出去的临近节点,发现B点的临近节点D,也不是我们要找的终点H,则把B推入待遍历队列尾部,接着遍历同样是二度节点的C。依次类推,重点是同一度的节点遍历完才会遍历下一度的节点,这是BFS的灵活所在。
本例子遍历的顺序是,如图:
代码片段如下:
def search(start,end,grapth):
seach_deque=deque()
seach_deque+=graph[start]
searched=[start]
while seach_deque:
person=seach_deque.popleft()
if node not in searched:
if node==end:#start<>end
searched.append(end)
return searched
else:
seach_deque+=graph[node]
searched.append(node)
return False
我们再编写一个函数,用来打印出遍历路径节点 ,从BFS遍历路径中找出最短路径,方法: 从循环从路径中遍历,直到找出哪个节点包含了终点,然后向上再遍历哪个父节点包含了该节点,然后倒序输出。
def print_bfs_path(start,end,lst,grapth):
path=[start]
pointer=end
while pointer!=start:
for node in lst:
if pointer in grapth[node]:
pointer=node
path.append(node)
break
print(path[::-1])#倒序打印出来节点列表
本例最终代码调用顺序及输出的最短路径,见下图:
总结:1.学习算法一定要了解算法的实际应用场景,是解决什么问题的;2.广度优先搜索是基于图,所以首先要了解图的相关概念,分类;3.第一阶段是看别人代码,第二阶段自己写代码,第三阶段举一反三,模拟一个实际应用进行编码实现,最终才能使用算法。
==================== =================完=======================================================