python 广度优先搜索算法理解和实现

  • 一 .相关概念及学习的意义

       广度优先搜索的官方概念,请自行搜索查阅,这里仅做剖析帮助理解。

[1]意义

       学习算法,首先一定要搞清楚每种算法使用的具体场景,主要解决什么问题的,这是学以致用的前提条件。广度优先搜索主要解决2个问题:

       1.起点到终点是否有路径;2.起点到终点最短路径,这点需要简单说明下,所谓最短指的分段最少,而不考虑每段的距离多长,是假设每个分段距离相等而言。当然如果考虑分段距离,那属于另外一种算法,这里先提个概念:迪克斯拉特算法,是一种加权算法。    

        在实际应用中应用非常广发,比如计算网络跳点,人工智能跳棋设计等。广度优先搜索(Breadth-first search,简称BFS)是基于图这种数据结构的其中一种普通使用的算法。

        [2]图(Grapth)

        是对树的一种扩展。在计算机科学技术范畴中,图是一种应用非常广泛的数据结构,如人脉关系中一度,二度等人脉,族谱关系等。要了解和使用BFS解决实际问题,就要对图有个初步了解,图分无向图有向图。图是有一系列的顶点和边组成。 

         python 广度优先搜索算法理解和实现_第1张图片

图1:无向图:意味着三个城市之间可以互通,如果加了箭头,则为有向图,表明城市之间是无法往返的。

python 广度优先搜索算法理解和实现_第2张图片

图2:有向图,带有箭头,表明师徒关系,如果去掉箭头就乱了辈分了

        [3]图的Python实现

         对图有个基本了解以后,那么怎么用计算机科学表示呢,看下面这个有向图。

python 广度优先搜索算法理解和实现_第3张图片图3:有向图

       现在我们通过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的灵活所在。

         本例子遍历的顺序是,如图:

python 广度优先搜索算法理解和实现_第4张图片图4:遍历次序

          代码片段如下:          

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])#倒序打印出来节点列表 

           本例最终代码调用顺序及输出的最短路径,见下图:

python 广度优先搜索算法理解和实现_第5张图片

       总结:1.学习算法一定要了解算法的实际应用场景,是解决什么问题的;2.广度优先搜索是基于图,所以首先要了解图的相关概念,分类;3.第一阶段是看别人代码,第二阶段自己写代码,第三阶段举一反三,模拟一个实际应用进行编码实现,最终才能使用算法

====================  =================完=======================================================

 

         

 

 

       

你可能感兴趣的:(python 广度优先搜索算法理解和实现)