簡體   English   中英

C#圖遍歷 - 跟蹤任意兩個節點之間的路徑

[英]C# graph traversal - tracking path between any two nodes

尋找一種好方法來跟蹤兩個節點之間的廣度優先遍歷,而不了解圖形的任何信息。 與深度優先(如果它沒有平移你可以扔掉路徑)你可能在遍歷期間有很多“開放”的可能性。

天真的方法是構建一個樹,源節點作為根,所有連接作為子節點。 根據您擁有的空間量,您可能需要隨時消除周期。 您可以使用位圖執行此操作,其中每個位對應於圖中的不同節點。 當您到達目標節點時,您可以按照父鏈接返回到根目錄,這是您的路徑。 由於您首先要求廣泛,即使您沒有消除周期,也可以確保它是最短的路徑。

對於廣度優先搜索,您需要存儲至少兩件事。 一個是已訪問過的節點集,另一個是可以從受訪節點直接訪問但不會自己訪問的節點集。 然后你繼續將狀態從后一組移動到前者,向后者添加新的可達狀態。 如果您需要具有從根到某個節點的路徑,那么您還需要在上述集合中為每個節點(根除了)存儲父節點。

通常,訪問節點集合和未訪問子節點集合(即,所見節點集合)的並集存儲在哈希表中。 這是為了能夠快速確定之前是否已經看到“新”狀態,如果是這種情況則忽略它。 如果你有很多狀態,你可能確實需要一個位數組(如Joseph Bui( 57509 )所述),但除非你的狀態可以(直接或間接)用作該數組的索引,否則你需要使用一個哈希函數將狀態映射到索引。在后一種情況下,您可能完全忽略某些狀態,因為它們映射到與不同(和看到的)節點相同的索引,因此您可能需要小心這一點。另外,要獲取路徑你仍然需要存儲父信息,它幾乎否定了比特數組的使用。

未訪問但看到的節點集可以存儲為隊列。 (位數組對於此集合沒有用處,因為數組將基本為空,並且找到下一個設置位相對昂貴。)

我剛剛提交了一份解決方案在這里也適用於這個問題。

基本上,我只保留一個訪問節點的列表(真正的堆棧)。 在遞歸或保存解決方案之前,將節點添加到列表中。 始終直接從列表中刪除。

如果您使用的是.NET 3.5,請考慮使用Hashset來防止重復節點被擴展,這會在圖形中出現循環時發生。 如果您對圖的內容有任何了解,請考慮實施A *搜索以減少擴展的節點數。 祝你好運,我希望它適合你。

如果你仍然是樹木的粉絲,那么有許多關於圖形和圖形搜索主題的優秀書籍,例如Peter Norvig和Stuart Russell的人工智能:現代方法。

我的回復中的鏈接似乎有一個他們是Hashset的錯誤: http ://msdn.com/en-us/library/bb359438.aspx和A * search: http//en.wikipedia.org/wiki/A* _search_algorithm

暫無
暫無

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

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