質問がありましたので書こうと思います。こちらのtabataさんの二年前の記事ですが、SDKもそのころからだいぶ変わっていますので、最新のコードを書いてみます。
量子コンピュータの応用 - VQEの基本とこれを応用した組合せ最適化問題のプログラミング
https://blueqat.com/tetsurotabata/d8553b7e-4575-48a7-8427-457cd6748d94
from blueqat import Circuit
from blueqat.pauli import qubo_bit as q
import scipy.optimize as optimize
import numpy as np
H = 5 - 3*q(0)/2 - 3*q(1)/2 - 3*q(2)/2 - 5*q(3)/2 - 1*q(4)/2 + q(0)*q(1) + q(0)*q(3) + q(1)*q(2) + q(2)*q(3) + q(3)*q(4) # ハミルトニアンの定義
def f(params, mode=1, shots=1000, amplitude = "00000"):
a, b, c, d, e, f, g, h, i, j= params
circ = Circuit().ry(a)[0].rz(b)[0].ry(c)[1].rz(d)[1].ry(e)[2].rz(f)[2].ry(g)[3].rz(h)[3].ry(i)[4].rz(j)[4]
if mode == 1:
res = circ.run(hamiltonian = H)
elif mode == 2:
res = circ.run(shots=shots)
elif mode == 3:
res = circ.run(backend="draw")
elif mode == 4:
res = circ.run(amplitude = amplitude)
return res
initial_guess = np.array([np.random.rand() for _ in range(10)])
result = optimize.minimize(f, initial_guess, method="Powell",
options={
"ftol": 5.0e-2,
"xtol": 5.0e-2,
"maxiter": 1000
})
f(result.x, mode=2, shots=1000)
Counter({'10110': 1000})
最大の違いは状態ベクトルを使わなくなったということですね。期待値は求めやすくなりました。振幅を確認したい場合は、個別で求めます。
amp = f(result.x, mode=4, amplitude="01010")
prob = np.abs(amp)**2
print(amp)
print(prob)
(0.07418534390086429-0.997244136098726j)
0.9999993322329834
以上です。