common.title

Docs
Quantum Circuit
TYTAN CLOUD

QUANTUM GAMING

Nobisuke

Dekisugi


autoQAOA
DEEPSCORE

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

こんにちは、今日は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>

image

次に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>

image

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

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

image

早速解いてみますが、シミュレータでやってみます。調整変数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>

image

きちんとイジングとしてクラスタリングができています。上の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>

image

データは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]

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

© 2025, blueqat Inc. All rights reserved