2-SAT

點擊打開鏈接

序言

  

        最近花了一點心思研究2-sat模型,看了很多論文博客等等,也在POJ上做了一點題。其實這個東西也還挺好玩的,當然,前提是每道題你都有認真分析,認真想清楚模型的意義,搞明白爲什麼可以這樣,而不是簡單的知道怎樣做,就套上一個模板了事,那樣,是不是也太糟蹋這門科學了。

  關於2-sat,基本上所有人都會推薦兩個資料:

        伍昱 由對稱性解2-sat問題(ppt)

        趙爽 2-sat解法淺析(pdf)

        我當然也會推薦啦,好歹這也是引導我入門的東西,雖然說一開始看的並不是很懂,不過,還是要先膜拜一下兩位大牛。

  這篇文章主要是把我對2-sat的一些研究進行總結,我不太喜歡公式化的語言,所以,基本上會是白話陳述,主要包括以下五個內容:
       1、概念的闡述
       2、算法的闡述
       3、算法的解釋
       4、構圖的介紹
  5、題目的分享
  下面就進入正題。


概念

  

       要知道2-sat是什麼,我們先要知道什麼是適定性(Satisfiability)問題,適,就是合適,定,就是確定,適定性問題通俗的說就是確定是否可以滿足所有的條件?或者說就是確定一個滿足所有條件的方案。取英文的前三個字母,簡稱sat問題。

  通俗的sat問題表述一般是這樣的:有很多個集合,每個集合裏面有若干元素,現給出一些取元素的規則,要你判斷是否可行,可行則給出一個可行方案。如果所有集合中,元素個數最多的集合有k個,那麼我們就說這是一個k-sat問題,同理,2-sat問題就是k=2時的情況。
  爲什麼研究2-sat呢?無可置疑的是它很有用。爲什麼不研究3-sat乃至k更大的情況呢,因爲它們已經被證明爲是 NP完全問題了,在更多的情況下,2-sat不僅僅是元素個數最多的集合含有2個元素,而是每個集合都含有2個元素,且這2個元素不允許同時取出,這篇文章主要討論的就是這樣一種特殊的模型。


算法

  

       仍然這樣,我的總結也從這道題開始。

  題目大意:一國有n個黨派,每個黨派在議會中都有2個代表,現要組建和平委員會,要從每個黨派在議會的代表中選出1人,一共n人組成和平委員會。已知有一些代表之間存在仇恨,也就是說他們不能同時被選爲和平委員會的成員,現要你判斷滿足要求的和平委員會能否創立?如果能,請任意給出一種方案。( POI 0106 )
  正如你看到的那樣,題目給的非常裸,其實,2-sat的題目都沒有隱藏的那麼深,不像網絡流那樣很難發現。
  對於這個問題,暴力當然可以解決了,其實說的更好聽一點,也就是在圖上進行暴力,噗,是不是感覺很高級的樣子,嗯,這其實就是一個很容易理解的算法了。
  

算法一:持之以恆

  假設1A、1B爲1號黨的兩名黨員,2A、2B(噗,不準笑)爲2號黨的兩名黨員,且1A與2A之間存在仇恨!那麼,這意味着什麼?如果選擇1A,就只能選擇2B了,如果選擇了2A呢?那同理就只能選擇1B了,那麼,我們可以這樣構建一個圖,在1A到2B之間搭上一條邊,2A到1B之間搭上一條邊,這條邊的含義就是:必須。
  也就是說,沿着一條路徑,如果一個點被選擇了,那麼這條路徑以後的點都將被選擇,那麼,出現不可行的情況就是,存在一個黨派兩個黨員都被選擇了,那麼,我們只需要枚舉一下就可以了,數據不大,答案總是可以出來的。
  這麼一個簡單的算法,放在第一個說,看來你已經知道它不是重點了,但是,若題目要求的是字典序最小的方案的話,那就只能選擇這個算法了。

算法二:沒有名字

  構圖還是跟第一個算法一樣,但是在解圖的過程中進行了非常漂亮的優化。
  爲了說清楚傳遞,我們先來回憶一下命題的概念:命題、逆命題、否命題、逆否命題。
       概念就不說了,舉了例子也好:
  命題:三角形內角和爲180°
  逆命題:內角和爲180°的是三角形
  否命題:不是三角形的內角和不爲180°
  逆否命題:內角和不是180°的不是三角形
  有個很顯然的結論就是,命題與逆否命題的真假性是一樣的(又有人要說我囉嗦了嗯)

  也許,你正在很奇怪我爲什麼要扯到這個東西,雖然我看的所有資料都沒有介紹過,也沒人把這兩東西扯到一起,不過,我還就真覺得它們就是一路的,怎麼說?


  選A就必須選B,那麼我們先“逆一下”,從B到A,再“否一下”,不選B就一定不選A,這是顯然成立的,也就是說,在構好的圖中,“必須”是沿着邊正方向傳遞下去的,“禁止”是沿着邊反方向傳遞下去的,那麼每次我們選擇了一個點,就把它的對立點(即同集合的另一元素)標記爲不可選,然後呢,我們把選擇標記正向傳遞,再把禁止標記逆向傳遞,這是符合題意的高效做法,但是……還是很麻煩,竟然要雙向傳遞,而且……你怎麼知道一開始要選擇哪一個節點纔好呢?囧。
  不要急,請先達成一點共識:
       1、如果很多節點已經處在一個強連通分量內了,也就是它們兩兩均可互達了,那麼意味着選擇了其中的一個,整個強連通分量都將被選擇,如果不選擇其中的一個,那麼整個強連通分量內都不能夠被選擇。
       2、如果一個集合的兩個元素處在了同一個強連通分量內,也就是說要麼都不選,要麼都被選,那麼題目要求的選出一個就一定無法成立了。
  3、題中不管給出哪兩個不能同時選,都不能改變我們連的邊都是對稱的這一事實,只要A到B有邊,那麼B的對立節點到A的對立節點就有邊。
  4、邊的對稱意味着圖的對稱,原圖的對稱意味着哪怕用強連通分量縮點後的圖一樣對稱,所以對立節點的概念也可以應用在強連通分量上。
  5、爲了敘述方便,以下簡稱強連通分量爲塊,注意:真正的塊指的是點雙連通分量,這裏只是一種形象化的表述,是不規則的!

算法的過程如下:
構圖

  更具體的後面再說
縮點
  Tarjan算法縮點,將所有的邊反過來( 爲什麼?後面有嗯 )
判可行
  枚舉集合的兩個元素,看其是否處於不同的塊內,若否的話則給出不可行信息
記錄矛盾
  這裏所說的矛盾不是題中給出的兩個人之間有仇恨,那樣的邊是實際存在,我們這裏說的矛盾是指若兩個塊分別含有兩個對立節點,也就是說一個集合的兩個元素分佈在了兩個不同的塊中,那麼這兩個塊就是矛盾的,即不可能同時被選擇,這樣一種矛盾關係是不存在於邊中的,是不依賴於輸入的數據的,我們要找到與一個塊對立的塊,並把它們保存下來。
拓撲排序
  將縮點後的圖進行拓撲排序(排的是塊而不是節點)
構造方案
  按照拓撲序列的順序,依次訪問所有塊,若一個塊未被標記,將其標記爲“選擇”,不傳遞“選擇”標記,將被選塊的對立塊標記爲“不選擇”,將其“不選擇”標記沿着邊正向傳遞。( 不是逆着邊麼?哼,圖已經被反過來了,你到底有沒有認真看吶!囧 )

  沒了?沒了,真沒了。我知道你很想問爲什麼,= =,ps:是不是覺得我特別囉嗦……
唉,囉嗦慣了,看到那些 “一 點 都 不 囉 嗦 的 論 文 我 就 想 * * ”。回到正題,我們繼續。

解釋


1、爲什麼要用反邊存縮點後的圖?

- - 考慮到算法傳遞標記的時候,“選擇”標記是沒有進行傳遞的,也就是說正向邊是沒有利用到的,傳遞的都是“不選擇”標記,也就是說走的都是反邊,但是,鄰接表存邊,怎麼走得了反邊呢?那麼既然正向邊沒有用,就把整個圖反過來存就好了,並且,這個反圖還真是反得好啊!爲什麼呢,往下看。

2、爲什麼要拓撲排序呢?

- - 不該來的還是來了,這可真是一個令人噁心的問題,哪怕到我現在寫,我也無法對它有種深深的認同,你懂的,有些東西,哪怕你並說不出它爲什麼如此,但是你能感受到,能夠認同到,能夠抓住它的走向,深信其的正確,但是,有的東西,哪怕你已經能夠說出爲什麼了,還是無法對其有深深的認同感,總覺得有種彆扭、不舒服的感覺在,少廢話,繼續。
- - 觀察下面的這幅圖(注意:此圖爲原圖,非縮點後存的反圖)


  如果我們沒有按照拓撲序列來選擇塊的話:訪問到A,發現其無標記,於是把它標記爲可選擇,然後把A’標記爲不可選擇,然後呢,進行標記傳遞,但是問題出現了,若進行“選擇”標記傳遞,則B和B’將被標記爲選擇,若進行“不選擇”標記傳遞,則B和B’將被標記爲不選擇,這又選擇又不選擇的,不就矛盾了嗎?難道是因爲此圖無解嗎?但是根據我們判斷無解的標準,即兩對立節點處在同一塊中,此圖是有解的,不存在節點可以互達,究其原因,是因爲我們的構造方法不對,A處在了整個邊的上游地帶,先就將其確定爲選擇對原圖的影響太大了,根本就無法保證接下來還能進行正確的抉擇。所以,正確的方法應該是按照拓撲順序,從影響小的開始抉擇,在轉成反邊後,A’會處在拓撲序列的首位,將A’標記爲選擇,將A標記爲不選擇,都不能傳遞,再將B標記爲選擇,B’標記爲不選擇,當然,將B標記爲不選擇,B’標記爲選擇也是可以的,這完全看拓撲排序的編寫規則,畢竟我們是訪問到一個無標記的就將其標記爲選擇的,那麼誰先出現誰就被選擇了,自然界的規律哈哈。

3、爲什麼只傳遞“不選擇”標記,不傳遞“選擇”標記?

- - 還記得我們的選擇規則嗎?好像已經重複了好多遍了……找到一個未被標記的,就將其標記爲選擇,然後將對立塊標記爲不選擇,再把不選擇標記傳遞,如果我們選擇了B,那麼它的後代節點A’(此處爲原圖的後代,即上圖所示)一定是被選擇了的?爲什麼呢?如果它的後代節點A’是沒有被選擇的,那麼它的後代節點的對立節點A肯定是被選擇了的,根據邊的對稱性,A’是B的後代節點,那麼B’就是A的後代節點,既然A被選擇了,那麼B’也要被選擇,那麼根據順序,B會被標記爲不可選擇,那麼我們在訪問到B的時候,就不會把它認定爲未標記,那也就不存在將其標記爲選擇了,這與假設是矛盾的,顯然不可行。所以,既然我們選擇一個節點的時候,它的後代都已經被選擇好了,那麼我們就不需要進行“選擇”標記的傳遞了,況且,到標記傳遞的時候,我們都已經存的是反圖了,就算你想傳遞也沒辦法了……囧。總的來說,就是雖然我們沒有傳遞選擇標記,但是這種傳遞的性質是滿足的。

4、標記法構造方案的時候爲什麼不會同時選定一個集合的兩個元素?

- - 嗯,我想這跟上一個問題是一樣的,如果你還心存疑惑,Please read it again.

5、標記法構造方案的時候爲什麼不會把同一集合兩個元素都標記爲不選擇?

- - 我們不妨把選擇一個塊,然後將其對立塊標記爲不選擇這一行爲叫做直接標記,把其對立塊進行“不選擇”標記傳遞時標記塊叫做間接標記,下面就容易說話了……
(1)若兩對立塊是在某塊被標記爲選擇後,同時被其直接標記爲不選擇的:
  那麼我們想想它們爲什麼會被其直接標記?當然是因爲它們的內部有與標記爲選擇的塊對立的節點,在記錄矛盾這一步驟中被記錄了下來,所以纔會這樣的,但是再定睛一看,憑什麼被標記爲選擇的塊中某兩節點的對立節點分佈在了不同的塊中?還記得我們達成的共識嗎?邊的對稱意味着塊的對稱,那麼這兩個被直接標記爲不選擇的塊本就不應該分開,這種情況是不成立的。也就是說,這兩個被標記爲“不可選”的塊不都是直接標記的。
  這同時還說明了很重要的一點,與一個塊直接矛盾的塊存在且僅存在一個,所以我們記錄矛盾塊用的不是鄰接表,而只是一個數組就可以了。
(2)若兩對立塊是在某塊被標記爲選擇後,其中一個塊被其直接標記,另一塊被其間接標記:
       因爲其中一塊被其直接標記,故其間存在一對對立節點,另一塊與被直接標記的這一塊爲對立塊(根據大前提),那麼又出現了存在於被直接標記的塊中的兩個節點,它們的對立節點分散在了兩個塊中,這又矛盾了。也就是說,這兩個被標記爲“不選擇”的塊都不是被直接標記的。
(3)若兩對立塊是在某塊被標記爲選擇後,同時被其間接標記爲不可選擇的:
  這麼說來,被標記爲選擇的塊的對立塊(假設爲O),它到這兩個塊(假設爲A,A’)都是有路徑的,因爲要進行不選擇標記傳遞啊(此處爲反圖敘述),但是根據圖的對稱性,既然O到A有路徑,那麼A’就到O,然而,O到A’也有路徑,那麼兩個塊就顯然是一個塊,這是與假設相悖的。也就是說,這兩個被標記爲“不可選”的塊也都不是間接標記的。
  那麼,總的來說,在將一個塊標記爲“選擇”之後,在直接標記與間接標記中都不會出現上述情況。那在不同的塊被標記爲“選擇”之後,會出現上述情況嗎?
(4)在整個操作中會把兩個對立塊都標記爲不選擇嗎?
  至此,我們已經可以確定的就是,在一次選擇與傳遞過程中,是不會出現這樣的情況的,若是放在整個的構造過程中,我們也可以確信的就是,兩個對立塊的任何一個都不會被別的塊直接標記爲不可選,如果一個塊已經被標記爲不可選了,那麼只能是它的對立塊被標記爲可選了,纔將其直接標記,同時,那些可能再度將其標記爲不可選的塊,會在它的間接標記下,死亡……嗯,也就是被奪去標記別人的資格,爲什麼?因爲圖是對稱的!
這個問題就這樣愉快的解決了!


6、都說用對稱性解決2-sat問題,到底哪裏用到了對稱性?

- - 是的,這個問題真的是太蠢的,不知道你是不是有跟我一樣的想法,至少我就糾結過好久,唉,讓我再感嘆一次吧!愚蠢的問題啊!算法雖然沒有直接用到對稱性來實現,但是對稱性是算法的基石啊!如果原圖不是對稱的!那前面的證明就都不成立,那麼算法正確性就無法保證了!真是太2的問題了,誰說一定要在算法過程中體現才叫用到啊,唉,真是2死了。

模型

  

       當然,我還是很希望你看到這裏已經懂了的,不然,肯定是我敘述的太沒水準了。= = 如果不懂的話,還是弄懂再往下走爲妙,畢竟,(詞乏了,略去)

  如果你以爲2-sat就只是和平委員會這樣的題目的話,那你就錯了,但是,你以爲它比和平委員會多很多的話,那你也錯了,其實,常用的模型沒有太多。

模型一:兩者(A,B)不能同時取

  那麼選擇了A就只能選擇B’,選擇了B就只能選擇A’
  連邊A→B’,B→A’


模型二:兩者(A,B)不能同時不取

  那麼選擇了A’就只能選擇B,選擇了B’就只能選擇A
  連邊A’→B,B’→A


模型三:兩者(A,B)要麼都取,要麼都不取

  那麼選擇了A,就只能選擇B,選擇了B就只能選擇A,選擇了A’就只能選擇B’,選擇了B’就只能選擇A’
  連邊A→B,B→A,A’→B’,B’→A’


模型四:兩者(A,A’)必取A

  那麼,那麼,該怎麼說呢?先說連邊吧。
  連邊A’→A
  你想出來爲什麼了嗎?也許你在想,哇塞,這樣就保證了在反圖中A在拓撲序中靠前,然後就會先選擇A,呵呵,你錯了。
  雖然,我在一些人的博客中見到了這樣的解釋,但是,我還是非常負責任的告訴你,這是不全面的。
  我們從A’向A連邊,要的不僅是拓撲序,還有判可行與否。在2-sat圖當中,若該圖是可行的,就意味着如果從A到A’有路徑的話,A’到A是沒有路徑的,因爲如果有路徑,它們就成一個塊了,不會被判爲可行,那麼,如果A到A’是有路徑的話,在反圖中,A’就到A有路徑,那麼拓撲裏,A’就會因爲靠前被標記爲“選擇”,並未滿足條件。並且,我們應當確信的是,解的多情況依賴的是拓撲排序的多情況,不按拓撲序來的話,解就是錯誤的,或者說是不成立的,也就是說,我們拓撲序先選擇A的話,就會導致別的約束條件的不成立,那麼在我們引入了A’到A的這條邊後,A就與A’在同一塊中了,算法會報告不可行信息。若是原圖本來就滿足A到A’有路徑,然而A’到A無路徑的話,我們添一條邊,只是確定了其有解,但絲毫不會影響到拓撲排序,只有當A到A’之間根本不存在路徑的時候,纔會影響到其拓撲排序,所以,真相是這樣的。
  是不是有人已經開始疑惑,講了這麼久的對稱性,整個算法都是依賴對稱性才得以成立的,那麼怎麼一下引入一條邊讓圖不對稱了算法還成立呢!關於這個問題,其實很好解釋,仔細想想,對稱性確保的是什麼?它確保的可是原圖有解,則一定可以構造出來。現在我們引入了一條邊A’→A,若通過上述判斷,讓其無解了,那麼對後面顯然是沒有影響的,畢竟算法都沒執行下去了,還算什麼影響。如果還有解呢?這說明了什麼?這說明了A’到A原本就存在一條路徑,或者A’到A之間根本就沒有路徑。如果有路徑的話,那麼我多增加一條有區別嗎?它會影響到算法的任何一步嗎?顯然不會啊,那如果原本沒有路徑的話呢?沒有路徑意味着誰在拓撲序列中靠前都是可能的,在有了該邊後(反邊爲A→A’),A將在拓撲序列中靠前,被標記爲“選擇”,那麼我們會對A’進行直接標記,此時,A’到A是沒有路可走的,它根本就無法訪問到A,所以在標記的這個過程中,這條路徑根本就沒有影響到圖的任何對稱性,在拓撲排序後,你完全可以當其不存在。


  模型其實都大同小異,還是看自己去變幻,比如模型一和模型二其實就是一樣的,只是針對的點不同而已。一般,如果2-sat感覺很明顯的話,就用2-sat做好了,不過,千萬記得考慮好如何降低構圖的複雜度噢!複雜度如果太高,就還是再另闢蹊徑吧,也許有更加好的方法嗯。

題目

  

        都源自POJ,大家可以自行練習,如果要對拍什麼的,這裏也有程序,題目按從簡單到簡單的順序排序(噗……其實是推薦做題順序),大家,一起好好加油。

        POJ 3207

        POJ 3683

        POJ 3678

        POJ 3648

        POJ 2723

        POJ 2749


發佈了275 篇原創文章 · 獲贊 11 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章