您的位置:首页 > 其它

(原创)广度优先搜索解决最短路径问题

2017-11-13 20:23 309 查看

一、用途

广度优先搜索用于解决两种问题:
1.从某点到某点是否存在路径?

2.若存在,最短的是哪条?


二、简单介绍图

1.图有点和边组成。

2.当图中的所有边的指向都是单向的,这种图叫做有向图。若A指向B,则B为A的邻居。

3.当图中存在一条或一条以上的没有箭头的边,即A指向B,且B指向A,这种图成为无向图。其中,A和B互为邻居。

4.如下图,其中若从A出发,则B、C、D是一度关系,E、F是二度关系,以此类推。




三、简单介绍队列

1.队列只包括两种操作:入队与出队。

2.队列是一种先进先出的数据结构(First In First Out,FIFO);栈是一种后进先出的数据结构(Last In First Out,LIFO)。


四、广度优先算法实现逻辑

假设要在上图中寻找从A到E的最短路径:

1.将A的一度关系加入搜索队列。

2.判断搜索队列是否为空,是则返回False,表示不存在到E的路径,否则检查队列的第一个点。

2.检查该点是否被搜索过了,是则跳过。否则判断该点是否是E,是则返回true,否则将该点移除,并放入已经搜索过的点的列表,将该点的下一层加入整个待搜索队列的后面。

3.重复第二步。


注意!!

a.要将下一层放在队列的最后面,才能确保找到的是最短路径。

b.检查过的点要放入已经搜索过的队列,并在每次检查时判断该点是否在搜索过的队列里,防止重复搜索。否则当出现无向图时,会进入死循环。

五、运行时间

广度优先搜索的运行时间是:O(V+E)
解析:
广度优先遍历需要在整个图网中进行遍历,所以会遍历每一条边,所以至少运行时间是O(边数),即O(E),E为边数;

而每次遍历一个点,就需要将它的下一层添加到队列,在散列表中添加一个对象是常数时间O(1),所以运行时间还要加上O(节点数),即O(V),V是节点数。

所以最后的运行时间是:O(V) + O(E) = O(V+E)。

六、具体实现

"""
广度优先搜索
"""
dict = {}
dict["oysq"] = ["a", "b", "c"]
dict["a"] = ["e", "f", "g"]
dict["b"] = ["h", "i"]
dict["c"] = []
dict["d"] = []
dict["e"] = []
dict["f"] = []
dict["g"] = []
dict["h"] = ["j", "k"]
dict["i"] = []
dict["j"] = []
dict["k"] = ["l"]
dict["l"] = []

def search(dict, head, target):
search_list = []
search_list += dict[head]
searched = []
while search_list != []:
temp = search_list.pop()
if searched.count(temp) == 0:
if temp == target:
return True;
else:
search_list += dict[temp]
searched += temp
return False

print search(dict, "oysq", "c")
print search(dict, "oysq", "v")


欢迎大家评价交流!!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: