# Easy Solverの使い方
:::{container} prog-cpp
**Easy Solver**はQUBO/HUBO式のためのヒューリスティックソルバーです.
Easy Solverを使って問題を解くには,以下の2つのステップで行います:
1. Easy Solver(`qbpp::EasySolver`)オブジェクトを作成します.
2. `search()` メンバ関数を呼び出して解を探索します.パラメータは初期化子リストとして渡します.`qbpp::easy_solver::EasySolverSol` オブジェクトが返されます.
## Easy Solverオブジェクトの作成
Easy Solverを使用するには,式(`qbpp::Expr`)オブジェクトを引数としてEasy Solverオブジェクト(`qbpp::EasySolver`)を以下のように構築します:
- **`qbpp::EasySolver(const qbpp::Expr& f)`**
ここで,`f` は解くべき式です.
事前に `simplify_as_binary()` 関数を呼び出してバイナリ式として簡約化しておく必要があります.
この関数は与えられた式 `f` を解探索中に使用される内部フォーマットに変換します.
## 探索パラメータの設定
探索パラメータは `search()` メンバ関数に初期化子リストとして直接渡します.
以下のパラメータが利用可能です:
| パラメータ | 説明 | デフォルト |
|---|---|---|
| `time_limit` | 制限時間(秒).`0` で時間制限なし. | `10.0` |
| `target_energy` | ターゲットエネルギー.この値以下の解が見つかると探索を終了. | (なし) |
| `enable_default_callback` | `1` で新たに得られた最良解を出力. | `0` |
| `topk_sols` | 保持するtop-k解の数. | (無効) |
| `best_energy_sols` | 最良エネルギーの解を保持.`0` で無制限. | (無効) |
| `seed` | 乱数シード.初期解や提案に使う乱数列を固定します.完全な実行再現は直列構成(例: `thread_count=1`)でのみ保証され,多スレッドではタイミングの非決定性が残ります. | `0`(非決定) |
パラメータは `search()` に初期化子リストとして渡します:
```{include} /../programFiles/markDown/solver/easy-solver-usage.md
:start-after:
:end-before:
```
未知のパラメータキーを指定するとランタイムエラーが発生します.
## 解の探索
Easy Solverは,**`search()`** メンバ関数を呼び出すことで解を探索します.パラメータは初期化子リストとして渡すことができます.
## プログラム例
以下のプログラムは,Easy Solverを使用してLow Autocorrelation Binary Sequences (LABS)問題の解を探索します:
```{literalinclude} /../programFiles/cppPrograms/solver/easy-solver-usage-program1.cpp
:language: cpp
:caption: easy-solver-usage-program1.cpp
```
この例では,以下のパラメータが `search()` に渡されています:
- 制限時間5.0秒,
- ターゲットエネルギー900,
- デフォルトコールバックが有効.
したがって,ソルバーは経過時間が5.0秒に達するか,エネルギーが900以下の解が見つかると終了します.
例えば,このプログラムは以下の出力を生成します:
```{include} /../programFiles/markDown/solver/easy-solver-usage.md
:start-after:
:end-before:
```
## 高度な使い方
### 複数のtop-k解の保持
Easy Solverは探索中に見つかった**複数のtop-k解**を保持できます.
この機能を有効にするには,`topk_sols` パラメータを設定します.
このパラメータが設定されると,`search()` が返す `EasySolverSol` オブジェクトには保持されたtop-k解が含まれます.
返されたオブジェクト `sols` に対して,インデックスまたはイテレータで保持された解にアクセスできます:
- **`sols.sols[i]`**: `i` 番目の `qbpp::Sol` オブジェクトを返します(メンバ配列 `sols` へのインデックス).
- **`sols.size()`**: 保持された解の数を返します.
- **`begin()`**, **`end()`**: 範囲ベースforループ(`for (const auto& sol : sols)`)で各解に順にアクセスできるイテレータです.
以下のプログラムは,Easy Solverを使用してLow Autocorrelation Binary Sequence (LABS)問題を解きます.
`topk_sols` を `20` に設定しているため,ソルバーは**最大20個のtop-k解**を保持します.
プログラムは範囲ベースforループを使用して各保持解を出力します.
```{literalinclude} /../programFiles/cppPrograms/solver/easy-solver-usage-program2.cpp
:language: cpp
:caption: easy-solver-usage-program2.cpp
```
このプログラムは以下の出力を表示します:
```{include} /../programFiles/markDown/solver/easy-solver-usage.md
:start-after:
:end-before:
```
### 複数の最良エネルギー解の保持
Easy Solverは探索中に見つかった最良(最小)エネルギーを共有する複数の解を保持できます.
この機能を有効にするには,`best_energy_sols` パラメータを設定します.
値は保持する最大解数を指定します.`0` で無制限です.
使い方は `topk_sols` と同じです.
したがって,上記のHi-QUBOプログラムでこの機能を有効にするには,`topk_sols` を `best_energy_sols` に置き換えます:
```{include} /../programFiles/markDown/solver/easy-solver-usage.md
:start-after:
:end-before:
```
このパラメータが設定された場合,ソルバーは見つかった最良エネルギーと等しいエネルギーの解のみを保持します.
結果として得られるプログラムは,すべて最良エネルギー値26を持つ以下の解を生成します:
```{include} /../programFiles/markDown/solver/easy-solver-usage.md
:start-after:
:end-before:
```
:::
:::{container} prog-python
**Easy Solver**はQUBO/HUBO式のためのヒューリスティックソルバーです.
Easy Solverを使って問題を解くには,以下の2つのステップで行います:
1. 解きたい式に対して **`EasySolver`** オブジェクトを作成します.
2. キーワード引数を渡して **`search()`** メソッドを呼び出し,解を探索します.見つかった最良解が返されます.
## Easy Solverオブジェクトの作成
Easy Solverを使用するには,以下のように式を引数として `EasySolver` オブジェクトを構築します:
- **`EasySolver(f)`**
ここで,`f` は解くべき式です.
事前に `simplify_as_binary()` を呼び出してバイナリ式として簡約化しておく必要があります.
この関数は与えられた式 `f` を解探索中に使用される内部フォーマットに変換します.
コンストラクタは式をホストメモリにロードします.以降 `search()` を複数回呼び出してもこのロードは1度きりなので,同じ式に対して繰り返し探索する際のオーバーヘッドがありません.
## 探索パラメータの設定
探索パラメータは `search()` メソッドにキーワード引数として直接渡します.
以下のパラメータが利用可能です:
| パラメータ | 型 | 説明 | デフォルト |
|---|---|---|---|
| `time_limit` | float | 制限時間(秒).`0` で時間制限なし. | `10.0` |
| `target_energy` | int | 目標エネルギー.この値以下の解が見つかると探索を終了します. | (なし) |
| `enable_default_callback` | int (0 または 1) | `1` に設定すると,新たに得られた最良解のエネルギーとTTSを自動的に出力します. | `0` |
| `topk_sols` | int | 保持するtop-k解の数. | (無効) |
| `best_energy_sols` | int | 最良エネルギーの解を保持.`0` で無制限. | (無効) |
| `seed` | int | 乱数シード.初期解や提案に使う乱数列を固定します.完全な実行再現は直列構成(例: `thread_count=1`)でのみ保証され,多スレッドではタイミングの非決定性が残ります. | `0`(非決定) |
パラメータは `search()` にキーワード引数として渡します:
```{include} /../programFiles/markDown/solver/easy-solver-usage.md
:start-after:
:end-before:
```
未知のパラメータキーを指定するとランタイムエラーが発生します.
## 解の探索
Easy Solverは,**`search()`** メソッドを呼び出すことで解を探索します.必要に応じてパラメータをキーワード引数として渡すことができます.
このメソッドは,見つかった最良解を返します.返される解は `sol.energy`(エネルギー値),`sol(x)`(変数値の取得),`sol.info`(ソルバー情報の辞書)などを提供します.詳細は [QR_SOLUTION](../quickReference/qr-solution.md) を参照してください.
## プログラム例
以下のプログラムは,Easy Solverを使用してLow Autocorrelation Binary Sequences (LABS)問題の解を探索します:
```{literalinclude} /../programFiles/pythonPrograms/solver/easy-solver-usage-program1.py
:language: python
:caption: easy-solver-usage-program1.py
```
この例では,以下のパラメータが `search()` に渡されています:
- 制限時間5.0秒,
- 目標エネルギー900,
- デフォルトコールバック有効.
したがって,ソルバーは経過時間が5.0秒に達するか,エネルギーが900以下の解が見つかると終了します.
例えば,このプログラムは以下のような出力を生成します:
```{include} /../programFiles/markDown/solver/easy-solver-usage.md
:start-after:
:end-before:
```
## 高度な使い方
### 複数のtop-k解の保持
Easy Solverは探索中に見つかった**複数のtop-k解**を保持できます.
この機能を有効にするには,`topk_sols` パラメータを設定します.
このパラメータが設定されると,`search()` が返す解は保持されたtop-k解も保持します.
これらは以下のプロパティや操作でアクセスできます:
- **`sol.sols`**: 保持されている解のリスト(エネルギーの昇順).
- **`sol.sols[i]`**: `i` 番目の解を返します.
- **`len(sol.sols)`**: 保持されている解の数.
以下のプログラムは,Easy Solverを使用してLABS問題を解きます.
`topk_sols` を `20` に設定しているため,ソルバーは**最大20個のtop-k解**を保持します.
プログラムはrange-based forループを使用して各保持解を出力します.
```{literalinclude} /../programFiles/pythonPrograms/solver/easy-solver-usage-program2.py
:language: python
:caption: easy-solver-usage-program2.py
```
このプログラムは以下のような出力を表示します:
```{include} /../programFiles/markDown/solver/easy-solver-usage.md
:start-after:
:end-before:
```
### 複数の最良エネルギー解の保持
Easy Solverは探索中に見つかった最良(最小)エネルギーを共有する複数の解を保持できます.
この機能を有効にするには,`best_energy_sols` パラメータを設定します.
値は保持する最大解数を指定します.`0` で無制限です.
使い方は `topk_sols` と同じです.
したがって,上記のプログラムでこの機能を有効にするには,`topk_sols` を `best_energy_sols` に置き換えます:
```{include} /../programFiles/markDown/solver/easy-solver-usage.md
:start-after:
:end-before:
```
このパラメータが設定された場合,ソルバーは見つかった最良エネルギーと等しいエネルギーの解のみを保持します.
結果として得られるプログラムは,すべて最良エネルギー値26を持つ以下の解を生成します:
```{include} /../programFiles/markDown/solver/easy-solver-usage.md
:start-after:
:end-before:
```
:::