[Python] 广度优先搜索

广度优先搜索主要解决两个方面的问题:

  • 存不存在路径的问题(例如,从A点是否可以达到B点)
  • 无权重的最短路径问题(例如,从A点到B点的最短路径)

Graph Data Structure的表示

在这里插入图片描述
上面这种图可以用Python表示为:

# sample graph implemented as a dictionary
graph = {'A': ['B', 'C', 'E'],
         'B': ['A','D', 'E'],
         'C': ['A', 'F', 'G'],
         'D': ['B'],
         'E': ['A', 'B','D'],
         'F': ['C'],
         'G': ['C']}

FIFO队列

在这里插入图片描述

BFS分层

类似通讯录一样,BFS搜索最短路径时,是按层级进行检索在这里插入图片描述

先解决存不存在的问题

# -*- coding:utf-8 -*-

# TODO: 解决路径显示的问题

# deque函数用来创建一个双端队列
from collections import deque

# -----------------
# 使用字典来表示图
# graph = {}
# key 代表当前节点标识(例如可以是反映名字的string)
# value 代表与该节点相关的下一层节点列表
# Example:
# graph = [1:[4,2],2:[3,4],3:[4],4:[5],5:[]]


def BFS_Search(graph,startNode,stopNode):
    # 创建一个待处理节点的队列
    search_queue = deque()
    # 将起始节点的下一层节点加入到待处理队列中
    search_queue += graph[startNode]
    # 创建一个检索过的列表,避免出现节点间的相互添加
    searched = [startNode]
    # 当队列不为空时
    while search_queue:
        # 从队列中取出要处理的节点
        currentNode = search_queue.popleft()
        # 保证只对未处理过的节点进行判断
        # Ex: A的下一层包含B,B的下一层又包含A
        if currentNode not in searched:
            # 这里写具体的终止条件
            # if 满足终止条件后return True
            if currentNode == stopNode:
                searched.append(stopNode)
                return True
            else:
                # else如果当前节点没有满足终止条件
                # 则将当前节点的下一层节点加到队列尾部
                search_queue += graph[currentNode]
                # 将检查过的节点加入到searched列表中
                searched.append(currentNode)
    return False


# Example One 从你身边的人脉网中找一个叫Tom的人
graph = {}
graph["Sprinkle"] = ["Alice","Claire","Bob"]
graph["Claire"]=["Sprinkle"]
graph["Alice"] = ["Peggy"]
graph["Bob"] = ["Sprinkle","Peggy","Tom"]
graph["Peggy"] =[]
graph["Tom"] = []

searched = BFS_Search(graph, "Sprinkle","Tom")

print(searched)

再解决最短路径的问题

# -*- coding:utf-8 -*-

# TODO: 解决路径显示的问题

# deque函数用来创建一个双端队列
from collections import deque

# -----------------
# 使用字典来表示图
# graph = {}
# key 代表当前节点标识(例如可以是反映名字的string)
# value 代表与该节点相关的下一层节点列表
# Example:
# graph = [1:[4,2],2:[3,4],3:[4],4:[5],5:[]]


def BFS_Search(graph,startNode,stopNode):
    # 创建一个待处理节点的队列
    search_queue = deque()
    # 将起始节点的下一层节点加入到待处理队列中
    search_queue += graph[startNode]
    # 创建一个检索过的列表,避免出现节点间的相互添加
    searched = [startNode]
    # 当队列不为空时
    while search_queue:
        # 从队列中取出要处理的节点
        currentNode = search_queue.popleft()
        # 保证只对未处理过的节点进行判断
        # Ex: A的下一层包含B,B的下一层又包含A
        if currentNode not in searched:
            # 这里写具体的终止条件
            # if 满足终止条件后return True
            if currentNode == stopNode:
                searched.append(stopNode)
                return searched
            else:
                # else如果当前节点没有满足终止条件
                # 则将当前节点的下一层节点加到队列尾部
                search_queue += graph[currentNode]
                # 将检查过的节点加入到searched列表中
                searched.append(currentNode)
    return False

def BFS_ShortestPath(graph,startNode,stopNode):
    searched = BFS_Search(graph,startNode,stopNode)
    path = [stopNode]
    # 当起始节点与目标节点不同时
    while stopNode != startNode:
        # 对检索过的节点进行遍历
        for node in searched:
            # 先找包含了目标节点的上一级节点
            if stopNode in graph[node]:
                # 将上一级节点加到stopNode之前
                path.insert(0, stopNode)
                # 将目标节点更换为node
                stopNode = node
                break
    return path


# Example One 从你身边的人脉网中找一个叫Tom的人
graph = {}
graph["Sprinkle"] = ["Alice","Claire","Bob"]
graph["Claire"]=["Sprinkle"]
graph["Alice"] = ["Peggy"]
graph["Bob"] = ["Sprinkle","Peggy","Tom"]
graph["Peggy"] =[]
graph["Tom"] = []

path = BFS_ShortestPath(graph,"Sprinkle","Tom")
print(path)

举个例子

< Python Breath First Search Maze solving program > 未完,挖坑再补

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值