宽度优先搜索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依次放入队列,标记为已访问


直到队列为空,后面操作重复,不再赘述。

# -*- 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()
代码中的图如下:

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/24024.html