BFS-宽度优先搜索(Python)

宽度优先搜索BFS
~工作方式:
从根节点开始,由里向外,逐层遍历所有节点——它每次总是扩展深度最浅的节点。
~缺点:在树的层次较深&子节点数较多的情况下,消耗内存十分严重。
~适用情况:节点的子节点数量不多,并且树的层次不会太深的情况。
~简单举例:BFS方法,从根节点1开始,下图遍历顺序是:1,2,3,4,5,6
在这里插入图片描述
优先访问深度最浅的节点,故,老节点总是优先于新节点被访问,因此,我们可以使用队列来管理节点。
BFS算法的工作原理如下:
1.将根节点放入队列
2.重复以下,直到队列为空
{
2.1 取出队列头的点
2.2 找出与该点相邻并没有被访问的节点,标记后依次放入队列
}

图可以采用二维数组或者邻接表来保存

下面,我将用图来展示BFS算法的工作过程:
在这里插入图片描述
1.将起始节点1放入队列,进行标记
在这里插入图片描述
在这里插入图片描述
2.从队列取出头节点1,找到与该节点邻接的节点,依次放入队列,标记为已访问
在这里插入图片描述
在这里插入图片描述
3.取出队列头节点2,找到与2节点邻接的节点1,5,6。节点1已被访问,将节点5,6依次放入队列,标记为已访问
在这里插入图片描述
在这里插入图片描述
直到队列为空,后面操作重复,不再赘述。

以下用两种方式实现BFS算法:
1.队列的方式

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

#BFS算法的队列实现

from Queue import Queue
from Stack import Stack
from simplegraph import *

def BFS(G,v,goal,came_from):#G为导入的图;v为起始节点;goal为目标节点;
    frontier=Queue()
    frontier.enqueue(v)
    came_from[v]=None
    visited={}
    while not frontier.is_empty():#队列不为空
        v=frontier.dequeue()#将节点v取出队列
        if visited.get(v)==None:#判断节点v是否被访问过
            if v==goal:
                return v
            else:
                visited[v]=True#节点v被访问
                for w in G.adjacentEdges(v):#依次取节点v的相邻节点w
                    frontier.enqueue(w)#将v相邻节点放入队列
                    came_from[w]=v
    return None


def main():
    came_from = {}
    start = '1'
    goal = '12'
    found = BFS(G1,start,goal,came_from)
    print('start:',start)
    print('goal:',goal)
    if found != None:
        s = Stack()
        s.push(found)
        found = came_from.get(found)
        while found != None:
            s.push(found)
            found = came_from.get(found)
        while not s.is_empty():
            print(s.pop(),end='-')
        print('end')
    else:
        print('Path not found!')
        

if __name__ == '__main__':
    main()
# -*- coding: utf-8 -*-

#Stack类,Stack类实现简单的栈

class Stack:
    def __init__(self):
        self.items = []
        
    def push(self,item):
        self.items.append(item)
        
    def pop(self):
        return self.items.pop()
    
    def is_empty(self):
        return self.items == []
    
    def peek(self):
        return self.items[-1]
    
    def top(self):
        return self.items[-1]
    
    def size(self):
        return len(self.items)
    
def main():
    s = Stack()
    print(s.is_empty())
    s.push(1)
    s.push(2)
    s.push(3)
    s.push(4)
    print(s.size())
    print(s.top())
    print(s.is_empty())
    while not s.is_empty():
        print(s.pop())
        
if __name__ == '__main__':
    main()
class SimpleGraph:
    def __init__(self):
        self.edge = {}
        
    def adjacentEdges(self,v):
        return self.edges[v]
    
G1 = SimpleGraph()
G1.edges = {
    '1' : ['2','3','4'],
    '2' : ['5','6'],
    '3' : [],
    '4' : ['7','8'],
    '5' : ['9','10'],
    '6' : [],
    '7' : ['11','12'],
    '8' : [],
    '9' : [],
    '10': [],
    '11': [],
    '12': []
}
# -*- coding: utf-8 -*-

class Queue:
    def __init__(self):
        self.items=[]
        
    def enqueue(self,item):
        self.items.insert(0,item)
        
    def dequeue(self):
        return self.items.pop()
    
    def is_empty(self):
        return self.items == []
    
    def size(self):
        return len(self.items)
    
def main():
    q = Queue()
    q.enqueue(1)
    q.enqueue(2)
    q.enqueue(3)
    q.enqueue(4)
    q.enqueue(5)
    print(q.size())
    while not q.is_empty():
        print(q.dequeue())
    print(q.size())
    
if __name__ == '__main__':
    main()

2.BFS算法的OPEN-CLOSED实现

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

#BFS算法的OPEN-CLOSED实现

from Stack import Stack
from simplegraph import *

def BFS(G,v,goal,came_from):
    open = [v]
    closed = []
    came_from[v] = None
    while len(open) != 0:
        v = open.pop(0)
        if v == goal:
            return v
        else:
            closed.append(v)
            for w in G.adjacentEdges(v):
                if w not in closed:
                    open.append(w)
                    came_from[w] = v
    return None

def main():
    came_from = {}
    start = '1'
    goal = '12'
    found = BFS(G1,start,goal,came_from)
    print('start:',start)
    print('goal:',goal)
    if found != None:
        s = Stack()
        s.push(found)
        found = came_from.get(found)
        while found != None:
            s.push(found)
            found = came_from.get(found)
        while not s.is_empty():
            print(s.pop(),end = '-')
        print('end')
    else:
        print('Path not found!')
        
if __name__ == '__main__':
    main()

代码中的图如下:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值