**布林可滿足度問題**（英文：**Boolean satisfiability problem / SATISFIABILITY**），可以借英文名簡稱 **SAT**，係一種邏輯同運算上嘅問題，指一個人或者一部電腦攞住一條布林公式，並且決定條公式有冇可能滿足得到。簡單噉講，布林表達式可以想像成一串「狀態 A 成立、狀態 B 唔成立... 狀態 XXX 成立 / 唔成立」噉嘅句子。即係話解 SAT 嘅人或者電腦要

攞 Input：一條布林表達式
畀 Output：「有可能滿足」或者「冇可能滿足」
呢類噉嘅問題有一定嘅應用價值，吸引咗唔少電腦科學工作者探究。

背景概念
----

内文：邏輯連接詞同布林表達式
睇埋：合取範式
首先，講講一啲基本嘅邏輯學概念。

一條布林表達式會有若干個變數（ 數值可以係**真**或者**假**），而變數之間會有邏輯連接詞連接住，形成一句「句子」，而句嘢嘅真假值係有可能判斷嘅，例如以下呢幾句嘢噉：

| 公式 | 用日常用語講會係... | 變數 | 連接詞 |
| --- | --- | --- | --- |
| {\displaystyle A\land B} | 「A 同 B 都係真確嘅。」—如果 A 同 B 當中是但一個唔成立，呢條公式就係**假**嘅。（邏輯與） | {\displaystyle A,B} | {\displaystyle \land } |
| {\displaystyle A\lor B} | 「A 或者 B 係真確嘅。」—如果 A 同 B 當中是但一個成立，呢條公式就會係**真**嘅。（邏輯或） | {\displaystyle A,B} | {\displaystyle \lor } |
| {\displaystyle \neg A} | 「A 嘅邏輯非。」—如果 A 係**真**，呢條公式就會係**假**嘅，而如果 A 係**假**，呢條公式就會係**真**嘅。 | {\displaystyle A} | {\displaystyle \neg } |
| {\displaystyle (A\lor B)\land (\neg C)} | 「A 或者 B 係真」係真，同時「C 唔係真」。 | {\displaystyle A,B,C} | {\displaystyle \land ,\lor ,\neg } |

邏輯連接詞嘅概念，仲可以用溫氏圖表達：

|  |  |  |  |  |
| --- | --- | --- | --- | --- |
| 

|  |
| --- |
| ：如果一笪區域係屬於 A **或者**屬於 B，就填紅色。 |
| {\displaystyle A\lor B}：如果一笪區域係屬於 A **或者**屬於 B，就填紅色。  |

|  |
| --- |
| ：如果一笪區域屬於 A **同時又**屬於 B，就填紅色。 |
| {\displaystyle A\land B}：如果一笪區域屬於 A **同時又**屬於 B，就填紅色。  |

 |

等等。

喺 SAT 相關用語上，一個字面係指一個變數或者一個變數嘅邏輯非，一句子句由若干個字面同佢哋之間嘅邏輯或組成（即係例如 {\displaystyle A\lor \neg B\lor C} 噉），而一條合取範式（CNF）就係由若干句子句之間嘅邏輯與組成嘅。

基本定義
----

布林可滿足度問題（SAT）做嘅嘢，就係要攞住一條布林表達式，再畀出答案，答「有冇最少一個變數狀態，係可以**滿足**到呢條公式（令到呢條公式出**真**）嘅呢？」呢條問題。一個（例如）電腦程式要解一條 SAT 問題，只有兩個可能答案：

* **真**（1）：有最少一個可能嘅變數狀態，係能夠滿足嗰條布林表達式嘅；
* **假**（0）：冇任何變數狀態係可以滿足呢條布林表達式嘅，個程式要證明呢一點；

例如想像返呢條式

{\displaystyle (A\lor B)\land (\neg C)}
如果「A 係真同時 C 係假」或者「B 係真同時 C 係假」，噉呢條式就會係**真**—呢條式係有可能滿足嘅。舉個實用啲嘅例子，可以想像而家有四個人—阿明、阿儀、阿安同彼得—想約時間開會，希望四個人都出到席，

「阿明淨係禮拜一、禮拜三、禮拜四得閒。」「阿儀禮拜三唔得閒。」「阿安禮拜五唔得閒。」「彼得禮拜二同禮拜四唔得閒。」
就可以當成要同以下嘅式解 SAT 問題：

{\displaystyle ({\text{ 禮 拜 一 }}{\text{ }}\lor {\text{ }}{\text{ 禮 拜 三 }}{\text{ }}\lor {\text{ }}{\text{ 禮 拜 四 }}{\text{ }})\land (\neg {\text{ }}{\text{ 禮 拜 三 }}{\text{ }})\land (\neg {\text{ 禮 拜 五 }}{\text{ }})\land (\neg {\text{ 禮 拜 二 }}{\text{ }}\land \neg {\text{ 禮 拜 四 }}{\text{ }})}
答案係，嗰個會一定要係喺**禮拜一**開。喺現實應用上，SAT 可以複雜得好交關，字面嘅數量往往遠遠唔只三四個咁少。呢類噉嘅問題，喺理論電腦科學、複雜系統相關研究、密碼學以及人工智能上都頗受關注。

解決方法
----

睇埋：組合爆發
事實表明，SAT 呢種問題可以幾複雜。事實表明，**2-SAT**（有兩個字面嘅 SAT）同 **3-SAT**（有三個字面嘅 SAT）並唔難解，當中 3-SAT 係一個 NP 完全嘅問題，可以將啲可能答案逐個逐個撞嚟解，而且一個答案啱唔啱可以喺相對快嘅多項式時間內核實得到。

### 局部搜尋

内文：局部搜尋
睇埋：爬山演算法
要解 SAT，一種可能嘅做發係用局部搜尋。局部搜尋係一種最佳化技術，起始嗰陣隨機噉試一個可能答案，唔啱用嘅話就對個答案做細幅度嘅修改然後再試，一路重複直到搵到個啱用（但未必完全最好）嘅答案或者過咗時限為止。用呢種方法解 SAT 問題，涉及以下嘅步驟，想像家吓要評估以下嘅布林表達式：

{\displaystyle (x\_{1}\lor \neg x\_{2}\lor \neg x\_{3})\land (\neg x\_{1}\lor \neg x\_{3}\lor x\_{4})\land (\neg x\_{1}\lor \neg x\_{2}\lor x\_{4})}
步驟：

1. 隨機噉設定啲變數嘅數值，例如設做
{\displaystyle x\_{4}=0,x\_{1}=x\_{2}=x\_{3}=1}
2. 試下第 1 步產生嗰個答案係咪啱用；
{\displaystyle (1\lor 0\lor 0)\land (0\lor 0\lor 0)\land (0\lor 0\lor 0)=0}（唔啱用）
3. 如果啱用，將手上嗰個答案畀出嚟做最終答案；
4. 如果唔啱用，就將其中一個變數「反轉」，例如變做
{\displaystyle x\_{1}=x\_{2}=x\_{3}=x\_{4}=1}（{\displaystyle x\_{4}}「反轉」咗）
5. 返去步驟 2，直至搵到個啱用嘅答案或者時限過咗為止。

局部搜尋嘅做法唔能夠證明任何嘢：例如可能有答案，但係佢咁啱唔好彩撞唔中（撞中之前時間到）；又或者有多過一個答案，但佢淨係搵到其中一個。

### 解 SAT 器

睇埋：歸約
**解 SAT 器**顧名思義係指解 SAT 問題嘅演算法。自從 2000 年代起，電腦科學界就有喺度開發解 SAT 器，有搞比賽用獎金鼓勵啲人開發新嘅解 SAT 器。呢啲比賽引起嘅創新，甚至仲有啟發其他電腦科學子領域嘅研究者。

解 SAT 器有好多種唔同嘅做法，一種幾常見嘅做法係將手上嗰條問題歸約做 3-SAT 問題：一條噉嘅演算法會攞一條 SAT 問題 {\displaystyle \phi }，將 {\displaystyle \phi } 轉化做一條 3-SAT 問題 {\displaystyle \phi ^{'}}，即係例如將一條有成六個變數咁多嘅 SAT 問題轉化做

{\displaystyle (x\_{1}\lor \neg x\_{2}\lor \neg x\_{4})\land (x\_{2}\lor x\_{3}\lor x\_{5})\land (x\_{1}\lor x\_{4}\lor \neg x\_{6})}
噉嘅 CNF，同時兩條問題係「同等」嘅，即係話「若且唯若 {\displaystyle \phi } 係可滿足嘅，{\displaystyle \phi } 會係可滿足嘅」。由於 3-SAT 問題係 NP-完全嘅，所以如果一條 SAT 問題可以轉做 3-SAT 當係 3-SAT 噉嚟解，就能夠令條問題易解好多。

睇埋
--

* 運算複雜度

參考
--

用咗嘅重要概念或者專有名詞嘅外語（主要係英文）名：

1. ↑  Boolean expression
2. ↑  variable
3. ↑  logical connectives
4. ↑  A and B
5. ↑  A or B
6. ↑  negation of A
7. ↑  Venn diagram
8. ↑  literal
9. ↑  clause
10. ↑  conjunctive normal form
11. ↑  NP-complete
12. ↑  polynomial time
13. ↑  local search
14. ↑  optimization
15. ↑  SAT solver

引用咗嘅學術文獻或者網頁：

1. 1 2  Vizel, Y.; Weissenbacher, G.; Malik, S. (2015). "Boolean Satisfiability Solvers and Their Applications in Model Checking". *Proceedings of the IEEE*. 103 (11): 2021-2035.
2. ↑  (2011). Clause. In: Sammut, C. Webb, G.I. (eds) *Encyclopedia of Machine Learning*. Springer, Boston, MA.
3. 1 2  Satisfiability: Algorithms, Applications and Extensions (PDF), *SAC 2010* Lecture slides.
4. ↑  Aho, Alfred V.; Hopcroft, John E.; Ullman, Jeffrey D. (1974). *The Design and Analysis of Computer Algorithms*. Addison-Wesley. p. 403.
5. ↑  Massacci, Fabio; Marraro, Laura (2000-02-01). "Logical Cryptanalysis as a SAT Problem". *Journal of Automated Reasoning*. 24 (1): 165-203.
6. ↑  Cook, Stephen A. (1971). "The complexity of theorem-proving procedures" (PDF). *Proceedings of the third annual ACM symposium on Theory of computing - STOC '71*. pp. 151–158.
7. ↑  The International SAT Competition Web Page.
8. ↑  *Reduction from SAT to 3SAT* (PDF), Swagato Sanyal.

外拎
--

* （英文） Efficient solution of Boolean satisfiability problems with digital memcomputing，呢篇英文文章對象係有意研習電腦科學嘅學生。