{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 9-Solving Graph Coloring Problem with PyQUBO\n", "この節では、[Ising formulations of many NP problems](https://arxiv.org/pdf/1302.5843v3.pdf) から6.1. Graph ColoringをPyQUBOを用いて解きます。" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "view-in-github" }, "source": [ "[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/OpenJij/OpenJijTutorial/blob/master/source/ja/009-GraphColorPyqubo.ipynb)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### グラフ彩色問題\n", "グラフ彩色問題は以下のような状況の最適解を求める問題であり、NP完全問題の一つです。まずは具体的な問から考えてみましょう。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 具体例\n", "分かりやすくするために具体的に以下のような問を考えます。\n", "> 10個のノードと20本の枝を持つ無効グラフが与えられたとします。枝で繋がれたノード同士は異なる色となるようにノードを色分けする時、3色で全てのノードを塗ることは可能であるか考えます。\n", "> グラフは下のようになっているとします。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " \n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> 塗り分けた後のグラフは下のようになります。\n", "> このグラフから全てのノードは3色で塗り分けることができると分かります。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " \n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 問題の一般化\n", "無効グラフ$G=(V,E)$が与えられるとします。辺で結ばれたノードの色が重複しないように全てのノードを$n$色で塗り分けることができるか考えます。\n", "\n", "全てのノードが$v$をindexとして持つとします。\n", "\n", "\n", "ノードの色分けはバイナリ変数$x$で表すことにしましょう。$x_{v,i}$はノード$v$が色$i$で塗られている時に1,その他の状態では0をとります。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## QUBO行列への変換\n", "ハミルトニアンは以下のように定めることができます。\n", "\n", "$$H = A\\sum_{v=1}^V\\left(1-\\sum_{i=1}^n x_{v,i}\\right)^2\n", "+ A\\sum_{(uv)\\in E}\\sum_{i=1}^nx_{u,i}x_{v,i}$$\n", "\n", "第一項はそれぞれのノードは必ず一色に塗られるという制約です。第二項は辺で繋がれたノードの色は異なるという制約です。これらが破られる度に$H$は増加します。\n", "\n", "$H=0$となる状態が見つかった時、グラフ$G$は$n$色で塗ることが可能だと分かります。\n", "\n", "また、$x_{v,i}$でどのiの時$x_{v,i}=1$となるか調べることでノード$v$の色を調べることができます。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## PyQUBOへの実装\n", "### QUBO行列の生成\n", "上記の例で示したグラフの彩色問題を実際にQUBO行列にしてPyQUBOを用いて解いてみます。\n", "まず、グラフの頂点数、塗り分けるのに使う色の数、辺を定義します。" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "#頂点数\n", "N_VER = 10\n", "#色の数\n", "N_COLOR = 4\n", "#辺の数\n", "N_EDGE = 20\n", "#辺のリスト\n", "graph = [(7, 5), (1, 6), (9, 0), (8, 9), (1, 2), (0, 6), (3, 4), (8, 2), (7, 1), (1, 5), (7, 0), (2, 4), (9, 3), (2, 0), (0, 1)]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "次にバイナリ変数xを定義します。" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "#PYQUBOをimportします\n", "from pyqubo import Array\n", "#QUBOを表現する変数(頂点数×色の数)\n", "x = Array.create('x', shape=(N_VER,N_COLOR), vartype='BINARY')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "この変数を用いてハミルトニアンを定義します。" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "from pyqubo import Constraint\n", "# ハミルトニアンの第一項 (各頂点に1色だけ塗る)\n", "H_A = Constraint(sum((1-sum(x[v,i] for i in range(1,N_COLOR)))**2 for v in range(N_VER)), label='HA')\n", "# ハミルトニアンの第二項 (辺で結ばれた頂点が同じ色で塗られていないか)\n", "H_B = sum(sum(x[u,i] * x[v,i] for i in range (1,N_COLOR)) for u,v in graph)\n", "# ハミルトニアン全体を定義します\n", "Q = H_A+H_B" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 実行結果\n", "\n", "ハミルトニアンをコンパイルしてto_qubo()でQUBOに変換します。\n", "quboにはPythonの辞書型で格納されたQUBOが、そしてoffsetにはQUBO化した際に現れる定数(無視してよい)が代入されます。\n", "\n", "では、これをSimulated Annealingのソルバーで解いて結果を見てみましょう。" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Defaulting to user installation because normal site-packages is not writeable\n", "Requirement already up-to-date: networkx in /home/jiko/.local/lib/python3.8/site-packages (2.5)\n", "Requirement already satisfied, skipping upgrade: decorator>=4.3.0 in /home/jiko/.local/lib/python3.8/site-packages (from networkx) (4.4.2)\n" ] } ], "source": [ "!pip install --upgrade networkx" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[Result]\n", "\n", "{'x[9][3]': 1, 'x[9][2]': 0, 'x[8][3]': 0, 'x[8][1]': 0, 'x[7][3]': 0, 'x[7][2]': 0, 'x[9][1]': 0, 'x[6][3]': 0, 'x[0][3]': 0, 'x[4][3]': 1, 'x[2][1]': 1, 'x[1][1]': 0, 'x[1][2]': 0, 'x[2][2]': 0, 'x[3][1]': 1, 'x[3][2]': 0, 'x[1][3]': 1, 'x[0][2]': 1, 'x[6][1]': 1, 'x[3][3]': 0, 'x[8][2]': 1, 'x[4][1]': 0, 'x[4][2]': 0, 'x[0][1]': 0, 'x[5][1]': 0, 'x[2][3]': 0, 'x[5][2]': 1, 'x[5][3]': 0, 'x[6][2]': 0, 'x[7][1]': 1}\n", "\n", "broken\n", "{}\n", "\n", "['skyblue', 'yellowgreen', 'plum', 'plum', 'yellowgreen', 'skyblue', 'plum', 'plum', 'skyblue', 'yellowgreen']\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "model = Q.compile()\n", "qubo, offset = model.to_qubo()\n", "from pyqubo import solve_qubo\n", "\n", "# nealを用いて問題を解きます。\n", "import neal\n", "sampler = neal.SimulatedAnnealingSampler()\n", "raw_solution = sampler.sample_qubo(qubo)\n", "decoded_sample = model.decode_sample(raw_solution.first.sample, vartype=\"BINARY\")\n", "\n", "#結果の表示\n", "print(\"[Result]\")\n", "print()\n", "print(decoded_sample.sample)\n", "print()\n", "\n", "#制約を守れているか見ます\n", "print(\"broken\")\n", "print(decoded_sample.constraints(only_broken=True))\n", "print()\n", "\n", "#グラフを表示します\n", "import networkx as nx\n", "\n", "G = nx.Graph()\n", "G.add_nodes_from([str(i) for i in range(1,11)])\n", "graph2 =[(str(a+1),str(b+1)) for a,b in graph]\n", "G.add_edges_from(graph2)\n", "cl=[\"plum\",\"skyblue\",\"yellowgreen\"]\n", "colors = []\n", "for i in range(0,N_VER):\n", " for j in range(1,N_COLOR):\n", " if decoded_sample.array('x', (i,j))==1:\n", " colors.append(cl[j-1])\n", "print(colors)\n", "nx.draw(G, with_labels=True, font_weight='bold',node_color = colors)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## OpenJijに投げる\n", "次にOpenJijのSAで解いてみましょう" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{0: {1: 1, 2: 0, 3: 0},\n", " 1: {1: 0, 2: 0, 3: 1},\n", " 2: {1: 0, 2: 1, 3: 0},\n", " 3: {1: 0, 2: 0, 3: 1},\n", " 4: {1: 1, 2: 0, 3: 0},\n", " 5: {1: 1, 2: 0, 3: 0},\n", " 6: {1: 0, 2: 1, 3: 0},\n", " 7: {1: 0, 2: 1, 3: 0},\n", " 8: {1: 1, 2: 0, 3: 0},\n", " 9: {1: 0, 2: 1, 3: 0}}" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# OpenJijのインポートをします\n", "import openjij as oj\n", "# SQAを使います。\n", "sampler = oj.SASampler()\n", "# PYQUBOで使ったquboを使います。\n", "response = sampler.sample_qubo(Q=qubo)\n", "# エネルギーが一番低い状態を取り出します。\n", "dict_solution = response.first.sample\n", "# デコードします。\n", "decoded_sample = model.decode_sample(dict_solution, vartype=\"BINARY\")\n", "# 辞書型をsortして見やすくする処理を追加します。\n", "solution = {}\n", "for i in range(N_VER):\n", " solution[i] = {}\n", " for j in range(1,N_COLOR):\n", " solution[i][j] = decoded_sample.array('x', (i, j))\n", "solution" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "グラフがどのように色が塗られるか見てみましょう。" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "broken\n", "{}\n", "\n", "['plum', 'yellowgreen', 'skyblue', 'yellowgreen', 'plum', 'plum', 'skyblue', 'skyblue', 'plum', 'skyblue']\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "print(\"broken\")\n", "print(decoded_sample.constraints(only_broken=True))\n", "print()\n", "cl=[\"plum\",\"skyblue\",\"yellowgreen\"]\n", "colors = []\n", "for i in range(0,N_VER):\n", " for j in range(1,N_COLOR):\n", " if decoded_sample.array('x', (i,j))==1:\n", " colors.append(cl[j-1])\n", "print(colors)\n", "nx.draw(G, with_labels=True, font_weight='bold',node_color = colors)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "結果を見ると制約を満たしつつ全てのノードを3色で塗り分けられていると分かります。" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "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.9.3" } }, "nbformat": 4, "nbformat_minor": 4 }