# 非線形関数
:::{container} prog-cpp
Hi-QUBO では,絶対値 `qbpp::abs()`・ReLU `qbpp::relu()`・
最大値 `qbpp::max()`・最小値 `qbpp::min()` を式の中で直接使えます.
これらの関数を含む式は,Hi-QUBO にバンドルされているソルバーが
関数値を直接扱って効率よく探索を行います.
補助変数やペナルティ多項式を手動で設計する必要はありません.
[ネイティブ整数変数](../advanced/native-integer.md)と組み合わせて使うこともできます.
## 絶対値: abs
`qbpp::abs(f)` は $|f|$,`qbpp::abs(f, 2)` は $|f|^2$ を表します
(指数は 1 か 2).次のプログラムは
$|x + y - 13| + |x - y - 3|$ を最小化します:
```{literalinclude} /../programFiles/cppPrograms/advanced/basic-operators-and-functions-program1.cpp
:language: cpp
:caption: basic-operators-and-functions-program1.cpp
```
プログラムの出力は以下の通りです:
```{include} /../programFiles/markDown/advanced/basic-operators-and-functions.md
:start-after:
:end-before:
```
## ReLU: relu
`qbpp::relu(f)` は $\max(0, f)$,`qbpp::relu(f, 2)` は
$\max(0, f)^2$ を表し,しきい値の**超過分だけ**にペナルティを
かけたいときに便利です.次のプログラムは,利益 $4x + 7y$ を
最大化しつつ,作業量 $2x + 3y$ が 36 を超えた分に 2 乗ペナルティを
かけ,さらに[ネイティブ制約](../basic/constraints.md) $x + y \le 12$ を
課しています:
```{literalinclude} /../programFiles/cppPrograms/advanced/basic-operators-and-functions-program2.cpp
:language: cpp
:caption: basic-operators-and-functions-program2.cpp
```
プログラムの出力は以下の通りです:
```{include} /../programFiles/markDown/advanced/basic-operators-and-functions.md
:start-after:
:end-before:
```
## 最大値と最小値: max / min
`qbpp::max(f, g)`・`qbpp::min(f, g)` は 2 つの式の最大値・最小値を
表します.次のプログラムは,4 個のジョブを 2 台のマシンに割り当て,
負荷の大きい方(メイクスパン)を最小化します:
```{literalinclude} /../programFiles/cppPrograms/advanced/basic-operators-and-functions-program3.cpp
:language: cpp
:caption: basic-operators-and-functions-program3.cpp
```
プログラムの出力は以下の通りです:
```{include} /../programFiles/markDown/advanced/basic-operators-and-functions.md
:start-after:
:end-before:
```
## 対応と制限
- バンドルされているソルバー([EasySolver](../solver/easy-solver-usage.md)・
[ABS3 Solver](../solver/abs3-solver-usage.md)・[Exhaustive Solver](../solver/exhaustive-solver-usage.md))は
`abs`・`relu`(指数 1, 2)・`max`・`min` のすべてに対応します.
- [GurobiSolver](../solver/gurobi-solver-usage.md) と ScipSolver(Quadratic 方式)は
`abs`・`relu`(指数 1, 2)に対応します.線形化方式の MIP ソルバー
(SCIP Linearize・HiGHS・CBC・GLPK)は指数 1 のみ対応します.
- `max`・`min` は relu の恒等式に展開されるため,MIP ソルバーでも
凸方向 — $w \cdot \max$ の最小化と min の最大化(最小化目的の中の
$-w \cdot \min$)— は解けます.非凸方向は明示的なエラーになります.
- 非線形関数の係数には任意の定数を使えます.負の係数は関数値を
最大化する向きに働きます(バンドルソルバー専用 — MIP ソルバーでは
正の係数のみ使えます).また,非線形関数を含む式は
`expand_cons()`・`reduce()` には対応していません.
- 解 `sol` に対する式の値 `f(sol)` は,ソルバーが返すエネルギーと
常に一致します.
## cons() との関係
[ネイティブ制約](../basic/constraints.md)の `qbpp::cons()` も,値の上では非線形関数の
仲間です.等式制約の値は
$$
\operatorname{cons}(f = k) = \operatorname{abs}(f - k,\, 2)
$$
と同じで,範囲制約の値は
$$
\operatorname{cons}(l \le f \le u) =
\operatorname{relu}(l - f,\, 2) + \operatorname{relu}(f - u,\, 2)
$$
と同じです(違反するのは高々片側なので,2 つの relu が同時に正になる
ことはありません).
違いは意味論です.`cons()` は式を**制約として宣言**し,違反本数
(Viol)の集計や実行可能性・`target_energy` の判定に参加します.
`abs()`・`relu()` は意味論を持たない純粋な目的関数の項で,
制約としては扱われません.「満たすべき条件」には `cons()` を,
「値そのものをコストにしたい量」には `abs()`・`relu()` を使ってください.
:::
:::{container} prog-python
PyQBPP では,絶対値 `qbpp.abs()`・ReLU `qbpp.relu()`・
最大値 `qbpp.max()`・最小値 `qbpp.min()` を式の中で直接使えます.
これらの関数を含む式は,Hi-QUBO にバンドルされているソルバーが
関数値を直接扱って効率よく探索を行います.
補助変数やペナルティ多項式を手動で設計する必要はありません.
[ネイティブ整数変数](../advanced/native-integer.md)と組み合わせて使うこともできます.
## 絶対値: abs
`qbpp.abs(f)` は $|f|$,`qbpp.abs(f, 2)` は $|f|^2$ を表します
(指数は 1 か 2).次のプログラムは
$|x + y - 13| + |x - y - 3|$ を最小化します:
```{literalinclude} /../programFiles/pythonPrograms/advanced/basic-operators-and-functions-program1.py
:language: python
:caption: basic-operators-and-functions-program1.py
```
プログラムの出力は以下の通りです:
```{include} /../programFiles/markDown/advanced/basic-operators-and-functions.md
:start-after:
:end-before:
```
## ReLU: relu
`qbpp.relu(f)` は $\max(0, f)$,`qbpp.relu(f, 2)` は
$\max(0, f)^2$ を表し,しきい値の**超過分だけ**にペナルティを
かけたいときに便利です.次のプログラムは,利益 $4x + 7y$ を
最大化しつつ,作業量 $2x + 3y$ が 36 を超えた分に 2 乗ペナルティを
かけ,さらに[ネイティブ制約](../basic/constraints.md) $x + y \le 12$ を
課しています:
```{literalinclude} /../programFiles/pythonPrograms/advanced/basic-operators-and-functions-program2.py
:language: python
:caption: basic-operators-and-functions-program2.py
```
プログラムの出力は以下の通りです:
```{include} /../programFiles/markDown/advanced/basic-operators-and-functions.md
:start-after:
:end-before:
```
## 最大値と最小値: max / min
`qbpp.max(f, g)`・`qbpp.min(f, g)` は 2 つの式の最大値・最小値を
表します.次のプログラムは,4 個のジョブを 2 台のマシンに割り当て,
負荷の大きい方(メイクスパン)を最小化します:
```{literalinclude} /../programFiles/pythonPrograms/advanced/basic-operators-and-functions-program3.py
:language: python
:caption: basic-operators-and-functions-program3.py
```
プログラムの出力は以下の通りです:
```{include} /../programFiles/markDown/advanced/basic-operators-and-functions.md
:start-after:
:end-before:
```
## 対応と制限
- バンドルされているソルバー([EasySolver](../solver/easy-solver-usage.md)・
[ABS3 Solver](../solver/abs3-solver-usage.md)・[Exhaustive Solver](../solver/exhaustive-solver-usage.md))は
`abs`・`relu`(指数 1, 2)・`max`・`min` のすべてに対応します.
- MIP ソルバーでは,`GurobiSolver` が `abs`・`relu`(指数 1, 2)と
`max`・`min` の凸方向(`w·max` の最小化・min の最大化)に対応します
(係数は正のみ).他の MIP ラッパーは非線形関数に対応していません.
- 非線形関数の係数には任意の定数を使えます.負の係数は関数値を
最大化する向きに働きます.また,非線形関数を含む式は
`expand_cons()`・`reduce()` には対応していません.
- 解 `sol` に対する式の値 `f(sol)` は,ソルバーが返すエネルギーと
常に一致します.
## cons() との関係
[ネイティブ制約](../basic/constraints.md)の `qbpp.cons()` も,値の上では非線形関数の
仲間です.等式制約の値は
$$
\operatorname{cons}(f = k) = \operatorname{abs}(f - k,\, 2)
$$
と同じで,範囲制約の値は
$$
\operatorname{cons}(l \le f \le u) =
\operatorname{relu}(l - f,\, 2) + \operatorname{relu}(f - u,\, 2)
$$
と同じです(違反するのは高々片側なので,2 つの relu が同時に正になる
ことはありません).
違いは意味論です.`cons()` は式を**制約として宣言**し,違反本数
(Viol)の集計や実行可能性・`target_energy` の判定に参加します.
`abs()`・`relu()` は意味論を持たない純粋な目的関数の項で,
制約としては扱われません.「満たすべき条件」には `cons()` を,
「値そのものをコストにしたい量」には `abs()`・`relu()` を使ってください.
:::