2017-05-04 83 views
1

所以,我有這張圖,我想使用廣度優先搜索算法來查看是否存在從頂點到另一個頂點的路徑。這是一個廣度優先的搜索算法嗎?

Cool sketch of a graph

所以,我實現了Python中的功能取決於通路的存在,它返回true或false,和它的作品。那麼,它爲我做的測試工作。我想知道的是,如果這確實是一個呼吸優先的搜索算法。我以前沒有見過任何BFS算法,我只知道它的基本思想。聽說BFS遞歸實現,但我實現它反覆,這就是爲什麼我對it.So疑惑,這裏都是功能和我圖的表示:

outb = {1: [2, 3], 
    2: [4, 5], 
    3: [5, 11, 12], 
    4: [6, 7], 
    5: [7], 
    6: [9, 10], 
    7: [8], 
    11: [3], 
    12: [15, 14, 13], 
    13: [17], 
    14: [17], 
    15: [12, 5, 8, 16], 
    17: [18]} 

def BFS(v1, v2): 
    parsed = [] 
    toParse = [v1] 
    current = v1 

    while len(toParse) > 0: 

     while current in parsed: 
      current = toParse.pop(0) 

     if current not in outb: 
      return False 

     if v2 in outb[current]: 
      return True 

     toParse += outb[current] 
     parsed.append(current) 

    return False 

而且我是最後一個問題:從本質上講,BFS是否找到了從頂點到另一個頂點的最短路徑?我在網上閱讀這個東西,我想確定。

+0

閱讀[wikipedia page](https://en.wikipedia.org/wiki/Breadth-first_search)。它看起來像你的代碼在那裏執行算法,它表明BFS找到最短路徑。 – Barmar

+0

比較你的代碼和維基百科中的僞代碼,S == parsed,Q == toParse,current == current。 – Barmar

+0

你的代碼是一個BFS,但它也是錯誤的,因爲'current not in outb'並不意味着沒有路徑,並且你試圖做'toParse.pop(0)'而不考慮'toParse'是否真的有元素。而且,對於大多數使用的數據結構,列表並不是一個有效的選擇。 – user2357112

回答

1

這是一個廣度優先搜索。它遵循相當典型的結構,將搜索邊界視爲隊列(儘管列表對於隊列來說是一個低效的選擇),並且它按照距離根的距離來排列節點,就像標準的廣度優先搜索一樣。

但是,這也是錯誤的。 0123'終止條件導致它wrongly output FalseBFS(1, 18)搜索和while current in parsed: current = toParse.pop(0)循環可以耗盡toParse並拋出一個異常,當它試圖從一個空的列表中彈出,demonstrated here與略有不同的圖形。此外,您的outb與它應該表示的圖形圖片不匹配;它缺少一堆後端邊緣,例如6-> 4。

+0

因此,如果我要糾正這些錯誤和圖形表示,它可以被認爲是一個「合法的」BFS算法? – Xyntell

+1

@Xyntell:我已經認爲它是一個BFS,但它不是你想要的BFS。 – user2357112

+0

好的。得到它了!感謝您的迴應。 – Xyntell

1

這是一個BFS算法,用於查找是否存在路徑,但它不會告訴您該路徑是什麼,也不會說明您的字典用於表示圖形的方式。

下面是上圖的BFS示例,它可以處理字典代表圖形的方式。它找到一個時返回路徑,當路徑不存在時返回False。如果你只是希望它返回True當它找到一個路徑,編輯一行19 return True

def BFS2(graph, v1, v2): 
    ''' 
    graph: a dictionary representing an unweighted graph 
    v1: a key in graph, representing the start node 
    v2: a key and value in graph, representing the end node 
    returns: a shortest path from v1 to v2, False if there is no path. 
    ''' 
    if v1 not in graph: 
     return False 
    path_start = [v1] 
    paths = [path_start] 
    while len(paths): 
     test_path = paths.pop(0) 
     last_node = test_path[-1] 

     for next_node in graph[last_node]: 
      if next_node not in test_path: 
       next_path = test_path + [next_node] 
       if next_node == v2: 
        paths.append(next_path) 
        return next_path 
       elif next_node in graph: 
        paths.append(next_path) 
    return False 
+1

沒有要求BFS必須實際返回路徑。搜索是否是廣度優先搜索只是搜索結構的一個屬性,而不是它輸出的內容。 – user2357112

+1

@ user2357112明白了。謝謝!看起來我需要重新審視我的圖論。編輯以反映這一點。 –

+0

更好,但你的實現是越野車。如果'v1'沒有外出邊緣,並且由於它不使用訪問集合,它會執行指數級的冗餘工作。 (試圖使用路徑作爲訪問集合並不會阻止它冗餘地考慮指向相同節點的許多不同路徑。) – user2357112