はじめに
以前に過去記事でDwaveのleapを使った量子アニーリングの試行結果を整理していましたが、あれから1年半が経過し、pyquboやOpenjij等、いくつか便利なツールが増えていることが分かったので、本記事はそれらを試行した結果を整理しました。
Qubo等の基本的な概念を理解されている前提で記述を進めているので、疑問点を感じられた方は以下の記事を一度読んでいただけるとありがたいです。
D-Waveで量子アニーリングを解くために必要な手順:
D-WaveのLeapのサンプルプログラムをPythonで動作させてみた
ナップサック問題を対象とした問題の定式化とQUBOモデル作成:
D-WaveのLeapを使ってナップサック問題を量子アニーリングで解いてみた
参考文献
もっと導入の考え方である、イジングモデルやスピングラス、キメラグラフといった用語は以下を読んで勉強しました。
使用ライブラリ
以下のライブラリを使用しています。いずれもpipでインストール可能です。
pyqubo == 0.4.0
openjij == 0.0.11
pyqubo
pyquboが登場する以前は、量子アニーリングを実行するためには以下の手順が必要でしたが、pyquboを用いることでこの「2」の工程が不要になり、さらに「3」のコーディングもシンプルにできるようになりました。
- 組み合わせ最適化問題の定式化
- 数式を展開し2次形式に変換
- コーディング
具体的に見ていきます。組み合わせ最適化問題の定式化とは、ナップサック問題であれば以下のような状態の式を作るところまでを指しています。
ここからquboモデルを作るまでのコーディングが以下で済むようになりました。
from pyqubo import Array, Constraint #荷物の入れる/入れない x = Array.create('x', n, 'BINARY') #スラック変数 s = Array.create('s', margin, 'BINARY') #価値 total_value = sum(x_i * v_1 for x_i, v_1 in zip(x, values)) #重さ total_weight = sum(x_i * w_1 for x_i, w_1 in zip(x, weights)) #ハミルトニアン H = -1 * total_value + alpha * Constraint((total_weight - weight_limit + sum(s_i for s_i in s))**2, label='weight_limit') #quboモデル model = H.compile() qubo, offset = model.to_qubo()
従来は以下のように式を展開した上で
以下のような複雑なコードを書いてquboを定義しなければいけませんでしたので、pyquboにより大幅に手間が改善できるようになったと感じました。
Q = dict() for i in range(n+weight_limit): for j in range(n+weight_limit): if i==j: if i < n: Q.update({("x"+str(i), "x"+str(i)):-value[i]+alpha*weight[i]**2}) else: Q.update({("x"+str(i), "x"+str(i)):alpha*c[i-n]**2}) elif i > j: if (i < n) & (j < n): Q.update({("x"+str(i), "x"+str(j)):2*alpha*weight[i]*weight[j]}) elif (i >= n) & (j < n): Q.update({("x"+str(i), "x"+str(j)):-2*alpha*c[i-n]*weight[j]}) else: Q.update({("x"+str(i), "x"+str(j)):2*alpha*c[i-n]*c[j-n]}) else: continue
openjij
openjijは各種量子アニーリングAPIに対して同様のIFでのアクセスができることを目指したライブラリで、D-waveやその他の量子アニーリングのベンチマークをすることが可能です。また、ローカル環境においても、シミュレーテッド・アニーリング手法を実行することができ、APIの問題なのか定式化の問題なのかを切り分けることが出来るようになりました。
# OpenJijで解く sampler = oj.SASampler() response = sampler.sample_qubo(qubo, num_reads=1000)
コーディングは上記の通り、非常にシンプルなコードで動作させることが出来ました。また、例えばこのoj.SASamplerの部分を「oj.CMOSAnnealer」に変更すれば、同様のコードでNEDOがAnnealing Cloud Web で提供している量子アニーリングライブラリを使うことが出来ることも確認できました。
まとめ
pyquboとopenjijの登場により、量子アニーリングを試すまでのハードルはかなり下がりました。これにより、これまでは動作させるだけで精いっぱいだったところが、量子アニーリングソルバーのパラメータの理解等やパラメータ調整など、より実践的な検討を進めて行けそうです。