2013-04-09 64 views
11

我有一個依賴關係算法的問題,依賴類似於maven依賴,除了它是基於嚴格的版本範圍。算法來解決版本範圍的依賴關係

例如:

component A, version 1 depends on: component B, version 1~3; and component C, version 2~3 
component D, version 1 depends on: component B, version 2~4; and component C, version 1~2 

現在,我想的依賴,當我想安裝組件A,版本1和成分d,第1版。因爲它們都依賴於組分B,C等我需要一個正確的算法來獲得B和C的正確版本

進一步,我可能需要升級組件A和D.例如,現在我有以下新版本:

component A, version 2 depends on: component B, version 3~5; and component C, version 4~5 
component A, version 3 depends on: component B, version 6~7; and component C, version 4~5 
component D, version 2 depends on: component B, version 3~4; and component C, version 3~4 

現在我需要一種算法來獲得我可以升級到的A和D的正確版本及其所有依賴項。這裏的一個問題是成分A 3版本和組件d,第2版具有成分B的依賴性衝突

是否有現有的算法來解決這樣的問題呢?或類似(更容易)的問題。你有什麼建議嗎?

由於不應該有大量的數據,所以不考慮性能。

在此先感謝!

+0

對於一個簡單的解決方案,你可以使用拓撲排序嗎?您可以從建立一個每個節點都是{節點ID,版本號}的圖開始。之後,做一個拓撲排序來獲得依賴順序。 – trequartista 2013-04-09 17:57:35

+0

謝謝,但在我的情況下,依賴只需要解析一個組件版本,所以如果構建一個圖,對於具有相同節點id的節點,輸出列表只能輸出一個節點;對於某些節點來說,它們的版本可能會有衝突,所以這樣的節點可能永遠不會在輸出列表中。如何解決這個問題呢? – Xilang 2013-04-10 01:57:18

+0

不是我的意思是,每個節點都有節點ID和版本ID。即。 {組件A,版本1}和{組件A,版本2}是不同的節點。例如: – trequartista 2013-04-10 18:38:10

回答

1

這是satisfiability problem的變體。 osgi也必須處理這個問題。所以你可以看看osgi規範和/或實現,看看它們是如何解決它的。

11

此問題是經由來自3SAT以下還原NP難題。給定一個3CNF公式,對於每個變量,都有一個包含兩個版本的組件,並且對於每個子句,都有一個包含三個版本的組件。我們想安裝一個版本的「超級」組件,它取決於所有的子組件,但對版本不挑剔。對於每個子句,子句組件1取決於出現在子句中的第一個變量,如果文字是正數,則需要版本1,如果是負數,則爲0。子句組件2取決於第二個變量等。我們可以安裝超級組件,當且僅當公式是可滿足的。

在這種減少的光,它是有道理的制定你的問題,因爲constraint satisfaction。每個組件都是一個變量,其可能的值是該組件的版本,如果沒有安裝該組件,則加上「未安裝」是一個選項。對於每個組件A的版本取決於組件B的版本,存在涉及A和B變量的約束,將版本的選擇限制爲其域的產品的特定子集。對於第一個例子中的A和B,這是{(1,1),(1,2),(1,3)},因爲A版本1取決於B版本1〜3。如果A的版本2也可用,則這個約束將是{(1,1),(1,2),(1,3),(2,3),(2,4),(2,5) }。如果我們不必安裝A或B,那麼{(none,none),(none,1),(none,2),(none,3),(none,4),(none,5), (1,1),(1,2),(1,3),(2,3),(2,4),(2,5)}。

由於您的情況是小,你可能需要一個完整的回溯搜索,可能與約束傳播。約束傳播的常用算法是AC-3,它強制實施弧一致性,即根據已被消除的內容從考慮中排除顯然無法工作的所有版本。例如,給定約束{(1,1),(1,2),(1,3)},我們可以消除B =無,因爲從不出現。既然B的選擇是受限制的,那麼我們可以推斷B的依賴關係C等等。當沒有更多的簡化可以做時,我們必須猜測;一種策略是選擇剩下最少版本的組件並遞歸嘗試所有組件(回溯)。