クイックリファレンス: 解

qbpp::Sol クラスは QUBO 問題の解を表します。 変数の割り当て(パックされたビット配列)とエネルギー値、求解時間を格納します。

Sol の作成

式 説明
Sol(expr) 式 expr に対する、すべての変数が 0 の解を作成(ネイティブ整数変数は下限の値)

変数・項・式の評価

解 sol が与えられたとき、変数値や式の結果は2つの等価な呼び出し方法で取得できます:

式 等価 戻り値の型 説明
sol(x) x(sol) energy_t Var x を評価(0 または 1 を返す)
sol.get(x) sol(x) coeff_t Var x の値(0 または 1)を取得。ネイティブ整数変数なら整数値(energy_t)
sol(vi) vi(sol) energy_t 整数変数 vi を評価(整数値)
sol(t) t(sol) energy_t Term t を評価
sol(f) f(sol) energy_t Expr f を評価
sol(c) c(sol) energy_t 制約式 c のペナルティを評価
sol(arr) arr(sol) Array<coeff_t> 変数(Var)の配列、ネイティブ整数変数の配列、式(Term・Expr)の配列を評価(同じ形)

sol(x) と x(sol) は同じ結果を返します。 x(sol) 形式は配列で使いやすく、サイズ $n \times m$ の Var 配列 x の場合、 x(sol) はサイズ $n \times m$ の割り当て値(0 または 1)を含む Array<coeff_t> を返します。 式の配列(Array<Dim, Expr>)も、sol(arr) / arr(sol) で各要素を評価した同じ形の Array<coeff_t> を返します(部分配列 arr[i] にも使えます)。 値が coeff_t に収まらない要素があると例外 std::overflow_error になるので、その場合は要素ごとに arr[i](sol)(energy_t)で評価します。

解のモデル(ソルバーに渡した式)に含まれていない変数を読み出したり、そのような変数を含む式を評価したりすると、エラー(例外 std::runtime_error)になります。 replace で値を固定した変数は、固定したあとの式の解には含まれないので、Sol(f).set(sol, ml) で元の式 f の解に戻してから読み出します。 sol.has(x) で、変数がモデルに含まれているか確認できます。

変数値の設定

式 説明
sol.set(x, value) 変数 x を value(0 または 1,ネイティブ整数変数なら整数)に設定
sol.flip(x) バイナリ変数 x の値を反転(0 ↔ 1)。格納されたエネルギーは無効になる。ネイティブ整数変数には使えない
sol.set(other) 別の Sol からすべての変数値をコピー
sol.set(ml) MapList から変数値を設定
sol.set(other, ml) other からコピーし、MapList ml を適用

MapList は (Var, 値) または (Expr, 値) (この Expr は整数変数) のペアのリストです:

qbpp::MapList ml = {{x[0], 1}, {x[1], 0}, {vi, 5}};
sol.set(ml);

set() は Sol& を返します。replace で変数を固定した式の解 sol から元の式 f の解を作るには、set(sol, ml) を使います:

auto full_sol = qbpp::Sol(f).set(sol, ml);

ml の値には ~x[1] のような式も書け、その値は sol の変数値で評価されます。 解を渡さない set(ml) では値は定数でなければならず、式を書くと std::invalid_argument 例外が投げられます。

エネルギーと評価

式 戻り値の型 説明
sol.energy() energy_t 格納されたエネルギー値を返す
sol.comp_energy() energy_t エネルギーを返す(無効な場合のみ現在の変数値から再計算して格納)
sol.tts() double 求解時間(秒)

sol.energy() はソルバーが解を見つけた時点で格納されたエネルギー値を返します。 エネルギーの再計算は行いません。 sol.set() や sol.flip() で変数値を変更した後は、格納されたエネルギーは無効になります。 この状態で sol.energy() を呼び出すとエラーが発生します。 sol.comp_energy() を呼んでエネルギーを再計算・更新してからアクセスしてください。 エネルギーが既に有効な場合、comp_energy() は再計算せずにキャッシュ値を返します。

解からの整数の抽出

onehot_to_int() — ワンホットデコード

式 戻り値の型 説明
onehot_to_int(sol(x)) Array<coeff_t> 最後の軸に沿ってワンホットをデコード(デフォルト)
onehot_to_int(sol(x), k) Array<coeff_t> 軸 $k$ に沿ってワンホットをデコード

指定された軸に沿ってデコードし、次元が1つ少ない配列を返します。 1 次元の配列を渡したときは、配列ではなく coeff_t のスカラー(1 の位置)を返します(軸は指定しません)。 出力形状は入力形状から軸 $k$ を除いたもので、各要素はその軸に沿った1のインデックスです。 負のインデックスもサポートされています(例: -1 = 最後の軸)。 有効なワンホットベクトルでないスライス(ちょうど1つの1を含まない)に対しては $-1$ を返します。

詳細と例については ワンホットから整数への変換 を参照してください。

ソルバー情報

ソルバーの結果クラス(EasySolverSol、ExhaustiveSolverSol、ABS3SolverSol)は Sol を継承し、 info() で追加情報を提供します。

式 戻り値の型 説明
sol.info() const KeyValueVector& ソルバー情報のキーバリューペア
sol.info().get(key) const char* キーに対応する値(無ければ nullptr)
sol.sols const std::vector<Sol>& 収集された全解
sol.size() size_t 収集された解の数
sol.sols[i] const Sol& $i$ 番目の解にアクセス

info() オブジェクトはソルバーのメタデータを文字列のキーバリューペアとして格納しています。 代表的なキー:

キー 説明
"flip_count" 実行された変数フリップの総数(ABS3Solver では "total_flip_count")
"var_count" モデルの変数数
"term_count" モデルの項数
"version" QUBO++ のバージョン
"cpu_name" CPU モデル名
"hostname" マシンのホスト名

返されるキーはソルバーによって異なります。たとえば ExhaustiveSolver は flip_count・version・cpu_name・hostname を返しません(ネイティブ整数変数を含むモデルでは var_count・term_count も返しません)。 info().get(key) はキーが無ければ nullptr を返します。 全エントリを反復処理するか、キーでアクセスできます:

for (const auto& kv : sol.info()) {
  std::cout << kv.key << " = " << kv.value << std::endl;
}
std::cout << "var_count = " << sol.info().get("var_count") << std::endl;

出力

Sol オブジェクトは std::cout で出力できます:

std::cout << sol << std::endl;

変数の割り当てを含む人間が読みやすい形式で出力されます。 表示の例は クイックリファレンス: 表示 を参照してください。


Back to top

Page last modified: 2026.10.15.

© 2026 中野浩嗣, 広島大学