式の評価

辞書を使った評価

式の値は、すべての変数への値の割り当てを {変数: 値} の辞書として与えることで簡単に計算できます。 辞書は完全な割り当てを構成する (変数, 値) のペアのリストを保持します。

以下のプログラムは、$(x,y,z)=(0,1,1)$ に対して関数 $f(x,y,z)$ を計算します:

import pyqbpp as qbpp

x = qbpp.var("x")
y = qbpp.var("y")
z = qbpp.var("z")
f = qbpp.sqr(x + 2 * y + 3 * z - 3)

ml = {x: 0, y: 1, z: 1}

print("assignment =", ml)
print("f(0,1,1) =", f(ml))

このプログラムでは、辞書 ml = {x: 0, y: 1, z: 1} で $x=0$, $y=1$, $z=1$ の割り当てを定義し、 f(ml) が $f(0,1,1)$ の値を返します。 このプログラムの出力は以下の通りです:

assignment = {x: 0, y: 1, z: 1}
f(0,1,1) = 4

あるいは、辞書リテラルとして直接、または (変数, 値) のタプルのリストとして 割り当てを与えることもできます:

import pyqbpp as qbpp

x = qbpp.var("x")
y = qbpp.var("y")
z = qbpp.var("z")
f = qbpp.sqr(x + 2 * y + 3 * z - 3)

print("f(0,1,1) =", f({x: 0, y: 1, z: 1}))
print("f(0,1,1) =", f([(x, 0), (y, 1), (z, 1)]))

辞書形式とタプルのリスト形式は等価で、同じ結果を返します。

Solを使った評価

解(Sol)を使って式の値を評価することもできます。 そのためには、まず与えられた式 f に関連付けた解 sol を構築します。 新しく作成された解は、すべてゼロの割り当てで初期化されます。

sol.set(x, value) メソッドで、個々の変数に値を割り当てられます。 そして、f(sol)sol(f) のどちらも、sol に格納された割り当ての下での 式 f の値を返します。 さらに、comp_energy() メソッドも同じ値を計算して返します。

import pyqbpp as qbpp

x = qbpp.var("x")
y = qbpp.var("y")
z = qbpp.var("z")
f = qbpp.sqr(x + 2 * y + 3 * z - 3)
f.simplify_as_binary()

sol = qbpp.Sol(f)
sol.set(y, 1)
sol.set(z, 1)

print("f(0,1,1) =", f(sol))
print("f(0,1,1) =", sol(f))
print("f(0,1,1) =", sol.comp_energy())

sol のメソッド comp_energy() はエネルギー値を計算し、 解の内部にキャッシュすることに注意してください。 また、ソルバーが返す解は、既にエネルギー値が計算されキャッシュされています。 再計算せずにエネルギーを取得するには、以下に示すように energy プロパティを使用できます:

import pyqbpp as qbpp

x = qbpp.var("x")
y = qbpp.var("y")
z = qbpp.var("z")
f = qbpp.sqr(x + 2 * y + 3 * z - 4)
f.simplify_as_binary()

solver = qbpp.EasySolver(f)
sol = solver.search(target_energy=0)

print("sol =", sol)
print("energy =", sol.energy)

sol.flip(z)
print("flipped sol =", sol)
print("flipped energy =", sol.energy)

このプログラムでは、sol.energy は正しく 0 を返します。 しかし、変数 z をフリップした後、キャッシュされたエネルギー値は無効になります。 エネルギーを再計算せずに sol.energy にアクセスすると、以下のように ランタイムエラーが発生します:

sol = 0:{{x,1},{y,0},{z,1}}
energy = 0
RuntimeError: energy is not up to date; call comp_energy() after modifying the solution

この問題を解決するには、解を変更した後に sol.comp_energy() を呼び出して エネルギーを明示的に再計算する必要があります:

print("sol =", sol)
print("energy =", sol.energy)

sol.flip(z)
print("sol.comp_energy() =", sol.comp_energy())
print("flipped sol =", sol)
print("flipped energy =", sol.energy)

このプログラムは以下の出力を生成します:

sol = 0:{{x,1},{y,0},{z,1}}
energy = 0
sol.comp_energy() = 9
flipped sol = 9:{{x,1},{y,0},{z,0}}
flipped energy = 9

comp_energy() を呼び出した後は、sol.energy プロパティも正しい(再計算後の) エネルギーを返します。


Back to top

Page last modified: 2026.05.12.