2-CNF 問題解決方案

本篇文章主要是根據上屆一個東大學長謝文豔寫的一篇《給定2CNF可滿足性問題》自己重新總結了一下,然後把所有的代碼都調試了一遍,不過有一點要注意的是,文章中的方法能夠判斷問題是有具有解,能給出該問題的一種可行解,但並不能給出所有的解。

我自己總結爲兩個部分,圖論問題和算法的詳解。

一、將問題轉換爲圖論問題 

首先,將2CNF的問題轉換爲圖論問題。

下面的規則說明了如何把一個2CNF轉化爲一個有向圖G=<V,E>

u    2CNF的每個變量及這個變量的非都作爲圖G的頂點。顯然若這個2CNF3個變量,那麼將有6個頂點。

 

u   

 

第一步首先爲那些有到自己的非的有向路徑的變量賦值,即如果圖G中有從x到的有向路徑,那麼將變量x賦值爲false。如果圖G中有從到x的有向路徑,則將變量x賦值爲true。將在這個步驟中被賦了值的變量稱爲一級變量。

如下所示:

 

 

 

 

第二步依次從與每一個一級變量對應的節點出發(如果一級變量x被賦值爲true,則從與x對應的節點出發;如果x被賦值爲false, 則從與對應的節點出發),將所有能到達的、還沒有被賦值的節點賦值爲true(如果該節點對應於y,則將y賦值爲true;如果該節點對應於,則將y賦值爲false)。將在這個步驟中被賦了值的變量稱爲二級變量。

如下所示:

 

第三步:依次檢查還沒有被賦值的變量,如s,如果與s對應的頂點出度不爲0(有指向其它節點的有向邊),則將s賦值爲true,然後從與s對應的頂點出發,將所有能到達的、還沒有被賦值的節點賦值爲true;如果與s對應的頂點出度爲0,則將s賦值爲false,從與s對應的頂點出發,將所有能到達的、還沒有被賦值的節點賦值爲true。將在這個步驟中被賦了值的變量稱爲三級變量。

如下所示:

    

 

 

   

二、算法的詳解

 

 

1.        先構圖,並將圖表示爲鄰接矩陣。思想主要是將每一個字句用鄰接矩陣edges表示,如字句xUy,輸入的時候表示爲:1 1然後,將該字句表示 在數據結構中表示爲edges[n+1][2]=1以及edges[2][n+1]=1

2.        並找出一級變量。主要思想是調用isSatisfiable函數,利用廣度優先從頂點i到頂點n+i看看是否能走通,同時,也判斷從頂點n+i到頂點i,如果都走通了,說明誤解,否則判定這n個點後,不存在兩個條件都滿足的情況,則表示有解了。同時,在判斷的過程中,找出一級變量。

 

3.        找出二級變量和三級變量。從每一個一級變量出發,根據原則,利用廣度優先的算法,把所有能達到的變量變爲true,這些變量就是二級變量了。然後再獲取三級變量,通過一個循環,將沒有訪問過的變量,利用的原則來將所有的所能達到的置爲true

 

4.        自此,算法結束,輸出所有變量的值。(注意:該算法只能獲得一組可行解,但不能獲得所有的解)

 

 

 

如果輸入:  

格式如下:

4 3//第一個參數是行數 第二個是變量個數

//記下來是字句輸入 表示爲-1 2

 

-1 2

-2 3

1 -3

3 2

得出結果:

有可行解

1:1

2:1

3:1

 

 

又例如輸入:

 

 

 

 

 

得出結果:

 

1:1 //X1:1
2:0 //x2:0
3:0 //x3:0
4:1 //x4:1
5:0 //x5:0

 

 

點擊這裏下載完整代碼

若有問題歡迎發郵件給我:[email protected]

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章