# NAE-SAT (全不等充足可能性問題) :::{container} prog-cpp **全不等充足可能性問題 (NAE-SAT: Not-All-Equal Satisfiability)** はブール充足可能性問題 (SAT) の変種です. ブール変数 $x_0, x_1, \ldots, x_{n-1}$ と節の集合が与えられたとき,各節は少なくとも1つの変数が True であり,**かつ**少なくとも1つが False である場合にのみ**充足**されます. つまり,節内のすべての変数が同じ値(すべて True またはすべて False)のとき,その節は違反となります. 例えば,ブール変数 $x_0, x_1, x_2, x_3$ に対して,以下の節を考えます: $$ \begin{aligned} C_0 &= \lbrace x_0,x_1,x_2 \rbrace,\\ C_1 &= \lbrace x_1,x_2,x_3 \rbrace,\\ C_2 &= \lbrace x_1,x_3 \rbrace \end{aligned} $$ 割り当て $(x_0, x_1, x_2, x_3) = (\text{True}, \text{True}, \text{False}, \text{False})$ は解です.各節に少なくとも1つの True と少なくとも1つの False の変数が含まれています. NAE-SAT は NP 完全であり,ハイパーグラフ彩色や制約充足問題などの応用があります. ## HUBO による定式化 $n$ 個のバイナリ変数 $x_0, x_1, \ldots, x_{n-1}$ と $m$ 個の節 $C_0, C_1, \ldots, C_{m-1}$ に対して,NAE-SAT 制約は HUBO(高次制約なしバイナリ最適化)式として定式化できます. ### NAE 制約 各節 $C_k = \lbrace x_{i_1}, x_{i_2}, \ldots, x_{i_s} \rbrace$ に対して以下を定義します: - **全 True ペナルティ**: 積 $$x_{i_1} \cdot x_{i_2} \cdots x_{i_s}$$ は節内のすべての変数が True のときにのみ 1 になります. - **全 False ペナルティ**: 積 $$\overline{x}_{i_1} \cdot \overline{x}_{i_2} \cdots \overline{x}_{i_s}$$ はすべての変数が False のときにのみ 1 になります.ここで $$\overline{x}_i$$ は否定リテラル($$\overline{x}_i = 1 - x_i$$)を表します. インスタンス全体の制約は以下の通りです: $$ \text{constraint} = \sum_{k=0}^{m-1} \Bigl( \prod_{j \in C_k} x_j + \prod_{j \in C_k} \overline{x}_j \Bigr) $$ この式はすべての節が NAE 充足されている場合にのみ 0 になります. ### 目的関数(オプション) 副次的な目的として,True と False の変数数のバランスを取ることができます: $$ \text{objective} = \Bigl(2\sum_{i=0}^{n-1} x_i - n\Bigr)^2 $$ これは True/False の数がなるべく均等なとき最小化されます($n$ が偶数のとき 0,$n$ が奇数のとき 1). ### HUBO 式 最終的な HUBO 式は,制約と目的関数をペナルティ重み $P$ で組み合わせます: $$ f = \text{objective} + P \times \text{constraint} $$ ここで $P$ は十分大きく(例えば $P = n^2 + 1$),制約の充足が目的関数の最小化よりも優先されるようにします. ## Hi-QUBO による定式化 Hi-QUBO は否定リテラル $$\overline{x}_i$$(`~x[i]` と記述)をネイティブに扱えるため,NAE-SAT の定式化が自然かつ効率的に行えます. 以下のプログラムは,5 変数・4 節(各節サイズ 3)の簡単な NAE-SAT インスタンスを定義し,EasySolver で解き,結果を検証します. ```{literalinclude} /../programFiles/cppPrograms/example/math/naesat-program1.cpp :language: cpp :caption: naesat-program1.cpp ``` ### 実行結果の例 ```{include} /../programFiles/markDown/example/math/naesat.md :start-after: :end-before: ``` ソルバーは `constraint = 0` となる割り当てを見つけ,4 つの節すべてが NAE 充足されています. 目的関数の値は 1 です.これは $n = 5$ が奇数であるため,最良の True/False バランス(例えば True が 3,False が 2)で $(2 \times 3 - 5)^2 = 1$ となるためです. ### 要点 - **否定リテラル**: Hi-QUBO では `~x[i]` を直接使用して $$\overline{x}_i$$ を表現でき,$$1 - x_i$$ に展開する必要がありません.これにより HUBO 式がコンパクトに保たれます. - **高次項**: サイズ $s$ の節は次数 $s$ の項を生成します(例えば,3 リテラルの節では $x_0 x_1 x_2$).Hi-QUBO は HUBO 式をネイティブに扱えるため,二次化(quadratization)は不要です. - **ペナルティ重み**: $P = n^2 + 1$ により,制約違反が目的関数の最大値を必ず上回るようにします. ::: :::{container} prog-python **全不等充足可能性問題 (NAE-SAT: Not-All-Equal Satisfiability)** はブール充足可能性問題 (SAT) の変種です. ブール変数 $x_0, x_1, \ldots, x_{n-1}$ と節の集合が与えられたとき,各節は少なくとも1つの変数が True であり,**かつ**少なくとも1つが False である場合にのみ**充足**されます. つまり,節内のすべての変数が同じ値(すべて True またはすべて False)のとき,その節は違反となります. 例えば,ブール変数 $x_0, x_1, x_2, x_3$ に対して,以下の節を考えます: $$ \begin{aligned} C_0 &= \lbrace x_0,x_1,x_2 \rbrace,\\ C_1 &= \lbrace x_1,x_2,x_3 \rbrace,\\ C_2 &= \lbrace x_1,x_3 \rbrace \end{aligned} $$ 割り当て $(x_0, x_1, x_2, x_3) = (\text{True}, \text{True}, \text{False}, \text{False})$ は解です.各節に少なくとも1つの True と少なくとも1つの False の変数が含まれています. NAE-SAT は NP 完全であり,ハイパーグラフ彩色や制約充足問題などの応用があります. ## HUBO による定式化 $n$ 個のバイナリ変数 $x_0, x_1, \ldots, x_{n-1}$ と $m$ 個の節 $C_0, C_1, \ldots, C_{m-1}$ に対して,NAE-SAT 制約は HUBO(高次制約なしバイナリ最適化)式として定式化できます. ### NAE 制約 各節 $C_k = \lbrace x_{i_1}, x_{i_2}, \ldots, x_{i_s} \rbrace$ に対して以下を定義します: - **全 True ペナルティ**: 積 $$x_{i_1} \cdot x_{i_2} \cdots x_{i_s}$$ は節内のすべての変数が True のときにのみ 1 になります. - **全 False ペナルティ**: 積 $$\overline{x}_{i_1} \cdot \overline{x}_{i_2} \cdots \overline{x}_{i_s}$$ はすべての変数が False のときにのみ 1 になります.ここで $$\overline{x}_i$$ は否定リテラル($$\overline{x}_i = 1 - x_i$$)を表します. インスタンス全体の制約は以下の通りです: $$ \text{constraint} = \sum_{k=0}^{m-1} \Bigl( \prod_{j \in C_k} x_j + \prod_{j \in C_k} \overline{x}_j \Bigr) $$ この式はすべての節が NAE 充足されている場合にのみ 0 になります. ### 目的関数(オプション) 副次的な目的として,True と False の変数数のバランスを取ることができます: $$ \text{objective} = \Bigl(2\sum_{i=0}^{n-1} x_i - n\Bigr)^2 $$ これは True/False の数がなるべく均等なとき最小化されます($n$ が偶数のとき 0,$n$ が奇数のとき 1). ### HUBO 式 最終的な HUBO 式は,制約と目的関数をペナルティ重み $P$ で組み合わせます: $$ f = \text{objective} + P \times \text{constraint} $$ ここで $P$ は十分大きく(例えば $P = n^2 + 1$),制約の充足が目的関数の最小化よりも優先されるようにします. ## PyQBPP による定式化 PyQBPP は否定リテラル $$\overline{x}_i$$(`~x[i]` と記述)をネイティブに扱えるため,NAE-SAT の定式化が自然かつ効率的に行えます. 以下のプログラムは,5 変数・4 節(各節サイズ 3)の簡単な NAE-SAT インスタンスを定義し,EasySolver で解き,結果を検証します. ```{literalinclude} /../programFiles/pythonPrograms/example/math/naesat-program1.py :language: python :caption: naesat-program1.py ``` ### 実行結果の例 ```{include} /../programFiles/markDown/example/math/naesat.md :start-after: :end-before: ``` ソルバーは `constraint = 0` となる割り当てを見つけ,4 つの節すべてが NAE 充足されています. 目的関数の値は 1 です.これは $n = 5$ が奇数であるため,最良の True/False バランス(例えば True が 3,False が 2)で $(2 \times 3 - 5)^2 = 1$ となるためです. ### 要点 - **否定リテラル**: PyQBPP では `~x[i]` を直接使用して $$\overline{x}_i$$ を表現でき,$$1 - x_i$$ に展開する必要がありません.これにより HUBO 式がコンパクトに保たれます. - **高次項**: サイズ $s$ の節は次数 $s$ の項を生成します(例えば,3 リテラルの節では $x_0 x_1 x_2$).PyQBPP は HUBO 式をネイティブに扱えるため,二次化(quadratization)は不要です. - **ペナルティ重み**: $P = n^2 + 1$ により,制約違反が目的関数の最大値を必ず上回るようにします. :::