給定一個循環圖,我正在尋找一個將此圖分解爲非循環子圖的算法。這些子圖中的每一個都有一個根頂點,這個頂點是計算最短路徑的源。例如,下面給出的循環圖,其中,所述週期是3,4之間,和5:將循環圖分解爲最短路徑子圖的最小數目
+-------------------------+
| |
| |
+----------+----------+ |
v | v |
+---+ +---+ +---+ +---+ +---+ |
| 1 | --> | 3 | <--> | 4 | <--> | 5 | --> | 6 | |
+---+ +---+ +---+ +---+ +---+ |
^ |
| |
| |
+---+ |
| 2 | |
+---+ |
+---+ |
| 7 | <---------------------+
+---+
相對於最短路徑的子圖1是:
+---+ +---+ +---+ +---+
| 1 | --> | 3 | --> | 4 | --> | 7 |
+---+ +---+ +---+ +---+
|
|
v
+---+ +---+
| 5 | --> | 6 |
+---+ +---+
最短路徑的子圖相對於2將是:
+---+
| 7 |
+---+
^
|
|
+---+ +---+ +---+ +---+
| 2 | --> | 4 | --> | 5 | --> | 6 |
+---+ +---+ +---+ +---+
|
|
v
+---+
| 3 |
+---+
相對於最短路徑sugraph至5將是:
+---+ +---+ +---+ +---+
| 6 | <-- | 5 | --> | 4 | --> | 7 |
+---+ +---+ +---+ +---+
|
|
v
+---+
| 3 |
+---+
注意,關於3的最短路徑子圖是1的子集,4是2的子集。 6和7是葉子。
我目前的(天真的)解決方案將是爲每個節點執行一個BFS,標記節點訪問以防止週期。然後檢查子圖是否是彼此的子集以創建最小數量的不同子圖。任何更好,更正式的解決方案的想法?
編輯在我的情況圖是不加權的,但有後人的一般解決方案是很好的。
(與http://bloodgate.com/graph-demo由圖)
@食譜 - 我發現一篇論文,有人想出了一個非常快的APSP算法,並將其添加到我的答案中。另外,我對你的算法有點懷疑,因爲我不認爲你的「包含」的定義必然是正確的。僅僅因爲你可以達到與v相同的一組頂點,並不意味着v中的BFS樹將被包含在U的BFS樹中。或者我錯了嗎? – templatetypedef
@templatetypedef我說:「顯然你只包含v_only if_ ...」,不是當且僅當。換句話說,可能有從u到v的路徑,但是u不包含v。在第二階段中將誤報消除。另外,您鏈接的論文是關於節省時間的;如果OP仍然願意運行所有的BFS,那麼似乎時間不是問題,但只有OP可以肯定地告訴我們。 – comestibles
@食品 - 啊,我的錯誤,我誤解了。回顧一下,看起來在最糟糕的情況下,你需要運行O(n)不同的BFS迭代,這會得到O(n(n + m))= O(n^2 + nm)的運行時間, ,其中m = o(n log n)的圖比迭代的Dijkstra更好,對於m = o(n^2)的圖更好於Floyd-Warshall。非常好! – templatetypedef