# 範囲制約と整数線形計画問題の解法 ## 範囲制約の多項式による定式化 $f$ を2値変数の多項式とします。 範囲制約は、$l \leq f \leq u~(l < u)$ の形で表されます。ここでの目的は、この範囲制約が満たされる場合に限り最小値 0 をとる多項式を設計することです。 基本的な考え方は、補助整数変数 $a$ を導入し、$a$ が $l \leq a \leq u$ の範囲の値をとるようにすることです。次の式を考えます。 $$ g=(f − a)² $$ この式 $g$ は、$f = a$ のときにちょうど最小値 0 をとります。$a$ は $l \leq a \leq u$ の任意の整数値をとることができるため、この式 $g$ は $f$ 自身が同じ範囲内の整数値をとる場合に限り 0 を達成します。 この補助変数の手法を用いて、Hi-QUBO では範囲制約を実装しています。 $f$ が線形式である場合、$g$ は QUBO 式になります。 $f$ が3次以上の式である場合、$g$ は HUBO 式になります。
**NOTE** :::{container} prog-cpp Hi-QUBO は内部的に軽量な改良を用いており、範囲制約をわずかに少ない2値変数で符号化できるようにしています。 ::: :::{container} prog-python PyQBPP は内部的に軽量な改良を用いており、範囲制約をわずかに少ない2値変数で符号化できるようにしています。 ::: 詳細は [比較演算子](https://hi-qubo.com/docs/advanced/comparison-operators.html) で説明されています。
## 整数線形計画問題の解法 整数線形計画問題のインスタンスは、目的関数と複数の線形制約から構成されます。 例えば、次の整数線形計画問題は、2つの変数、1つの目的関数、および2つの制約を持ちます。 $$ \mathrm{Maximize:}&~5x+4y,\\ \mathrm{Subject}~\mathrm{to:}&~2x+3y \leq 24,\\ &~7x+5y \leq 54. $$ この問題の最適解は、 $x = 1, y = 2$ であり、目的関数値は 40 です。 :::{container} prog-cpp 以下の Hi-QUBO プログラムは、Easy Solver を用いてこの最適解を求めます。 ```{literalinclude} ../../programFiles/cppPrograms/basic/range-constraints-and-ilp-program1.cpp :language: cpp :caption: range-constraints-and-ilp-program1.cpp ``` この Hi-QUBO プログラムでは、 - `f` は目的関数を表します。 - `c1` および `c2` は範囲制約を表します。 - `g` はそれらを1つの最適化式にまとめたものです。 目的は最大化であるため、目的関数は `-f` として符号を反転させています。また、制約 `c1` および `c2` には重み 100 のペナルティを与え、制約が高い優先度で満たされるようにしています。 `g` に対して Easy Solver のインスタンスを作成し、時間制限 1.0 秒で探索を実行します。最適解 `sol` を取得した後、プログラムは `x`、`y`、`f`、`c1`、`c2`、`*c1`、および `*c2` の値を出力します。 このプログラムの出力は次のとおりです。 ```{include} ../../programFiles/markDown/basic/range-constraints-and-ilp-program.md :start-after: :end-before: ``` ここで、 - `c1` は制約 `0 ≤ 2x + 3y ≤ 24` を表す式です。 - `*c1` は線形式 `2x + 3y` を表します。 以上より、ソルバーが正しく最適解を見つけていることが確認できます。 ::: :::{container} prog-python 以下の PyQBPP プログラムは、Easy Solver を用いてこの最適解を求めます。 ```{literalinclude} ../../programFiles/pythonPrograms/basic/range-constraints-and-ilp-program1.py :language: python :caption: range-constraints-and-ilp-program1.py ``` この PyQBPP プログラムでは、 - `f` は目的関数を表します。 - `c1` および `c2` は範囲制約を表します。 - `g` はそれらを1つの最適化式にまとめたものです。 目的は最大化であるため、目的関数は `-f` として符号を反転させています。また、制約 `c1` および `c2` には重み 100 のペナルティを与え、制約が高い優先度で満たされるようにしています。 `g` に対して Easy Solver のインスタンスを作成し、時間制限 1.0 秒で探索を実行します。最適解 `sol` を取得した後、プログラムは `x`、`y`、`f`、`c1`、`c2`、および制約本体の式の値を出力します。 このプログラムの出力は次のとおりです。 ```{include} ../../programFiles/markDown/basic/range-constraints-and-ilp-program.md :start-after: :end-before: ``` ここで、 - `c1` は制約 `0 ≤ 2x + 3y ≤ 24` を表す式です。 - `c1.body` は線形式 `2x + 3y` を表します。 以上より、ソルバーが正しく最適解を見つけていることが確認できます。 :::