SAT(充足可能性問題)を HUBO で解く

節を入力するかランダムな k-SAT を生成して、Solve を押します。各節が HUBO モデルの 1 つの積の項になり、QUBO++ がすべての節を満たす割当てを探します。

解説: C++ 版(QUBO++)· Python 版(PyQBPP)

10s

Click cell to cycle: empty → + (positive) → − (negative) → empty

使い方

このデモは資源の限られた AWS Lambda 上で動いています。 デスクトップ PC 上の QUBO++ は数倍速く動きます。

論理式を HUBO にする

このデモでは True を 0、False を 1 で表します。 すると、正のリテラル $x$ が False になるのは $x=1$ のとき、 負のリテラル $\lnot x$ が False になるのは $\overline{x}=1$($\overline{x}=1-x$)のときです。 $(x_0 \lor \lnot x_1 \lor x_2)$ のような節が満たされないのは、すべてのリテラルが False のときだけです。 つまり、次の積が 1 になるときだけです。

\[x_0\,\overline{x_1}\,x_2\]

すべての節についてこの積を足したものは、満たされない節の数になります。 したがって、値が 0 になる割当てが論理式を満たします。

$k$ 個のリテラルを持つ節は $k$ 次の項になるので、このモデルは QUBO ではなく HUBO(Higher-order Unconstrained Binary Optimization、高次の制約なし二値最適化)です。 QUBO++ は、補助変数を使って QUBO に変換することなく、HUBO のまま解きます。 否定リテラル $\overline{x}$ もそのまま扱います。 デモの下にある 2 つめの式は、すべての $\overline{x}$ を $1-x$ に展開したものです。 否定リテラルを含む節は、展開すると複数の項に分かれます。

プログラム

QUBO++ の Python 版である PyQBPP では、節をリテラルの積で書きます。否定リテラルは ~x です。 次の 2 行は、SAT のページ のプログラムからの抜粋です。

c0 = x[0] * x[1] * x[2]
c1 = ~x[0] * x[3] * x[4]

1 行目は節 $(x_0 \lor x_1 \lor x_2)$、2 行目は節 $(\lnot x_0 \lor x_3 \lor x_4)$ です。 プログラム全体と出力は SAT のページ にあります。 C++ 版 もあります。

自分のコンピュータで動かす

PyQBPP は Linux(x86-64・ARM64)と、WSL 経由の Windows で動きます。

pip install pyqbpp

詳しくは インストール を見てください。 QUBO++ で解く問題は、ほかのデモ にもあります。