# ピタゴラスの三つ組 :::{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)に一覧があります. :::