///1
2-sat問題,通俗的說就是有n對點(2n個點),從每對點中選出乙個點,共選出n個點,而且要滿足若干個這樣的條件:某兩點不能同時被選出。
設一對點為x、~x,如果a被選出則b一定要被選出,就在圖中加有向弧(a,b)表示這種關係。那麼如果a,b(a!=b,a!=~b)不能同時被選出,那麼加兩條有向弧(a,~b),(b,~a)。這樣由圖的對稱性可以證明,2-sat有解等價於任取x、~x,x、~x不在乙個強聯通分量中。
現在討論一下特殊情況的意義。建圖的過程中,如果a=b時,只用加一條有向弧(a,~a);這樣也是有意義的,可表示a不能出現(~a必須被選出)。如果a=~b時,會加兩條有向弧(a,a),(b,b),屬於重邊,無意義。這兩種特殊情況都滿足圖的對稱性:(a,~b)和(b,~a)同時存在,故不影響2-sat的正確性。這樣可以泛化一下滿足條件,變成拓展的2-sat:如果條件對應的若干個有向弧保證(a,~b)和(b,~a)同時存在,那麼就可以轉化最原始的2-sat問題來解決。舉個例子,如果有滿足條件要求a必須出現,那麼只需新增其對應的有向弧(~a,a)。這樣2-sat的應用範圍就被大大增強了。
///2
2-sat 演算法
2-sat問題描述:
有n二元個組(xi, yi),現在有些組之間的元素是相互衝突的,如xi, 和yj相互衝突,現在要你從每個組中選出乙個元素,使得他們不會相互衝突。
演算法:1. 建圖。
對於有衝突的兩個元素xi, yj,現在在原圖中建兩條這樣的邊,。
2, 求圖中的強連通分量。
如果存在二元組(xi, yi)在同乙個強連通分量中,則不存在答案,直接退出演算法.
否則,就將每個連通分量合併成乙個點,得到新圖g』.
3, 我們可以知道得到的新圖是乙個有向無環圖,對其進行拓撲排序,得到a0,a1,..,am;
現在對於拓撲序列中的元素進行著色,對於序列中沒有著色的點ai,將它著色為1,然後尋找它的原圖中屬於這個連通分量的點的對稱點(也就是二元組中的另乙個點,例如xi的對稱點是yi)所在的連通分量s,將其染成2,然後在新圖中對這個點s進行dfs,將它能訪問到的點染成2.
4, 最後同種顏色的點就是一組滿足要求的解.
2-sat問題:
每組有2個元素,必須取且只能取其中乙個,相當與x和~x,同時有一些相斥關係,比如選了x就不能選y,記a->b表示選了a就必須選b,那麼x與y相斥 <=> x->~y且y->~x <=> ~(x∧y) <=> (~x∨~y)
2-sat問題就是求把包含2個元素的布林式取∧後得到true的一組解
對於k-sat,k > 2是np問題
如果選擇的次序不當,對於x可能它的後繼有存在~x,於是需要回溯,演算法的改進就是如何給出乙個恰當的選擇次序。
演算法:
建圖:對於x->y,連一條x到y的邊,根據對稱性,~y->~x,同樣連一條~y到~x的邊
因為關係->具有傳遞性,故如果存在乙個強連通分量,則選取其中任意乙個結點,其餘的結點也同樣會被選到,故可以先縮點,如果x和~x在同乙個強連通分量裡,則無解。
否則,得到新的有向無環圖
在新圖中按照拓撲反序開始選擇,若當前結點沒有選擇,則選擇當前結點並刪除對稱結點以及對稱結點的前驅。
因為採用了拓撲反序,不存在未處理的後繼
強連通分量scc
kosaraju演算法
一次dfs搜出拓撲序,第二次按照拓撲序在反圖上dfs
tarjan演算法
pre[u]表示u結點的訪問時間,low[u]表示u以及u的後代能訪問到的最早的最先結點v的pre[v]
如果pre[u] == low[v],則說明u是dfs樹中u所在scc的起始點,這時u之後棧內的結點都是u所在scc中的結點,將它們出棧並染色
計算low[u]的方法和無向圖求割頂割邊時類似
(u, v) in e
若v未被訪問,即(u, v)為樹枝邊,low[u] = min(low[u], low[v])
若v已被訪問,如果v在棧中,(u, v)可以為後向邊也可以為連線同乙個dfs樹中沒有後代關係的兩個結點的交叉邊,
low[u] = min(low[u], pre[v])
如果v不在棧中,(u, v)為連線不同dfs樹的交叉邊,v處於另乙個scc,不必考慮
gabow演算法
和tarjan的思想一樣,不過用到了兩個棧,乙個棧s和原來一樣,另乙個棧p儲存dfs樹中scc的起始點
s和p每次都把樹邊的結點壓入棧,如果(u, v) in e 是且v在s棧中,則表示出現了環,將p中的結點出棧直到v。當結點訪問u的後代後,u在p的棧頂,說明u是所在scc的起始點,同tarjan演算法把s棧內結點出棧並染色,注意別忘了把p棧的棧頂元素出棧。
三種演算法中kosaraju最容易理解,但需要存反圖並且兩次dfs,但其實另兩種演算法也容易理解,tarjan演算法與圖論中很多演算法的原理相同,gabow演算法在tarjan演算法基礎上不需要頻繁跟新low陣列。個人比較偏向於使用tarjan演算法。
pku 3207
判斷圓上的線是否可能相交,推出互斥關係,判斷2-sat問題是否有解
此題資料非常弱
pku 3678
巧妙的建圖:對於x必須選,連~x->x的邊
注意不要少加邊了
pku 2723
二分+強連通判無解
pku 3648
輸出一組未被選擇的解,注意新郎必須選
pku 3683
處理一下時間
pku 2749
二分建圖後判是否有解,先排序的話速度會快一些
hit 1917
標準的2-sat,測試模板
2 SAT問題的小結
什麼是2 sat呢?就是有一些集合,每個集合中有且僅有兩個元素,且不能同時選取兩個元素,集合間的元素存在一定的選擇關係,求解可行性及可行方案。1 連邊 2 跑tarjan 3 判可行性,即同一集合中的兩個點是否同屬乙個強連通塊 4 縮點建新圖,連反邊 5 拓撲序,若當前點沒有被訪問過,則選擇該點,不...
學習筆記 2 SAT 小結
目錄從sat說起布林可滿足性問題 boolean satisfiability problem sat 屬於決定性問題,也是第乙個被證明屬於np完全的問題。此問題在電腦科學上許多領域的皆相當重要,包括電腦科學基礎理論 演算法 人工智慧 硬體設計等等。摘自某百科 如 有三個bool變數,三個人要求的取...
2 SAT問題的演算法
求解2 sat問題的演算法有很多,有一種效率還不錯,實現方便又理解方便的演算法。注意例子中的那個條件 x1為假或x2為真 在x1為假的時候x2可以為任意值,但在x1為真的時候,x2為滿足條件必須是真。也就是說x1為真可以推導出x2為假 x2為假可以推導出x1為真。換成一般的情況,已知xa xb 則x...