簡體   English   中英

給定無向圖時,一個接一個地刪除邊驗證刪除的一個是否是橋,如果是 - 兩個部分的頂點

[英]Given undirected graph when removing edges one-by-one verify if removed one was a bridge and if so - the vertices of both parts

我正在為這個特定問題尋找一種時間有效的算法:

我有多達 10,000 個頂點和大約 1-10 條邊的給定頂點的無向圖。

現在我將從圖中刪除選定的邊,我想知道我剛剛刪除的邊是否是一座橋 - 如果是,那么兩邊連接的頂點是什么。 我會經常重復刪除邊緣的步驟,可能直到我得到 10 000 個斷開的頂點(每次我需要橋的信息時)。 因此,例如,最后一條邊應該告知它是一座橋,一側有一個頂點,另一側有一個頂點。

數據的預處理是完全可以接受的,memory 的成本——在現代 PC 的合理范圍內——還可以。 我正在尋找一種優化邊緣去除操作時間的算法。

我的交易工具是 C#,但我很樂意接受任何偽代碼或想法

在文獻中研究了這個問題的一個近親,名稱為“ 遞減連通性”。 主要區別在於您希望枚舉新連接的組件,而不是能夠回答連接查詢。

這篇論文似乎是藝術的理論 state,但略讀后,我認為新想法對你沒有用,因為你有一個圖表

  • 可能太小而無法發揮漸近優勢
  • 就在那個大小,它具有良好的表示,適合 L1 緩存,但足夠大,你也不能適應花哨的數據結構。

我的建議是 Even--Shiloach 的簡化版本,其中省略了 BFS 部分(它增加了復雜性和 memory 消耗,但在稀疏圖中似乎並沒有明顯獲勝)。 這個想法是保持

  • 殘差圖
  • 殘差圖的生成森林
  • 從頂點到代表連接組件的標簽的 map。

如果不在森林中的邊緣被刪除,那么我們只需將其刪除。 否則,我們選擇剛剛被切割的樹的一側(對於哪一側的正確性無關緊要,但您想要較小的一側以提高效率;我建議生根生成樹並使用子樹),遍歷它以臨時更新它label 到新的東西,然后掃描它的所有邊以確定剛剛刪除的邊是否是樹的 rest 的橋。 如果是,那就太好了; 遍歷另一棵新樹以報告頂點集。 否則,我們必須修復標簽和樹結構。

對於數據結構,我推薦一個緊湊的鄰接表。 由於最多有 10,000 個節點,因此節點索引將適合 16 位的short 不幸的是,最多有 100,000 個半邊,所以我們將使用 32 位int來表示邊索引。 我們使用一個int數組指向一個short數組; 條目2*v是節點v的鄰接列表的開頭,條目2*v+1是結尾。 對於緩存位置,我們在鄰接列表旁邊存儲了兩條額外的數據:連接的組件 label 和生成林中的后代數量。 在其他鄰居之前訂購跨越森林的后代。

總的來說,這是在一個簡單的圖表上的樣子:

Graph:
   0
  / \
 /   \
1-----3     2

Spanning forest:
   0
  /
 /
1-----3     2

Arrays:
[|   |   |   |   |   |   |   |  ]
 |   |   |    \  |   |   |   |
 |   |   |     \  \  |   |    \
 |    \   \     \  | |   |     |
 v     v   v     v v v   v     v
[0 1 1 3 x 0 1 3 0 2 0 x 0 0 0 1]
           ^ ^ \ /
           | |  |
           | |  adjacency list; descendants (3) before others (0)
           | |
           | number of spanning forest descendants
           |
           connected component label
             = root of tree in spanning forest

我留下x s 來表示之前從02刪除的邊。

(我對 C# 沒有太多經驗,因此強制邊界檢查可能會成為問題,但我無法想象指針會更好,尤其是在 64 位機器上。)

暫無
暫無

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

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