簡體   English   中英

圖中2個節點之間的所有路徑

[英]All the paths between 2 nodes in graph

我必須進行一個不知情的搜索(廣度優先搜索)程序,它接受兩個節點並返回它們之間的所有路徑。

public void BFS(Nod start, Nod end) {
            Queue<Nod> queue = new Queue<Nod>();
            queue.Enqueue(start);
            while (queue.Count != 0)
            {
                Nod u = queue.Dequeue();
                if (u == end)  break;
                else
                {
                    u.data = "Visited";
                    foreach (Edge edge in u.getChildren())
                    {
                        if (edge.getEnd().data == "")
                        {
                            edge.getEnd().data = "Visited";
                            if (edge.getEnd() != end)
                            {
                                edge.getEnd().setParent(u);
                            }
                            else
                            {
                                edge.getEnd().setParent(u);
                                cost = 0; 
                                PrintPath(edge.getEnd(), true);
                                edge.getEnd().data = "";
                                //return;
                            }
                        }
                        queue.Enqueue(edge.getEnd());
                    }
                }
            }
        }

我的問題是,我只獲得兩條路徑,而不是所有路徑,我不知道在我的代碼中編輯什么來獲取它們。 我的問題輸入基於這張地圖: 地圖

廣度優先搜索是生成所有可能路徑的一種奇怪方式,原因如下:您需要跟蹤BFS中的每個單獨路徑是否已遍歷該節點,而不是完全遍歷該節點。

舉一個簡單的例子

1----2
 \    \
  3--- 4----5

我們想要從1到5的所有路徑。我們排隊1,然后是2和3,然后是4,然后是5.我們已經失去了通過4到5的兩條路徑的事實。

我建議嘗試用DFS來做這件事,盡管這可能是BFS可以解決的問題。 排隊的每個東西都是路徑,而不是單個節點,因此可以看到該路徑是否訪問過每個節點。 如此,這是浪費的記憶

在BFS算法中,您必須在找到解決方案后停止。 一個想法是為你訪問過的所有城市設置數據null,除了第一個,讓函數運行一點點。 我沒有時間給你寫一個片段但是如果你沒有得到它我會寫至少一個偽代碼。 如果你不理解我的想法發表你的問題的評論,我會嘗試更好地解釋。

路徑是一系列頂點,其中沒有頂點重復多次。 根據這個定義,你可以編寫一個遞歸算法,它應該按如下方式工作:將四個參數傳遞給函數,稱之為F(u, v, intermediate_list, no_of_vertices) ,其中u是當前源(當我們遞歸時它將改變) , v是目的地, intermediate_list是一個最初應為空的頂點列表,每次我們使用頂點時,我們都會將它添加到列表中,以避免在路徑中多次使用頂點,而no_of_vertices是我們想要找到的路徑的長度,其下限應為2 ,上限由V (頂點數)限定。 本質上,該函數應返回一個路徑列表,其源為u ,目標為v ,每個路徑的長度為no_of_vertices 創建一個初始空列表並調用F(u, v, {}, 2), F(u, v, {}, 3), ..., F(u, v, {}, V) ,每個時間將F的輸出與我們打算存儲所有路徑的列表合並。 嘗試實現這一點,如果你仍然遇到麻煩,我會為你編寫偽代碼。

編輯:使用BFS解決上述問題:廣度優先搜索是一種可用於探索圖形的所有狀態的算法。 您可以使用BFS瀏覽給定圖形的所有路徑的圖形,並選擇所需的路徑。 對於每個頂點v ,將以下狀態添加到隊列中: (v, {v}, {v}) ,其中每個狀態定義為: (current_vertex, list_of_vertices_already_visited, current_path) 現在,當隊列不為空時,彈出隊列的頂部元素,對於current_vertex每個邊e ,如果list_of_vertices_already_visited已經存在尾部頂點x ,則推送新狀態(x, list_of_vertices_already_visited + {x}, current_path -> x)到隊列,並在將其從隊列中彈出時處理每個路徑。 通過這種方式,您可以搜索圖表的整個路徑圖,無論是定向還是無向。

聽起來像是家庭作業。 但有趣的是那種。

以下是偽代碼,首先是深度而不是先呼吸(所以應該轉換為隊列類型算法,並且可能包含錯誤,但是一般的jist應該是清楚的。

class Node{
  Vector[Link] connections;
  String name;
}

class Link{
  Node destination;
  int distance;
}

Vector[Vector[Node]] paths(Node source, Node end_dest, Vector[Vector[Node]] routes){
  for each route in routes{
    bool has_next = false;
    for each connection in source.connections{
      if !connection.destination in route {
        has_next = true;
        route.push(destination);
        if (!connection.destination == end_dest){
          paths(destination, end_dest, routes);
        }
      }
    }
    if !has_next {
      routes.remove(route) //watch out here, might mess up the iteration
    }
  }
  return routes;
}

編輯:這實際上是您正在尋找的問題的答案嗎? 或者你真的想找到最短路徑? 如果是后者,請使用Dijkstra的算法: http//en.wikipedia.org/wiki/Dijkstra%27s_algorithm

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM