乱択アルゴリズムに挑む(その 3)
k-CNF の充足可能な(つまり、全ての clause が真になるような真偽値の)割り当てを求める問題は k-SAT(Satisfiability Problem)と呼ばれる。同書にならって 3-SAT を考える。
問題としては、これまた同書でユーリが「僕」に示した問題で行ってみよう。まず変数を 4 個用意し、それぞれ以下の意味とする。
- x[0] : 強い
- x[1] : 正しい
- x[2] : 美しい
- x[3] : 優しい
これを用いて、同問題の P1 〜 P8 を書き下してみよう。なお、配列の index が 0 から始まる都合上、p[0] 〜 p[7] に変えておく。
boolean [] x = new boolean[4]; boolean [] p = new boolean[8]; p[0] = x[0] || x[1] || x[2]; p[1] = x[3] || x[1] || !x[2]; p[2] = !x[0] || x[3] || x[2]; p[3] = !x[0] || !x[3] || x[1]; p[4] = !x[3] || !x[1] || x[2]; p[5] = !x[0] || !x[1] || !x[2]; p[6] = x[0] || !x[3] || !x[2]; p[7] = x[0] || x[3] || !x[1];
p[0] 〜 p[7] が全て真であるかどうか確認するには以下のようにすればよい。
boolean sat = p[0]; for(int i = 1; i < p.length; i++) { sat = sat && p[i]; }
これで sat が true であれば、全ての p[i] が真であることが確認できる。