解について

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

Sol の作成

式

説明

Sol(expr)

式 expr に対するすべてゼロの解を作成

変数・項・式の評価

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

式

等価

戻り値の型

説明

sol(x)

x(sol)

energy_t

Var x を評価(0 または 1 を返す)

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>

変数/式の配列を評価

sol(x) と x(sol) は同じ結果を返します. x(sol) 形式は配列で使いやすく,サイズ \(n \times m\) の Var 配列 x の場合, x(sol) はサイズ \(n \times m\) の割り当て値(0 または 1)を含む Array<coeff_t> を返します.

変数値の設定

式

説明

sol.set(x, value)

変数 x を value(0 または 1)に設定

sol.set(other)

別の Sol からすべての変数値をコピー

sol.set(ml)

MapList から変数値を設定

{% raw %}

sol.set(other, ml)

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

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

set(Sol&) と set(ml) メソッドは Sol& を返すため,チェーンが可能です:

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

エネルギーと評価

式

戻り値の型

説明

sol.energy()

energy_t

格納されたエネルギー値を返す

sol.comp_energy()

energy_t

エネルギーを返す(無効な場合のみ現在の変数値から再計算して格納)

sol.tts()

double

求解時間(秒)

sol.energy() はソルバーが解を見つけた時点で格納されたエネルギー値を返します. エネルギーの再計算は行いません. sol.set() で変数値を変更した後は,格納されたエネルギーは無効になります. この状態で 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つ少ない配列を返します. 出力形状は入力形状から軸 \(k\) を除いたもので,各要素はその軸に沿った1のインデックスです. 負のインデックスもサポートされています(例: -1 = 最後の軸). 有効なワンホットベクトルでないスライス(ちょうど1つの1を含まない)に対しては \(-1\) を返します.

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

ソルバー情報

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

式

戻り値の型

説明

sol.info()

const KeyValueVector&

ソルバー情報のキーバリューペア

sol.sols

const std::vector<Sol>&

収集された全解

sol.size()

size_t

収集された解の数

sol.sols[i]

const Sol&

\(i\) 番目の解にアクセス

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

キー

説明

"flip_count"

実行された変数フリップの総数

"var_count"

モデルの変数数

"term_count"

モデルの項数

"version"

Hi-QUBO のバージョン

"cpu_name"

CPU モデル名

"hostname"

マシンのホスト名

全エントリを反復処理するか,キーでアクセスできます:

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

出力

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

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

変数の割り当てを含む人間が読みやすい形式で出力されます.

Sol クラスは QUBO 問題の解を表します. 変数の割り当てとエネルギー値,求解時間を格納します.

Sol の作成

式

説明

Sol(expr)

式 expr に対するすべてゼロの解を作成

変数値の取得

Var / Term / Expr(通常の式・整数変数・制約式のいずれも)に対して,sol(x) と x(sol) は同じ値を返します. 加えて,sol[x] は sol(x) の省略形です.

式

戻り値の型

説明

sol(x) / x(sol) / sol[x]

int

変数 x の値を取得(0 または 1)

sol(vi) / vi(sol) / sol[vi]

int

整数変数 vi の整数値を取得

sol(t) / t(sol)

int

項 t を評価

sol(f) / f(sol)

int

式 f を評価

sol(c) / c(sol)

int

制約 c のペナルティを評価

配列の場合は要素ごとにアクセスします:

for i in range(n):
    print(sol[x[i]])

変数値の設定

式

説明

sol.set(x, value)

変数 x を value(0 または 1,整数変数なら整数)に設定

sol.set(other_sol)

別の解からすべての変数値をコピー

sol.set({x: val, ...})

辞書で変数値を一括設定

sol.set([(x, val), ...])

タプルリストで変数値を一括設定

sol.set(other_sol, {x: val, ...})

別の解からコピーし,辞書で上書き

sol.set(other_sol, [(x, val), ...])

別の解からコピーし,タプルリストで上書き

sol.set(x[0], 1)
sol.set(x[1], 0)
sol.set(vi, 5)

# 辞書で一括設定
sol.set({x[0]: 1, x[1]: 0, vi: 5})

set メソッドは self を返すため,チェーンが可能です:

full_sol = Sol(f).set(sol).set({x[0]: 1})

エネルギーと評価

式

戻り値の型

説明

sol.energy

int

格納されたエネルギー値を返す

sol.comp_energy()

int

エネルギーを返す(無効な場合のみ再計算)

sol.tts

float

求解時間(秒)

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

解からの整数の抽出

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

式

戻り値の型

説明

qbpp.onehot_to_int(sol(x))

array

最後の軸に沿ってワンホットをデコード(デフォルト)

qbpp.onehot_to_int(sol(x), axis=k)

array

軸 \(k\) に沿ってワンホットをデコード

指定された軸に沿ってデコードし,次元が1つ少ない配列を返します. 出力形状は入力形状から軸 \(k\) を除いたもので,各要素はその軸に沿った1のインデックスです. 負のインデックスもサポートされています(例: -1 = 最後の軸). 有効なワンホットベクトルでないスライスに対しては \(-1\) を返します.

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

ソルバー情報

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

式

戻り値の型

説明

sol.info

dict

ソルバー情報のキーバリューペア

sol.sols

list[Sol]

収集された全解

sol.size

int

収集された解の数

sol.sols[i]

Sol

\(i\) 番目の解にアクセス

info 辞書はソルバーのメタデータを文字列のキーバリューペアとして格納しています. 代表的なキー:

キー

説明

"flip_count"

実行された変数フリップの総数

"var_count"

モデルの変数数

"term_count"

モデルの項数

"version"

Hi-QUBO のバージョン

"cpu_name"

CPU モデル名

"hostname"

マシンのホスト名

for k, v in sol.info.items():
    print(f"{k} = {v}")

出力

print(sol)