QUBOもハミルトニアンな気がしますが、最近は仕様が量子アニーリングと量子ゲートで全然違うので苦労しました。最終的にはほぼChatGPTがやってくれました。
量子アニーリングの式を量子ゲートに変換するときの手順は、
1、QUBOやBQMと呼ばれるD-Wave特有のライブラリの値を量子ゲートのハミルトニアンに変換するのを目的とする
2、QUBOやBQMは接続された量子ビット同士の係数が保管されている。量子アニーリングと量子ゲートは量子ビット数が異なるので、量子ゲートはそこまで効率化されたQUBOの書き方を求められてない
3、QUBOやBQMの記述を隣接行列の形に落とし込んで、そこからハミルトニアンに落とし込む
4、隣接行列に落とし込む際に量子アニーリング側で決めた変数に順序をつける必要がある。
ということでやってみます。
まず、PyQUBOでハミルトニアンHがあったとして、それをBQMにします。
#compile to BQM
model = H.compile()
bqm = model.to_bqm()
これは極めて一般的な方法で、QUBO式というものを作ります。
次にBQMは変数が設定されており、必ずしも順番が決まっていません。ここで変数に順番を決めます。
例えば例として、変数がq[i][j]のように連想配列になっている場合、
var_order = [f"q[{i}][{j}]" for i in range(3) for j in range(3)]
bqm.relabel_variables({v: i for i, v in enumerate(var_order)})
このように、variable orderを設定し、それをbqm.relabel_variablesを使って設定します。次にBQMをQUBOに変換。
# BQMをQUBO行列に変換する
qubo = bqm.to_qubo()
そして、量子ビット数9を使って、9*9サイズの隣接行列のQUBO行列を作り、先ほどのQUBOの中身を移植します。
# QUBO行列を隣接行列に変換する
n = 9
adj_matrix = np.zeros((n, n))
for (i, j), value in qubo[0].items():
adj_matrix[i][j] = value
print(adj_matrix)
これで隣接行列ができました。networkxなどを使う方法もあるようです。
そうしたら、from blueqat import pauliでQUBOからblueqatのpauliハミルトニアンに変換します。
これで完成です。
あとは時間発展などを使ってQAOAを解けます。
from blueqat import pauli
from blueqat.utils import qaoa
hamiltonian = pauli.from_qubo(adj_matrix)
step = 1
result = qaoa(hamiltonian, step)
result.circuit.run(shots=100)
以上です。