# ピタゴラスの三つ組
:::{container} prog-cpp
3つの整数 $x$,$y$,$z$ が以下を満たすとき,**ピタゴラスの三つ組**と呼ばれます:
$$
\begin{aligned}
x^2+y^2&=z^2
\end{aligned}
$$
重複を避けるため,$x
## ピタゴラスの三つ組を列挙するHi-QUBOプログラム
以下のプログラムは,$x\leq 16$,$y\leq 16$,$z\leq 16$ の範囲でピタゴラスの三つ組を列挙します:
```{literalinclude} /../programFiles/cppPrograms/example/math/pythagorean-triples-program1.cpp
:language: cpp
:caption: pythagorean-triples-program1.cpp
```
このプログラムでは,1から16の範囲の整数変数 `x`,`y`,`z` を定義しています.
次に,2つの制約式を作成します:
- `f`: $x^2+y^2-z^2=0$
- `c`: $x+1\leq y$
これらを `g` に結合します.
すべての制約が満たされたとき,式 `g` は最小値0を取ります.
`g` に対してEasy Solverオブジェクト `solver` を作成し,`search()` に初期化子リストとして以下のオプションを渡します:
- `"time_limit"` を `10.0` に設定: 10秒後に探索を終了します.
- `"best_energy_sols"` を `0` に設定: 最良(最低)エネルギーを共有する解をすべて保持します(`0` は無制限).
`search()` の呼び出しは,最良の解を格納する `qbpp::easy_solver::Sols` オブジェクト `sols` を返します.
`qbpp::easy_solver::Sols` は格納された最良エネルギー解へのイテレータアクセス(`begin()`,`end()`,`cbegin()`,`cend()`)を提供するため,範囲ベースのforループで出力できます.
このプログラムは以下のような出力を生成します:
```{include} /../programFiles/markDown/example/math/pythagorean-triples.md
:start-after:
:end-before:
```
## `qbpp::cons()` を使ってより大きな範囲を探索する
等式 $x^2+y^2-z^2=0$ と不等式 $x+1\leq y$ は,`qbpp::cons()` で囲むことで
**制約**として記述できます.バンドルされたソルバーは,目的関数を最適化しつつ
制約を満たす割り当てを探索するため,はるかに大きな範囲を実用的に探索できます.
以下のプログラムでは範囲を `1..1000` に広げ,目的関数 `-z` を加えることで,
斜辺ができるだけ大きい三つ組をソルバーが返すようにしています:
```{literalinclude} /../programFiles/cppPrograms/example/math/pythagorean-triples-program2.cpp
:language: cpp
:caption: pythagorean-triples-program2.cpp
```
ここで `f.cons(sol)` は違反した制約の本数を返します.`0` は,返された三つ組が
`y > x` を満たす正しいピタゴラス数であることを意味します.典型的な出力は次の
とおりです:
```{include} /../programFiles/markDown/example/math/pythagorean-triples.md
:start-after:
:end-before:
```
## `c64e128` で大きな整数を扱う
大きな整数範囲では,ソルバーが扱う途中の値が64ビット整数の範囲を超えることが
あります.その場合は,プログラム先頭に `#define INTEGER_TYPE_C64E128` を置いて
`c64e128` 型(64ビット係数・128ビットエネルギー)を選択します.以下は範囲を
`1..10000` にした版です:
```{literalinclude} /../programFiles/cppPrograms/example/math/pythagorean-triples-program3.cpp
:language: cpp
:caption: pythagorean-triples-program3.cpp
```
典型的な出力は次のとおりです:
```{include} /../programFiles/markDown/example/math/pythagorean-triples.md
:start-after:
:end-before:
```
利用可能な整数型は[変数・式クラス](../basic/variables-and-expressions.md)に一覧があります.
:::
:::{container} prog-python
3つの整数 $x$,$y$,$z$ が以下を満たすとき,**ピタゴラス数**と呼ばれます:
$$
\begin{aligned}
x^2+y^2&=z^2
\end{aligned}
$$
重複を避けるため,$x
## ピタゴラス数を列挙する PyQBPP プログラム
以下のプログラムは,$x\leq 16$,$y\leq 16$,$z\leq 16$ のピタゴラス数を列挙します:
```{literalinclude} /../programFiles/pythonPrograms/example/math/pythagorean-triples-program1.py
:language: python
:caption: pythagorean-triples-program1.py
```
このプログラムでは,範囲 1 から 16 の整数変数 `x`,`y`,`z` を定義します.
次に,2つの制約式を作成します:
- `f`: $x^2+y^2-z^2=0$ の制約,
- `c`: $x+1\leq y$ の制約.
これらを `g` にまとめます.
式 `g` はすべての制約が満たされたときに最小値 0 を達成します.
`g` に対して全探索ソルバーオブジェクト `solver` を作成します.
`search(best_energy_sols=0)` を呼ぶと,最良エネルギー(最適)解がすべて保持され,`result.sols` から読み取れます.
整数変数は複数のバイナリ変数でエンコードされるため,同じ $(x,y,z)$ の割り当てが複数回出現する可能性があります.
そのため,出力前に `set` を使って重複を除去しています.
このプログラムは以下の出力を生成します:
```{include} /../programFiles/markDown/example/math/pythagorean-triples.md
:start-after:
:end-before:
```
## `qbpp.cons()` を使ってより大きな範囲を探索する
等式 $x^2+y^2-z^2=0$ と不等式 $x+1\leq y$ は,`qbpp.cons()` で囲むことで
**制約**として記述できます.バンドルされたソルバーは,目的関数を最適化しつつ
制約を満たす割り当てを探索するため,はるかに大きな範囲を実用的に探索できます.
以下のプログラムでは範囲を `1..1000` に広げ,目的関数 `-z` を加えることで,
斜辺ができるだけ大きい三つ組をソルバーが返すようにしています:
```{literalinclude} /../programFiles/pythonPrograms/example/math/pythagorean-triples-program2.py
:language: python
:caption: pythagorean-triples-program2.py
```
ここで `f.cons(sol)` は違反した制約の本数を返します.`0` は,返された三つ組が
`y > x` を満たす正しいピタゴラス数であることを意味します.典型的な出力は次の
とおりです:
```{include} /../programFiles/markDown/example/math/pythagorean-triples.md
:start-after:
:end-before:
```
## `c64e128` で大きな整数を扱う
大きな整数範囲では,ソルバーが扱う途中の値が64ビット整数の範囲を超えることが
あります.その場合は,`import pyqbpp.c64e128 as qbpp` で `c64e128` データ型
(64ビット係数・128ビットエネルギー)をインポートします.以下は範囲を
`1..10000` にした版です:
```{literalinclude} /../programFiles/pythonPrograms/example/math/pythagorean-triples-program3.py
:language: python
:caption: pythagorean-triples-program3.py
```
典型的な出力は次のとおりです:
```{include} /../programFiles/markDown/example/math/pythagorean-triples.md
:start-after:
:end-before:
```
利用可能なデータ型は[データ型](../basic/variables-and-expressions.md)に一覧があります.
:::