common.title
Cloud support

TYTAN CLOUD
QUANTUM GAMING

Nobisuke

Dekisugi

RAG


autoQAOA
RAG for dev
DEEPSCORE
Translation

Overview
Service overview
Terms of service

Privacy policy

Contact
Research

Sign in
Sign up
common.title

blueqat cloud経由でのD-Waveでのクラスタリング問題

Yuichiro Minato

2021/04/16 01:37

#量子アニーリング #blueqat cloud

2

こんにちは、今日はblueqat cloudを利用して簡単なクラスタリングを実行したいと思います。こちらはまだAPIを作ったばかりなので、フロントエンドのツール類はこれから少しずつ提供される予定なので、現時点ではちょっと煩雑かもしれませんが、楽しめる方は見ていただけると幸いです。

このファイルは、記事ページから直接blueqat cloudの自分のアカウントにimportできる機能が付いています。クラウドのダウンロードマークを押すと自分のblueqat cloudのフォルダにimportされます。

API関連整備 まずはツール類を読み込み関数を作ります。ポイントはタスクを投げるところ、回収するところです。APIのキーは事前に.passというテキストファイルに記述しておいてあり、そっから読み込んでます。

import json import urllib.request import numpy as np import pandas as pd import networkx as nx from blueqat.wq import * import matplotlib.pyplot as plt %matplotlib inline f = open('.pass', 'r', encoding='UTF-8') API_KEY = f.read()[:-1] f.close() API_ENDPOINT = "https://cloudapi.blueqat.com/v1/" def post_request(path, body): headers = { 'Content-Type': 'application/json', 'X-Api-Key': API_KEY, } req = urllib.request.Request( API_ENDPOINT + path, json.dumps(body).encode(), headers) with urllib.request.urlopen(req) as res: body = res.read() return json.loads(body) def get_quantum_tasks(index): path = "quantum-tasks/list" body = { "index": index, } return post_request(path, body) def get_quantum_task(id): path = "quantum-tasks/get" body = { "id": id, } return post_request(path, body) def create_quantum_task(qubo, num_reads, chain_strength=8): path = "quantum-tasks/create" body = { "qubo": qubo, "num_reads": num_reads, "chain_strength": chain_strength } return post_request(path, body) def get_credit(): path = "credit/get" return post_request(path, {})

次に、クラスタリングを進めます。こちらは以前行った記事をベースに組み立てます。 https://blueqat.com/yuichiro_minato2/af8fa7e9-d020-4a92-a3e1-fecf43bafb0a

今回は20ノードを2つのクラスタに分けます。全部で40量子ビット必要です。

n_node = 20 n_cluster = 2 N = n_node*n_cluster print(N)
40

適当にデータを作ります。

x = np.random.normal(0, 1.5, int(n_node/2)) y = np.random.normal(0, 1.5, int(n_node/2)) x = np.append(x, np.random.normal(5, 1.5, int(n_node/2))) y = np.append(y, np.random.normal(5, 1.5, int(n_node/2))) # 散布図を描画 plt.scatter(x, y)
<matplotlib.collections.PathCollection at 0x7fd0d75df3d0>
<Figure size 432x288 with 1 Axes>output

次にqubo matrixと呼ばれる問題設定をします。

#initialize distance d = np.zeros((n_node,n_node)) for i in range(0, n_node-1): for j in range(i+1, n_node): a = np.array([x[i],y[i]]) b = np.array([x[j],y[j]]) d[i][j] = np.linalg.norm(a-b) #map distance to qubo A = np.zeros((N,N)) for i in range(0, n_node-1): for j in range(i+1, n_node): A[i*2][j*2] = A[i*2+1][j*2+1] = d[i][j] #initialize constraint B = np.zeros((N,N)) for i in range(N): B[i][i] = -1 for i in range(n_node): B[i*2][i*2+1] = 2

きちんとできているかどうか確認します。まずはネットワークグラフでの確認。

#set a QUBO M = 1 qubo = A+B*M #show as network G = nx.from_numpy_matrix(qubo) nx.draw_networkx(G) plt.show()
<Figure size 432x288 with 1 Axes>output

次は行列自体を可視化してみます。

plt.imshow(qubo) plt.colorbar() plt.show()
<Figure size 432x288 with 2 Axes>output

早速解いてみますが、シミュレータでやってみます。調整変数Mを導入して50にしてみます。そして、先ほどの散布図に色として導入します。

#to simulator M = 50 qubo = A+B*M a = Opt() a.qubo = qubo res = a.run() print(sum(res)) plt.scatter(x, y, c=res[::2])
20
<matplotlib.collections.PathCollection at 0x7fd0d72901f0>
<Figure size 432x288 with 1 Axes>output

きちんとイジングとしてクラスタリングができています。上の20という数字は0が20こ、1が20こ、合計20となっているので、クラスタリングできている目安として使っています。続いてblueqat cloudを利用して実機のD-Wave Advantageを利用してみます。今回はquboを作ると、自動的にサーバーサイドで実機の接続に直して埋め込んでくれます。1000回の実行となっています。

num_reads = 10000 #to D-Wave Advantage M = 100 qubo = (A+B*M).tolist() result = create_quantum_task(qubo, num_reads) table = pd.read_json(result["task"]["dataframe"]).sort_values('energy') result2 = table.loc[0][0:N].astype('int').to_list() print(sum(result2)) plt.scatter(x, y, c=result2[::2])
16
<matplotlib.collections.PathCollection at 0x7fd0d6fd3f40>
<Figure size 432x288 with 1 Axes>output

データは1000回計算した結果が、表として得られました。今回はそれをさらにエネルギー値でソートし、一番低いエネルギーの解が一番正解に近いということで取り出しました。チェーンの接続強さとかを調整するともっと良い解が得られますが、今回はデフォルトでやってみました。テーブルは参考に下記のようになりました。

table
      0  1  2  3  4  5  6  7  8  9  ...  33  34  35  36  37  38  39  \

27    1  0  0  1  0  1  0  1  0  1  ...   0   1   0   1   0   1   0   

625   0  1  1  0  1  0  1  0  0  1  ...   1   0   1   0   1   1   0   

2050  1  0  0  1  0  1  0  1  0  1  ...   1   1   0   1   0   1   0   

4971  1  0  0  1  0  1  0  1  1  0  ...   1   1   0   1   0   0   1   

4174  0  1  0  1  0  1  0  0  0  1  ...   0   1   0   1   0   0   1   

...  .. .. .. .. .. .. .. .. .. ..  ...  ..  ..  ..  ..  ..  ..  ..   

9104  1  0  0  1  1  0  0  1  0  0  ...   0   0   0   0   1   0   1   

3233  1  0  1  0  0  1  1  0  1  1  ...   0   0   0   0   0   0   0   

9797  0  1  1  0  0  0  1  1  0  0  ...   1   0   0   1   0   0   0   

9958  0  1  1  1  1  1  0  0  0  1  ...   0   0   1   0   1   1   1   

8870  1  0  1  1  0  0  0  0  0  1  ...   0   1   1   1   1   1   1   



      chain_break_fraction       energy  num_occurrences  

27                   0.200 -1668.444513                1  

625                  0.225 -1658.498630                1  

2050                 0.250 -1655.938749                1  

4971                 0.250 -1624.865138                1  

4174                 0.275 -1609.859855                1  

...                    ...          ...              ...  

9104                 0.475  -587.514587                1  

3233                 0.425  -538.120855                1  

9797                 0.475  -499.884221                1  

9958                 0.475  -472.141642                1  

8870                 0.475  -337.330693                1  



[10000 rows x 43 columns]

調整変数の調整などで多少改善しますが、今回はランダムで作成した座標データの係数が細かいと実機への搭載時にやはり課題となりそうです。今回は以上です。

© 2024, blueqat Inc. All rights reserved