Nobisuke
Dekisugi
RAG
Privacy policy
2021/04/16 01:37
2
こんにちは、今日はblueqat cloudを利用して簡単なクラスタリングを実行したいと思います。こちらはまだAPIを作ったばかりなので、フロントエンドのツール類はこれから少しずつ提供される予定なので、現時点ではちょっと煩雑かもしれませんが、楽しめる方は見ていただけると幸いです。
このファイルは、記事ページから直接blueqat cloudの自分のアカウントにimportできる機能が付いています。クラウドのダウンロードマークを押すと自分のblueqat cloudのフォルダにimportされます。
API関連整備 まずはツール類を読み込み関数を作ります。ポイントはタスクを投げるところ、回収するところです。APIのキーは事前に.passというテキストファイルに記述しておいてあり、そっから読み込んでます。
Copy 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量子ビット必要です。
Copy n_node = 20 n_cluster = 2 N = n_node*n_cluster print(N)
40
適当にデータを作ります。
Copy 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>
次にqubo matrixと呼ばれる問題設定をします。
Copy #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
きちんとできているかどうか確認します。まずはネットワークグラフでの確認。
Copy #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>
次は行列自体を可視化してみます。
Copy plt.imshow(qubo) plt.colorbar() plt.show()
<Figure size 432x288 with 2 Axes>
早速解いてみますが、シミュレータでやってみます。調整変数Mを導入して50にしてみます。そして、先ほどの散布図に色として導入します。
Copy #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>
きちんとイジングとしてクラスタリングができています。上の20という数字は0が20こ、1が20こ、合計20となっているので、クラスタリングできている目安として使っています。続いてblueqat cloudを利用して実機のD-Wave Advantageを利用してみます。今回はquboを作ると、自動的にサーバーサイドで実機の接続に直して埋め込んでくれます。1000回の実行となっています。
Copy 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>
データは1000回計算した結果が、表として得られました。今回はそれをさらにエネルギー値でソートし、一番低いエネルギーの解が一番正解に近いということで取り出しました。チェーンの接続強さとかを調整するともっと良い解が得られますが、今回はデフォルトでやってみました。テーブルは参考に下記のようになりました。
Copy 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