Created
June 24, 2021 14:13
-
-
Save shokout/a4b38c4aa336614b3245c073de079097 to your computer and use it in GitHub Desktop.
Amazon Braket のサンプルノートブックです(日本語版)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# D-Wave の基本:最大カット問題を Braket で使う" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"このチュートリアルでは、Amazon BraketのD-Waveデバイスを使用して、有名な __Maximum-Cut (MaxCut)__ 問題の小さなインスタンスを解決します。 MaxCut問題は、組合せ最適化で最も有名なNP困難問題の1つです。 頂点セット $V$ とエッジセット $E$ を持つ無向グラフ $G(V, E)$ が与えられた場合、MaxCut問題は、2つのセット間のエッジの数が最も大きくなるように、 $V$ を2つのセットに分割しようとします。 \n", | |
"\n", | |
"この MaxCut 問題の実アプリケーションとしては、例えばマーケティング目的のクラスタリング問題や、金融のポートフォリオ最適化問題になどが考えられています。\n", | |
"\n", | |
"このハンズオンを実行するのに、0.3019ドル(1タスク + 10ショット 0.0019ドル)かかりますので、予めご了承ください。ジョブを複数投げると、その分コストが発生しますのでご利用の際はご注意ください。" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"免責事項:この例に示されているコードは、[こちら](https://github.com/dwave-examples/maximum-cut) の Github で入手可能な D-Wave チュートリアルから抜粋したものであり、著作権は D-Wave Systems、Inc. にあります。 Apacheライセンスの下でライセンスされています。 下記のスクリプトの目的は、D-Wave の Ocean tool suite を使用する既存のコードを、最小限のコード変更で Amazon Braket で簡単に実行できることを示すことです。" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import json\n", | |
"from braket.aws import AwsDevice\n", | |
"from braket.ocean_plugin import BraketSampler, BraketDWaveSampler" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import matplotlib.pyplot as plt\n", | |
"# magic word for producing visualizations in notebook\n", | |
"%matplotlib inline\n", | |
"import networkx as nx\n", | |
"import dwave_networkx as dnx\n", | |
"from dimod.binary_quadratic_model import BinaryQuadraticModel\n", | |
"from dwave.system.composites import EmbeddingComposite" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### [入力必須] __注__:以下にS3バケットとキーを入力してください。" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# Please enter the S3 bucket you created during onboarding in the code below\n", | |
"my_bucket = \"amazon-braket-Your-Bucket-Name\" # the name of the bucket\n", | |
"my_prefix = \"braket-handson/d-wave\" \n", | |
"s3_folder = (my_bucket, my_prefix)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# session and device\n", | |
"device = AwsDevice(\"arn:aws:braket:::device/qpu/d-wave/DW_2000Q_6\")\n", | |
"print('Device:', device)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## 最大カット問題の設定" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# helper function to plot graph\n", | |
"def get_graph(graph, pos):\n", | |
" \"\"\"\n", | |
" plot colored graph for given solution\n", | |
" \"\"\"\n", | |
" # positions for all nodes\n", | |
" # pos = nx.spring_layout(graph)\n", | |
"\n", | |
" # nodes\n", | |
" nx.draw_networkx_nodes(graph, pos, node_size=700)\n", | |
"\n", | |
" # edges\n", | |
" nx.draw_networkx_edges(graph, pos)\n", | |
"\n", | |
" # labels\n", | |
" nx.draw_networkx_labels(graph, pos, font_size=20, font_family='sans-serif')\n", | |
"\n", | |
" # plot the graph\n", | |
" plt.axis('off')\n", | |
" #plt.savefig(\"figures/random_graph.png\") # save as png\n", | |
" plt.show();" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# Copyright 2019 D-Wave Systems, Inc.\n", | |
"#\n", | |
"# Licensed under the Apache License, Version 2.0 (the \"License\");\n", | |
"# you may not use this file except in compliance with the License.\n", | |
"# You may obtain a copy of the License at\n", | |
"#\n", | |
"# http://www.apache.org/licenses/LICENSE-2.0\n", | |
"#\n", | |
"# Unless required by applicable law or agreed to in writing, software\n", | |
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n", | |
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", | |
"# See the License for the specific language governing permissions and\n", | |
"# limitations under the License.\n", | |
"\n", | |
"# ------ Import necessary packages ----\n", | |
"from collections import defaultdict\n", | |
"\n", | |
"# from dwave.system.samplers import DWaveSampler\n", | |
"# from dwave.system.composites import EmbeddingComposite\n", | |
"\n", | |
"# ------- Set up our graph -------\n", | |
"\n", | |
"# Create empty graph\n", | |
"G = nx.Graph()\n", | |
"\n", | |
"# Add edges to the graph (also adds nodes)\n", | |
"G.add_edges_from([(1,2),(1,3),(2,4),(3,4),(3,5),(4,5)])\n", | |
"\n", | |
"# plot graph\n", | |
"pos = nx.spring_layout(G)\n", | |
"# plot graph with labels\n", | |
"get_graph(G, pos)\n", | |
"\n", | |
"# ------- Set up our QUBO dictionary -------\n", | |
"\n", | |
"# Initialize our Q matrix\n", | |
"Q = defaultdict(int)\n", | |
"\n", | |
"# Update Q matrix for every edge in the graph\n", | |
"for u, v in G.edges:\n", | |
" Q[(u,u)]+= -1\n", | |
" Q[(v,v)]+= -1\n", | |
" Q[(u,v)]+= 2\n", | |
"\n", | |
"# print Q matrix\n", | |
"print('Show Q matrix:', Q)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## 最大カット問題をD-Wave 2000 で解く" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# ------- Run our QUBO on the QPU -------\n", | |
"# Set up QPU parameters\n", | |
"chainstrength = 8\n", | |
"numruns = 10\n", | |
"\n", | |
"# Run the QUBO on the Braket solver from your config file\n", | |
"# set sampler\n", | |
"sampler = BraketDWaveSampler(s3_folder,'arn:aws:braket:::device/qpu/d-wave/DW_2000Q_6')\n", | |
"sampler = EmbeddingComposite(sampler)\n", | |
"response = sampler.sample_qubo(Q, chain_strength=chainstrength, num_reads=numruns)\n", | |
"energies = iter(response.data())\n", | |
"\n", | |
"# ------- Print results to user -------\n", | |
"print('-' * 60)\n", | |
"print('{:>15s}{:>15s}{:^15s}{:^15s}'.format('Set 0','Set 1','Energy','Cut Size'))\n", | |
"print('-' * 60)\n", | |
"for line in response:\n", | |
" S0 = [k for k,v in line.items() if v == 0]\n", | |
" S1 = [k for k,v in line.items() if v == 1]\n", | |
" E = next(energies).energy\n", | |
" print('{:>15s}{:>15s}{:^15s}{:^15s}'.format(str(S0),str(S1),str(E),str(int(-1*E))))\n", | |
"\n", | |
"# ------- Display results to user -------\n", | |
"# Grab best result\n", | |
"# Note: \"best\" result is the result with the lowest energy\n", | |
"# Note2: the look up table (lut) is a dictionary, where the key is the node index\n", | |
"# and the value is the set label. For example, lut[5] = 1, indicates that\n", | |
"# node 5 is in set 1 (S1).\n", | |
"lut = response.lowest().first.sample\n", | |
"\n", | |
"# Interpret best result in terms of nodes and edges\n", | |
"S0 = [node for node in G.nodes if not lut[node]]\n", | |
"S1 = [node for node in G.nodes if lut[node]]\n", | |
"cut_edges = [(u, v) for u, v in G.edges if lut[u]!=lut[v]]\n", | |
"uncut_edges = [(u, v) for u, v in G.edges if lut[u]==lut[v]]\n", | |
"\n", | |
"# Display best result\n", | |
"pos = nx.spring_layout(G)\n", | |
"nx.draw_networkx_nodes(G, pos, nodelist=S0, node_color='r')\n", | |
"nx.draw_networkx_nodes(G, pos, nodelist=S1, node_color='c')\n", | |
"nx.draw_networkx_edges(G, pos, edgelist=cut_edges, style='dashdot', alpha=0.5, width=3)\n", | |
"nx.draw_networkx_edges(G, pos, edgelist=uncut_edges, style='solid', width=3)\n", | |
"nx.draw_networkx_labels(G, pos)\n", | |
"\n", | |
"filename = \"maxcut_plot.png\"\n", | |
"plt.savefig(filename, bbox_inches='tight')\n", | |
"print(\"\\nYour plot is saved to {}\".format(filename))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"__DISCUSSION__:このトイプロブレムの最適なカットサイズは5です。上記の破線で表示されているように、異なる色のノードを接続するすべてのエッジについて、ポイントをスコアリングします(つまり、このエッジをカットします)。 ここでは最大で5つのエッジをカットできます。 このおもちゃの例では、ノード5に優先する色がないため、明らかな$ Z_ {2} $対称性(つまり、2つのサブセットの色の選択は任意)を除いて、複数の最適な縮退解が見つかります。この問題は同等です。 フラストレーションの存在下で、反強磁性基底状態を見つけること(ノード3-4-5のサブグラフにここに存在するように)。" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"---\n", | |
"## APPENDIX" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Original MaxCut example from here: https://github.com/dwave-examples/maximum-cut" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# # Copyright 2019 D-Wave Systems, Inc.\n", | |
"# #\n", | |
"# # Licensed under the Apache License, Version 2.0 (the \"License\");\n", | |
"# # you may not use this file except in compliance with the License.\n", | |
"# # You may obtain a copy of the License at\n", | |
"# #\n", | |
"# # http://www.apache.org/licenses/LICENSE-2.0\n", | |
"# #\n", | |
"# # Unless required by applicable law or agreed to in writing, software\n", | |
"# # distributed under the License is distributed on an \"AS IS\" BASIS,\n", | |
"# # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", | |
"# # See the License for the specific language governing permissions and\n", | |
"# # limitations under the License.\n", | |
"\n", | |
"# # ------ Import necessary packages ----\n", | |
"# from collections import defaultdict\n", | |
"\n", | |
"# from dwave.system.samplers import DWaveSampler\n", | |
"# from dwave.system.composites import EmbeddingComposite\n", | |
"# import networkx as nx\n", | |
"\n", | |
"# import matplotlib\n", | |
"# matplotlib.use(\"agg\")\n", | |
"# from matplotlib import pyplot as plt\n", | |
"\n", | |
"# # ------- Set up our graph -------\n", | |
"\n", | |
"# # Create empty graph\n", | |
"# G = nx.Graph()\n", | |
"\n", | |
"# # Add edges to the graph (also adds nodes)\n", | |
"# G.add_edges_from([(1,2),(1,3),(2,4),(3,4),(3,5),(4,5)])\n", | |
"\n", | |
"# # ------- Set up our QUBO dictionary -------\n", | |
"\n", | |
"# # Initialize our Q matrix\n", | |
"# Q = defaultdict(int)\n", | |
"\n", | |
"# # Update Q matrix for every edge in the graph\n", | |
"# for u, v in G.edges:\n", | |
"# Q[(u,u)]+= -1\n", | |
"# Q[(v,v)]+= -1\n", | |
"# Q[(u,v)]+= 2\n", | |
"\n", | |
"# # ------- Run our QUBO on the QPU -------\n", | |
"# # Set up QPU parameters\n", | |
"# chainstrength = 8\n", | |
"# numruns = 10\n", | |
"\n", | |
"# # Run the QUBO on the solver from your config file\n", | |
"# sampler = EmbeddingComposite(DWaveSampler(solver={'qpu': True}))\n", | |
"# response = sampler.sample_qubo(Q, chain_strength=chainstrength, num_reads=numruns)\n", | |
"# energies = iter(response.data())\n", | |
"\n", | |
"# # ------- Print results to user -------\n", | |
"# print('-' * 60)\n", | |
"# print('{:>15s}{:>15s}{:^15s}{:^15s}'.format('Set 0','Set 1','Energy','Cut Size'))\n", | |
"# print('-' * 60)\n", | |
"# for line in response:\n", | |
"# S0 = [k for k,v in line.items() if v == 0]\n", | |
"# S1 = [k for k,v in line.items() if v == 1]\n", | |
"# E = next(energies).energy\n", | |
"# print('{:>15s}{:>15s}{:^15s}{:^15s}'.format(str(S0),str(S1),str(E),str(int(-1*E))))\n", | |
"\n", | |
"# # ------- Display results to user -------\n", | |
"# # Grab best result\n", | |
"# # Note: \"best\" result is the result with the lowest energy\n", | |
"# # Note2: the look up table (lut) is a dictionary, where the key is the node index\n", | |
"# # and the value is the set label. For example, lut[5] = 1, indicates that\n", | |
"# # node 5 is in set 1 (S1).\n", | |
"# lut = response.lowest().first.sample\n", | |
"\n", | |
"# # Interpret best result in terms of nodes and edges\n", | |
"# S0 = [node for node in G.nodes if not lut[node]]\n", | |
"# S1 = [node for node in G.nodes if lut[node]]\n", | |
"# cut_edges = [(u, v) for u, v in G.edges if lut[u]!=lut[v]]\n", | |
"# uncut_edges = [(u, v) for u, v in G.edges if lut[u]==lut[v]]\n", | |
"\n", | |
"# # Display best result\n", | |
"# pos = nx.spring_layout(G)\n", | |
"# nx.draw_networkx_nodes(G, pos, nodelist=S0, node_color='r')\n", | |
"# nx.draw_networkx_nodes(G, pos, nodelist=S1, node_color='c')\n", | |
"# nx.draw_networkx_edges(G, pos, edgelist=cut_edges, style='dashdot', alpha=0.5, width=3)\n", | |
"# nx.draw_networkx_edges(G, pos, edgelist=uncut_edges, style='solid', width=3)\n", | |
"# nx.draw_networkx_labels(G, pos)\n", | |
"\n", | |
"# filename = \"maxcut_plot.png\"\n", | |
"# plt.savefig(filename, bbox_inches='tight')\n", | |
"# print(\"\\nYour plot is saved to {}\".format(filename))" | |
] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "conda_braket", | |
"language": "python", | |
"name": "conda_braket" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.7.9" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 4 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment