我有一個DAG。我有這個操作來在兩個節點之間添加一條邊。添加邊緣以指導其他限制的無環圖
如果A可以從B到達,那麼B是A的父親。如果A不需要經過另一個節點就可以從B到達,那麼B就是A的直接父節點。
對於該曲線圖的要求是:
- 沒有循環。
- 對於任何節點,都有一個直接父節點P [1],P [2],P [3] ...的列表。對於任何i和j,P [i]不是P [j]的父親。
如果添加一條邊,不滿足要求1,則不構造邊。 如果添加邊,則不滿足要求2,則會構建邊,但直接父項將以符合要求2的方式進行修改。
例如,有3個節點
- A,直接父母:無
- B,直接父母:甲
- C,直接父母:甲
現在,如果我在B和C之間加了一條邊,我們有
- C,直系父母: A,B
但A是B的父,不符合要求2,因此,一個是由C的直接父刪除,我們有
- C,直接家長:乙
目前這裏是我做過什麼: 從A添加邊B(這方面的一個成爲B的母公司)
- 檢查B是由BFS A的母公司。如果是這樣,不要添加邊緣(這確保沒有周期)
- 檢查B是否已經是B的父母。如果是這樣,請不要添加邊緣。
- 查找A的父母與B的直接父母的交集。這是通過找到B的每個父母來完成的。刪除B的直接父母的交集,並添加A作爲B的直接父代。(2和3確保它符合要求2)
這很慢。它在5k節點級別發生故障(我正在尋找這個處理任何小於100k節點的圖形),速度變得不可接受,0.02秒用於添加節點邊緣。
我有一種感覺,第1步和第2步可以用一些其他算法完成。
我想過使用拓撲排序,但它必須橫跨整個圖,這是我的第一步的最壞情況1 & 2.添加新節點時排序會中斷。所以我必須每次爲插入運行拓撲排序,所以它不會產生任何好處。 對於第3步,必須找到整個A的父母。這個過程相當緩慢,因爲它平均橫跨圖的一個體面的部分。
我該如何提高效率?
我走了一圈,做了一些搜索,它是一個活躍的研究領域。 ,但對於要求2,我認爲有可能在短時間內進行一次傳遞減少以節省時間。 – 2009-08-13 12:04:38