はじめに
D-Waveというカナダのベンチャー企業の量子アニーリングマシンをクラウド経由で使えるサービスがあります。日本からも使えますが、日本語訳がないので簡単に見返してみます。
「約17億円の量子コンピューターをクラウドで貸し出すD-WAVEの「Leap」、ついに日本でも正式公開」
https://jp.techcrunch.com/2019/03/26/d-wave-leap/
D-Wave OceanとLEAP
D-Wave OceanとLEAPを組み合わせて使います。LEAPで登録をして、そこでAPIキーというものをもらって実機に投げます。その際に使うツールがOceanで、Oceanはpythonという言語で動きます。
LEAP
https://cloud.dwavesys.com/leap/login/?next=/leap/
Ocean
https://github.com/dwavesystems/dwave-ocean-sdk
Oceanはpythonのpipと呼ばれるパッケージ管理で、
pip install dwave-ocean-sdk
のようにインストールできます。今回は、
・古典ソルバー(シミュレータ)
・実機ソルバー
・ネットワークグラフ
・大規模問題分割
を見てみたいと思います。
早速使ってみる
早速量子アニーリングを実行する際に必要な知識として、シミュレータと実機があります。
シミュレータは手持ちのコンピュータで模擬的な計算をします。十分早いですが。。。
実機はクラウドでカナダのマシンにつなげます。繋げる際にはいくつかの指定がありますので、それも確認してみます。
公式ドキュメントはこちらです。
https://docs.ocean.dwavesys.com/en/latest/
シミュレータ(厳密解ソルバー)
シミュレータは二種類あります。まずは厳密解ソルバーです。
小さい問題の場合に使えます。python環境を準備して、
#ツール読み込み
import dimod
#ソルバーの選択
solver = dimod.ExactSolver()
#イジングの準備
response = solver.sample_ising({'a': -0.5, 'b': 1.0}, {('a', 'b'): -1})
#エネルギーを返す
response.data_vectors['energy']
#=>array([-1.5, -0.5, -0.5, 2.5])
こちらはdimodツールでExactSolverという全部の厳密解を出してくれるツールです。小さい系での確かめにとても便利そうです。上記はaとbでそれぞれ{-1,+1}という値をとる量子ビットに対して、局所磁場と相互作用というものが設定の通りに設定されている状況での厳密解をエネルギーで求めています。
1.5,-0.5,-0.5,2.5の値がでてきています。これではちょっとわかりにくいので、
import dimod
solver = dimod.ExactSolver()
response = solver.sample_ising({'a': -0.5, 'b': 1.0}, {('a', 'b'): -1})
for datum in response.data(['sample', 'energy']):
print(datum.sample, datum.energy)
#=>
{'a': -1, 'b': -1} -1.5
{'a': 1, 'b': -1} -0.5
{'a': 1, 'b': 1} -0.5
{'a': -1, 'b': 1} 2.5
こうするとaとbの組み合わせと対応するエネルギーの関係がわかりやすくなります。
上記はたとえばa=-1,b=-1のときは、
−0.5∗(−1)+1∗(−1)+(−1)∗(−1)∗(−1)=0.5−1−1=−1.5
となります。
近似解ソルバー
シミュレーテッドアニーリングベースの近似解ソルバーです。近似解ソルバーはその都度答えが変わりますので、厳密解みたいにきちんと答えは出ないで確率的にでます。
import neal
solver = neal.SimulatedAnnealingSampler()
response = solver.sample_ising({'a': -0.5, 'b': 1.0}, {('a', 'b'): -1}, num_reads=2)
response.data_vectors['energy']
#=>array([-1.5, -1.5])
こちらはSA(シミュレーテッドアニーリング)なので基底状態に近いものがでます。
実機のソルバー
実機はOcean経由で同様に使えますが、アクセスするためのパスワードのようなtokenが必要になります。こちらはD-WaveのLEAPに登録することで入手できます。登録は、
https://cloud.dwavesys.com/leap/
こちらより。登録が終わってログインすると、左側にAPI tokenというのがあるのでこれのcopyをおします。
早速tokenをつかってやってみましょう。python環境で、
from dwave.cloud import Client
client = Client.from_config(token='ABC-123456789123456789123456789')
client.get_solvers()
D-Waveをクラウド経由で接続するD-Wave cloud client経由でtokenを入れてclientを指定します。クライアントにはsolverがいくつか用意されています。
[Solver(id='DW_2000Q_2_1'), Solver(id='DW_2000Q_VFYC_2_1')]
実行すると2つ出てきました。1つは実機、もうひとつVFYCというのはVirtual Full-Yield Chimera Solverの略で、通常量子アニーリングマシンは量子ビットに欠損が出て、それを回避するように実行する必要がありますが、これは既存計算機でその部分を補完して計算をするものです。
config
毎回tokenを入れて実行するのも大変なので、通常は設定ファイルを用意します。ターミナル(python環境ではなく)で、
dwave config create
として、手順に沿って設定することで設定ができます。
https://docs.ocean.dwavesys.com/en/latest/overview/dwavesys.html
問題は、
from dwave.system.samplers import DWaveSampler
from dwave.system.composites import EmbeddingComposite
sampler = EmbeddingComposite(DWaveSampler())
response = sampler.sample_ising({'a': -0.5, 'b': 1.0}, {('a', 'b'): -1})
response.data_vectors['energy']
array([-1.5])
こうすることで実機に投げて答えが戻ります。D-WaveのLEAPに問題を投げた履歴が見れる項目があります。
実際に投げられたのを確認できます。configを使わない場合は下記のように投げます。
from dwave.system.samplers import DWaveSampler
from dwave.system.composites import EmbeddingComposite
sampler = EmbeddingComposite(DWaveSampler(endpoint='https://cloud.dwavesys.com/sapi', token='ABC-123456789012345678901234567890', solver='DW_2000Q_2_1'))
response = sampler.sample_ising({'a': -0.5, 'b': 1.0}, {('a', 'b'): -1})
response.data_vectors['energy']
ネットワーク問題
頂点被覆問題vertex coverという例題を見ます。D-Waveはプロセッサの形がネットワークをしていて、ネットワーク問題を解きやすい形式になっています。
通常networkxというツールを使います。ここではスター型のネットワークを構成し、中央に位置する量子ビットを計算で判別します。
import networkx as nx
s5 = nx.star_graph(4)
描画するにはmatplotlibというツールを使います。
import matplotlib.pyplot as plt
nx.draw_networkx(s5)
plt.show()
これをD-Waveで解くのは簡単です。
from dwave.system.samplers import DWaveSampler
from dwave.system.composites import EmbeddingComposite
import dwave_networkx as dnx
sampler = EmbeddingComposite(DWaveSampler())
print(dnx.min_vertex_cover(s5, sampler))
#=>[0]
0という答えが出てきました。dnxのなかにvertex coverのソルバーが入っていました。このようにネットワーク問題を解くことができます。
大規模問題分割qbsolv
D-Waveは2000量子ビットと呼ばれる単位で計算をします。それよりも大きな問題になると大規模問題分割が必要です。大規模問題分割用のツールのqbsolvを使います。qbsolvはQUBOと呼ばれる基本的なD-Wave向けの立式とソーバルという最適化アルゴリズムをハイブリッドで使います。
https://github.com/dwavesystems/qbsolv
インストールは、
pip install dwave-qbsolv
使い方は、
from dwave_qbsolv import QBSolv
Q = {(0, 0): 1, (1, 1): 1, (0, 1): 1}
response = QBSolv().sample_qubo(Q)
print("samples=" + str(list(response.samples())))
print("energies=" + str(list(response.data_vectors['energy'])))
このように使いますが、これに関してはより詳細な記事を書いてみたいと思います。
まとめ
このようにネットワーク問題を使いながらいろんな問題が解けます。ぜひ実機を使って色々やってみてくださいませ。