{ "cells": [ { "cell_type": "markdown", "id": "5ab6812d", "metadata": {}, "source": [ "# Solving the Max-Cut Problem with QAOA\n", "\n", "**Download this notebook - {nb-download}`qaoa_maxcut_example.ipynb`**\n", "\n", "\n", "In this notebook tutorial we will be demonstrating how to solve the max-cut problem using the quantum approximate optimization algorithm (QAOA). This is a variational algorithm where we run a parameterised circuit to compute an expectation value. We will then try and maximize this expectation value by classically optimizing the circuit parameters.\n" ] }, { "cell_type": "markdown", "id": "914fafd4", "metadata": {}, "source": [ "## The Max-Cut problem\n", "\n", "The max-cut problem is a classic problem from graph theory. The problem consists of partitioning the nodes in a graph into two sets $R$ and $B$ such that the number of edges between $R$ and $B$ is maximized. In our statement of the problem, we will color the nodes red and blue. The objective for max-cut is then to color the nodes of the graph such that the number of edges connecting red nodes to blue nodes is maximized.\n", "\n", "\n", "Now consider the graph below with three nodes.\n" ] }, { "cell_type": "code", "execution_count": 1, "id": "529cadb6", "metadata": { "execution": { "iopub.execute_input": "2026-06-19T16:04:43.701294Z", "iopub.status.busy": "2026-06-19T16:04:43.701083Z", "iopub.status.idle": "2026-06-19T16:04:44.186491Z", "shell.execute_reply": "2026-06-19T16:04:44.186089Z" } }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAANwAAADcCAYAAAAbWs+BAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAHVFJREFUeJzt3XtwVOd5x/Hv2dXqLiFASAhZAgSShRBCV27lYmPA3CQ7idPOtLWTTurUUztJm0nTJk0vaTL1ZDp1UnviuK2nnSROJomTTipxsw02BoMDZ3UBXcCykIUshBAgdEH3y/aP0zU3Ie2Rdvfds/t8ZjSAonPOI0c/ve95z/u+R3O5XC6EEH5hU12AEKFEAieEH0nghPAjCZwQfiSBE8KPJHBC+JEETgg/ksAJ4UcSOCH8SAInhB+FqS5ACL/p7oajR6GyEnQdmpthaAjCwmDhQiguhqIi2LQJMjJ8UoImcylF0Kuqgh/+EH72MxgeNgI2Pg53/+g7HDA6avz9kUfguedg717j671EAieC17VrRmh++UsjNGNjnh9rtxuhXLECfvpTo+XzArmHE8Hpt7+FrCz49a+Nf5sJGxhhA2hshDVr4FvfMn+OSUgLJ4LPSy/Bl78MmnZvt3GmNA1KS+FXv4KIiJmfRgIngsqPfgR//ue+ObfNZtzT/eY3M76vky6lCB7vvQfPPuu7809MQEUFfPvbMz6FtHAiOAwMwMqV8PHHt+6/fMVmMx4rFBaaP9QH5Qjhf3//99Da6lnYiouN+7y6Orh5Ey5eNEYyMzM9u5amwR//8YwGUaSFE9Z34wakpBjP2Dzx+uvwe79n/Hn2rPHQ+7nnIDYW1q2D+nrPzvPb38Jjj5kqVQInrO8HP4CvftXzEcn168HpvPWQG2D5cqitNR4jPPnk9Oew2+Ghh+DwYVOlSuCE9WVmwoULs38E4HQafxYXe37MhQumpoHJPZywtqtXoanJO8/bkpON2SlmvPeeqS+XwAlrq6z0znn+6I/ggQeMwRNPORymry+BE9ZWXW3cT83Ggw8ak5tPnoQf/9jz40ZHjccDJkjghLVdvWo8F5up5GTYvx96euCJJ4yH22ZcuWLqy2U9nLC220cazYqPh4MHISHBWAN3+bLPr++7wPX1GaM+lZXGeqTOThgZgehoWLzYWO5QXAx5eV5dbySC0/DwMH19ffT29tLX1/fJx9KLF8mcmMB0pzIiwpimlZUF27bBuXMzKywy0tSXe/8nvbLS6A///OfGg0ibzXgyf/sMAIcD/uM/jL8nJxuTTZ9+2nh4KULK+Pj4HQG6O1Duj5GRkTuOi4yMJC4ujvkJCdjMdgNtNmNwZP1648H17343s+I1DZYtM3eI157DXbwIX/gCHDlifrGfO5Rf/Sr80z+Z/q0hAo/L5WJgYGDKEPX29jIwMHDHcXa7nfj4eOLi4u75uP3zDofDOOD992HDBnPFff/78Bd/AeXlxnKbu/3sZ56dJywMvvEN42fWQ7MPnMsF//mf8Jd/aXQZZ7NIz2YzHiK+9hqsXTursoTvuLt307VKE3e1PLGxsZ8EJzY29p5gxcfHExkZiaZpnhczMABxceYGO955x5glcj9mrm9yetfsAjcxYcxB+9GPZnyKe9jtxjf8i1/AZz7jvfOKaY2Pj3Pz5s0pW6SpundTtUixsbHYZjOaOJWHH4bjx32/SuBuERHQ0WEMunho5oFzuYx7r1demdHhU9I04+M3v4HHH/f++UPM7d27qVqk/v7+O46z2+33BOfuQMXGxhIeHq7oO/t///M//v/lHBYGn/scvPqqqcNmHrh/+zejH+wrmmZ8U1VVkJvru+tY3MjIyH1DdPvn7te9m6pVioqKMte9U2VszJgl0tnpvS0VPFFZaXpN3MwC9+GHsGqV58shZioszFhUqOvGyGYIcXfvpmuVhu/6/yAiImLaVikmJgb7bGdnBJqf/hSeeso/17LbjYfkv/iF6UPNB25iAjZuNELgyQBJeLgxivPkkzB3rrH+6Fvf8nxZg6bBd78L3/ymqTIDlcvlYnBw8J4A9fb23nH/dL/u3VQtUlxcnPrunSoul7HfyBtv+PZeTtOMn+MPPoDERPOHmw7c4cOwfbvnX//znxu/DX7wA6Nl/PznoaTEuNE9ccKzc8TGGjenMTGmSvU3d/duqhapr6+P8bt+IGJiYqYdCrdM906l9nbj9qO317ehm8HCUzfzgXv8cWPumSetW0kJnD4NX/sa/Ou/Gp+LiDCWtnd2GqtuPfXqq8ZzPgXu7t5N1iJN1b2bqkWKjY0Nvu6dSlVVsHmzsYW5L0L34ovwpS/N+HBzgWtvN25OPT3ke98zHmbPm2dM9XL7m7+B55+HtDRoa5v+PDabcc9YU+NxqZ5wd++ma5Vu3rx5Vzm2ae+TQrp7p1pVlTFdy1stnd1u3Eq9/DI888ysTmVuate775obBSooMHauvT1sYLR6APn5ngVuYgLOnDFmdM+Z49GlR0dHp71Pul/3zh2clJQUsrKy7glWdHS0dO8CWWGh0Yt6+mk4cGB2G8LabJCebgzKmOmR3Ye5wFVW3vnCg+mkpEw+A9v9uUWLTF2eqiomtmz5pHs31QPau7t34eHhnwRn7ty5pKen39MiSfcuiCxaBPv2wWuv4fra19A6O5mw2Tybd+n+ZRoebnQfv/1tY9K9F5gLnK6bW44QFTX5o4OhoVv/u4cmNI3jL7zA0WPH7vi8u3vnDk5iYuKkXb2IWWxPLSxK0+DJJ/ndkiV8/PLLfLq9Hdt77xk9JvdzXreJiVvdz+XLjQ1ln3rKGJH0InOB86T7d7vBwcn3YXdPTh4c9PxcdjsZ0dHE7t17R6sk3TsxFZfLhV5dTeoTTxD2mc8Ycy/PnjV6ay0tRoPgcBhD/IWFxseCBT6rx1zgzC72u3wZUlPv/bx7GU57u8ensmkaacnJpHnptUEiNFy4cIEbN27wuHuKYHS0sffkunVK6jE3m9TsqFtNjbHALy7uzs+7VwKYHXWUbqEwSdd1kpOTSUtLU10KYDZw6enmzv7rXxv95C9+8dbnwsPhT/7EWPRnpos6Pm5+kEWEtBs3btDY2EhJSUnA3HaY61KWlBj78HnatTx92ljg9/zzkJRk7B/4uc/BkiXmH2JPTHjtLZQiNDidTiIiIli1apXqUj5hLnBFRebv4556Cr7znTvnUu7da6xfMkPTjOd6QnhgbGyM6upq8vPzA2oCgrnAbdly693Hnhoehq9/3fiYKZvNCPvd94JC3EddXR2Dg4OUlJSoLuUO5u7hkpONhX7+3mVrYmJW89dE6NF1nWXLljF//nzVpdzB/Jr3Z5/1ysvFTZkzBz77Wf9eU1jWpUuXaG9vD7jWDWYSuE2bYOtW/7Zy//iPspOX8Jiu68yZM4dMT1+w6EfmA6dp8N//bf6Z3EyEhRkPKKU7KTw0MDBAXV0dxcXFvtu0aBZmVlF6urGniS/ZbMaUm5/8ZPYvaxAho7q6GoCCAB3RnvmvgD/9U/jrv/ZiKbex2YyP//1fz9+7LELexMQETqeTlStXEhOguwPMrs19/nlj51kwt3nmFFx2u9Gy7dtnbisHEfKampro7u5mzZo1qku5r9kFTtPgn//Z2L1ozpxZd/1cQE9amvESkEcfndW5ROjRdZ1FixaROtmE+QDhnbvKP/gDYxejT33K+LeZ4Lk3fY2I4PJzz/Hik0/yoUxSFiZ1dXXR1NQUkI8Cbue9YZykJHj9dWNLha98xXj3lpvDcavL6R4MccvIMHb06ugg5cUXycjKYt++ffes2BZiKrquExUVxcqVK1WXMiXvvT3nbiMjUF9vLPSrrDReVj46aiyxWbLk1vvhli694/6vu7ubl19+mdWrV7Nnzx6flCaCy+joKC+88AKFhYVsD/D7ft89vQ4PNyYbFxQYI5oeSkhIYNu2bRw8eJDc3FwWL17ssxJFcKitrWVoaIji4mLVpUwr8J4MAiUlJaSlpVFeXs7obF4pK4Key+VC13UyMzOZ6+X9R3whIAOnaRplZWX09PTw7rvvqi5HBLC2tjY6OjoCfrDELSADB5CYmMiWLVs4efIk7Sb2PhGhRdd15s6dy/Lly1WX4pGADRzAhg0bSE5Opry8/J4NW4Xo7++noaGB4uLigNlCYToBHTi73U5ZWRmdnZ2c8PTFHyJkVFVVoWlawM6bnExABw4gJSWFDRs2cOzYMa5evaq6HBEg3PMmc3NziTKxobBqAR84gC1btpCQkEB5efk9b/IUoemDDz6gt7c3oOdNTsYSgXM4HJSWltLW1oau66rLEQFA13UeeOABUtybCluEJQIHsHjxYkpKSjhy5Ajd3d2qyxEKXbt2jY8++sgyjwJuZ5nAATzyyCNERUVRUVGBr2akicCn6zrR0dHk5OSoLsU0SwUuIiKCvXv30tzczJkzZ1SXIxQYGRnhzJkzFBYWEubv3eO8wFKBA8jMzCQvL4833njjnjeTiuB39uxZRkZGLDFvcjKWCxzAo48+it1u58CBA6pLEX7knjeZlZXFHA/fhBtoLBm46Ohodu3axblz52hoaFBdjvCT1tZWOjs7LTlY4mbJwAHk5OSQnZ3NgQMHGDTzYkdhWbquM3/+fDIyMlSXMmOWDZymaezevZuxsTHefPNN1eUIH+vr6+PcuXOWmjc5GcsGDiAuLo4dO3ZQU1PDhQsXVJcjfKiyshK73U5+fr7qUmbF0oEDY8PPpUuXUlFRwcjIiOpyhA+Mj49TWVnJqlWriLT4lveWD5ymaZSWljIwMMCRI0dUlyN84Pz589y8edNy8yYnY/nAAcydO5etW7dy+vRpWltbVZcjvEzXddLT00lOTlZdyqwFReAA1qxZQ2pqKhUVFYz5+3Vawmc6Ozu5ePGipR8F3C5oAmez2SgrK6Orq4tjx46pLkd4ia7rxMTEsGLFCtWleEXQBA4gKSmJzZs3c+LECTo6OlSXI2ZpeHiYs2fPUlRUhD1I3qAUVIED2LhxI4mJibJYNQicOXOG0dFRioqKVJfiNUEXOPc+KB0dHZw8eVJ1OWKG3PMms7Ozib9923yLC7rAAaSmprJu3TqOHj3K9evXVZcjZqClpYVr164FzWCJW1AGDuDhhx8mPj6e8vJyWaxqQbqus2DBApYsWaK6FK8K2sC590FpbW3F6XSqLkeY0Nvby/nz5ykpKbH0vMnJBG3gAJYuXUphYSGHDx+mp6dHdTnCQ06nE4fDQV5enupSvC6oAwewfft2IiIi2Ldvn3QtLWB8fJyqqipWr15NRBC+mDPoAxcZGcmePXtoamqitrZWdTliGg0NDfT39wfdYIlb0AcO4MEHHyQ3N5dDhw7R39+vuhwxBV3XWbJkCQsWLFBdik+EROAAdu7cCcDBgwcVVyLup6Ojg48//jhoWzcIocDFxMSwa9cu6uvrOX/+vOpyxCR0XScuLo7s7GzVpfhMyAQOIDc3l8zMTA4cOMDQ0JDqcsRthoaGqK2tpaioCJsteH8sg/c7m4SmaezZs4fh4WHZByXA1NTUMD4+HlTzJicTUoEDmDNnDtu3b6e6uprm5mbV5QhuzZvMyckhNjZWdTk+FXKBAygqKmLx4sXs27dP9kEJABcuXKCrqyuoB0vcQjJw7n1Q+vr6eOedd1SXE/J0XSc5OZm0tDTVpfhcSAYOYP78+Tz00EOcOnWKtrY21eWErO7ubhobG4Ny3uRkQjZwAOvXr2fhwoWUl5czPj6uupyQ5HQ6iYiIYNWqVapL8YuQDpzNZuOxxx7j+vXrHD9+XHU5IWdsbIyqqiry8/MJDw9XXY5fhHTgAJKTk9m4cSPHjx/nypUrqssJKfX19QwODobEYIlbyAcOYNOmTcybN0/2QfEzXdfJyMhg/vz5qkvxGwkcEBYWRllZGe3t7Zw6dUp1OSGhvb2dS5cuhVTrBhK4T6SlpbF27Vrefvtturq6VJcT9HRdZ86cOWRlZakuxa8kcLfZunUrsbGxVFRUyGJVHxoYGKCuri7o501OJrS+22mEh4dTWlpKS0sLVVVVqssJWtXV1bhcLgoLC1WX4ncSuLtkZGSQn5/PW2+9RW9vr+pygs7ExAROp5OVK1cSExOjuhy/k8BNYseOHTgcDvbv3y9dSy9ramqiu7s75AZL3CRwk4iKimL37t00NjZSX1+vupygous6KSkppKamqi5FCQncfaxYsYKcnBwOHjzIwMCA6nKCQldXF01NTSEzb3IyErgp7Nq1i4mJCQ4dOqS6lKDgdDqJjIwkNzdXdSnKSOCmEBsby86dO6mtraWxsVF1OZY2OjpKdXU1BQUFOBwO1eUoI4GbRl5eHsuWLWP//v0MDw+rLsey6urqGBoaori4WHUpSkngpqFpGnv37mVwcJDDhw+rLseS3FsoLF++nHnz5qkuRykJnAcSEhLYtm0bTqeTixcvqi7Hci5dusTly5dD9lHA7SRwHiopKSEtLY3y8nJGR0dVl2Mpuq6TkJDA8uXLVZeinATOQ5qmUVZWRk9PD0ePHlVdjmX09/dTX19PcXFxyM2bnIz8FzAhMTGRLVu28P7779Pe3q66HEuoqqpC0zQKCgpUlxIQJHAmbdiwgeTkZNkHxQMTExNUVlaSm5tLdHS06nICggTOJLvdTllZGZ2dnZw4cUJ1OQGtsbGRnp4eGSy5jQRuBlJSUtiwYQPHjh3j6tWrqssJWLquk5qayqJFi1SXEjAkcDO0ZcsWEhISZB+U+7h+/TrNzc3Sut1FAjdDDoeDsrIy2tra0HVddTkBR9d1oqOjWblypepSAooEbhbS09MpKSnhyJEjdHd3qy4nYIyMjFBTU0NBQQFhYWGqywkoErhZeuSRR4iKipJ9UG5TW1vLyMhIyM+bnIwEbpYiIiLYu3cvzc3NnDlzRnU5yrnnTWZlZZGQkKC6nIAjgfOCzMxM8vLyeOONN7h586bqcpT6+OOPuXLligyW3IcEzkseffRR7HY7Bw4cUF2KUrquM2/ePDIyMlSXEpAkcF4SHR3Nrl27OHfuHA0NDarLUaKvr4+GhoaQ3kJhOhI4L8rJySE7O5sDBw4wODiouhy/q6qqwm63k5+fr7qUgCWB8yJN09i9ezdjY2O8+eabqsvxq/HxcSorK1m1ahWRkZGqywlYEjgvi4uLY8eOHdTU1HDhwgXV5fjNBx98QF9fnwyWTEMC5wMFBQUsXbqUiooKRkZGVJfjF7quk5aWxsKFC1WXEtAkcD6gaRqlpaUMDAxw5MgR1eX4XGdnJy0tLdK6eUAC5yNz585l69atnD59mtbWVtXl+JSu68TExJCTk6O6lIAngfOhNWvWkJqaSkVFBWNjY6rL8Ynh4WHOnj1LYWEhdrtddTkBTwLnQzabjbKyMrq6ujh27JjqcnzizJkzjI6OyrxJD0ngfCwpKYnNmzdz4sQJOjo6VJfjVe55k9nZ2cTHx6suxxIkcH6wceNGEhMTg26xaktLC9euXZPBEhMkcH7g3gelo6ODkydPqi7Ha3RdJzExkSVLlqguxTIkcH6SmprKunXrOHr0KNevX1ddzqz19vZy/vx5mTdpkgTOjx5++GHi4+MpLy+3/GLVyspKHA4Hq1evVl2KpUjg/MjhcFBaWkpraytOp1N1OTPmnjeZl5dHRESE6nIsRQLnZ0uXLqWwsJDDhw/T09OjupwZOXfuHP39/TJYMgMSOAW2b99OREQE+/bts2TXUtd1Fi9eTFJSkupSLEcCp0BkZCR79uyhqamJ2tpa1eWYcuXKFVpbW6V1myEJnCIPPvggubm5HDp0iP7+ftXleOz06dPExcWRnZ2tuhRLksAptHPnTgAOHjyouBLPDA0NUVtbK/MmZ0ECp1BMTAy7du2ivr6e8+fPqy5nWjU1NYyPj1NUVKS6FMuSwCmWm5tLZmYm+/fvZ2hoSHU59+VyuXA6naxYsYK4uDjV5ViWBE4xTdPYu3cvIyMjAb0PSnNzM9evX5fBklmSwAWA+Ph4tm/fTnV1Nc3NzarLmZSu6yQlJZGenq66FEuTwAWIoqIiFi9ezL59+wJuH5Senh4aGxtl3qQXSOAChHsflL6+Pt555x3V5dzB6XQSHh5OXl6e6lIsTwIXQObPn89DDz3EqVOnaGtrU10OAGNjY1RVVbF69WrCw8NVl2N5ErgAs379elJSUigvLw+IfVAaGhoYGBiQwRIvkcAFGPc+KNevX+e9995TXQ66rpORkUFiYqLqUoKCBC4AJScns3HjRo4fP86VK1eU1XH58mXa2tqkdfMiCVyA2rRpE/PmzVO6D8rp06eJj48nKytLyfWDkQQuQIWFhVFWVkZ7ezunTp3y+/UHBwepq6ujuLgYm01+TLxF/ksGsLS0NNauXcvbb79NV1eXX69dXV2Ny+WisLDQr9cNdhK4ALd161ZiY2OpqKjw22JV97zJnJwcYmJi/HLNUCGBC3Dh4eGUlpbS0tJCVVWVX67Z1NTEjRs3ZLDEByRwFpCRkUF+fj5vvfUWvb29Pr+erussXLiQBx54wOfXCjUSOIvYsWMHDoeD/fv3+7RreePGDT788EOZN+kjEjiLiIqKYvfu3TQ2NlJfX++z6+i6TmRkJKtWrfLZNUKZBM5CVqxYQU5ODgcPHmRgYMDr5x8dHaWmpob8/HwcDofXzy8kcJaza9cuJiYmOHTokNfPXVdXx+DgoAyW+JAEzmJiY2PZuXMntbW1NDY2eu287ldPLV++nHnz5nntvOJOEjgLysvLY9myZezfv5/h4WGvnPPSpUtcvnxZWjcfk8BZkHsflMHBQQ4fPuyVc+q6TkJCAsuXL/fK+cTkJHAWlZCQwLZt23A6nbS0tMzqXP39/dTX18u8ST8IU12AmLmSkhLq6uqoqKjgmWeeuWdksbcXqquhqgouXYLhYQgPh5QUKCyEggKYO9eYNwlQUFCg4tsIKRI4C9M0jbKyMl555RWOHj3K9u3bGRqC11+Hl14CpxNcLrDZ4PaNksfHwb3iJy/PRXb2EJ/61Gqio6PVfCMhRHNZ8fUt4g7Hjx/nyJF3sNm+wve/P4fubiNkniyj0zQXLhdER7v45jdtfP3rII/gfEcCFwTOnx9nz56rNDcvnNV5NA1WrYLXXjP+FN4ngbO4w4ehrAxGRlyMj89+7qPdbgTvl7+ET3/aCwWKO0jgLOytt2D3bqPr6M1dGNxzln/1K3jiCe+dV0jgLKu+HoqLYWTEu2Fz0zSjtTt2DNav9/75Q5UEzoLGxmDNGqitNf7uK3Y7LF4MdXUQFeW764QSecppQf/yL1BT49uwgfH4oKUF/u7vfHudUCItnMX09MDCheDpq+RiYuCv/grWrjVaxXnz4POfhx//2PNr2mzQ2gqpqTMqWdxGWjiL+clPjBkjnkpMhH/4B1ixAs6cmfl1X3115seKWyRwFuJyGTNIzLh82WgRlywxWrqZmJiAl1+G0dGZHS9ukcBZSEsLfPihETxPjYyAN3ZL7+ycXQspDBI4C3E61V1b06CyUt31g4UEzkIqK9XNc7TbJXDeIIGzkNZW3zzk9sTYGATo68ctRQJnIUND6gLnvr6YHQmchTgct+Y5qiBvHJ49CZyFJCbeuZDUn+x2SEpSc+1gIoGzkMJCtc/C5M1VsydbLFhIUdHMjnv2WUhIgEWLjH+XloL7PR0vvWTsfTKd8fGZX1/cInMpLWR0FBYsMOZTmvHRR8ZMk8ksWQIXL05/jvBwuHoV4uPNXVvcSbqUFuJwwNNPm7+PW7rUGGyZ7MOTsIWFwR/+oYTNG6SFs5gLF0DFXq26bix4FbMjLZzFLFsGv//7/hutDAuDrVslbN4iLZwFdXZCdjZ0d5ubyDwTUVHQ0HD/e0BhjrRwFpSUBP/+774PG8ALL0jYvEkCZ1Gf/Sz87d/67vyaBs88A3/2Z767RiiSwFnYd74D3/iGb879xS/CD3+odipZMJJ7uCDwX/8FX/qSsdh0NhsLhYUZgzHf+x58+csSNl+QwAWJ1lb4wheMnZjDwswFz/3169YZe6ZkZvquzlAnXcogkZ4Ob74Jx48buyWH/f+kvfutMHAvZNU02LPH2MX5xAkJm69JCxekOjvh3XeNVdq6brSA7vfDpaZCSYkxN3LzZtn+zp8kcEL4kXQphfAjCZwQfiSBE8KPJHBC+JEETgg/ksAJ4UcSOCH8SAInhB9J4ITwIwmcEH70fzSf0FZpPFyjAAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import networkx as nx\n", "import matplotlib.pyplot as plt\n", "\n", "G = nx.Graph()\n", "G.add_edges_from([(0, 1), (1, 2), (2, 0)])\n", "plt.figure(figsize=(2, 2))\n", "nx.draw(\n", " G,\n", " node_color=[\"red\", \"blue\", \"red\"],\n", " font_size=12,\n", " font_color=\"white\",\n", " node_size=500,\n", " edge_color=\"gray\",\n", " with_labels=True,\n", ")\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "dd4cae83", "metadata": {}, "source": [ "There are $2^3$ colorings of the graph. In general there are $2^n$ for an $n$ node graph. The Max-cut problem can then be stated as that of finding the color assignment which maximizes the number of edges between nodes of a different color." ] }, { "cell_type": "markdown", "id": "ec6c7c2f", "metadata": {}, "source": [ "\n", "\n", "We can define the following cost function for solving the max-cut problem for a graph $G$\n", "\n", "$$\n", "\\begin{equation*}\n", "C(G)= \\frac{1}{2}\\sum_{(i,j) \\in E(G)} (1-z_i\\,z_j)\\,, \\quad z_i,z_j \\in \\{-1,1\\}\n", "\\end{equation*}\n", "$$\n", "\n", "Here $z_i$ and $z_j$ are variables representing the \"colors\" of each node and $E(G)$ is the edge set of the graph. We can solve max-cut by finding a coloring of the graph that maximizes $C(G)$\n", "\n" ] }, { "cell_type": "markdown", "id": "4ceb9ac7", "metadata": {}, "source": [ "\n", "## Quantum Approximate Optimization Algorithm (QAOA)\n", "\n", "### General theory\n", "\n", "Introduced in \"A Quantum Approximate Optimization Algorithm\" (found at https://arxiv.org/abs/1411.4028). The idea is to prepare a quantum state which encodes a solution to the max-cut problem. Measuring such a state will give us computational basis states (or bitstrings) which correspond to colorings of the graph. \n", "\n", "\n", "QAOA is a variational algorithm, which is to say that a parameterized state is prepared, with the parameters varied to improve the solution. We will have $2p$ parameters where $p$ is our number of layers. In particular, the state prepared has the form \n", "\n", "\n", "$$\n", "| \\psi ( \\beta, \\gamma ) \\rangle = U_B ( \\beta_{p-1} ) U_P ( \\gamma_{p-1} ) ... U_B (\\beta_0) U_P ( \\gamma_0 ) | +\\rangle ^{\\otimes n}\n", "$$\n", "\n", "where\n", "\n", "$$\n", "U_P ( \\gamma_i) = e^{i \\gamma_i H_P} \\quad \\& \\quad U_B( \\beta_i ) = e^{i \\beta_i H_B}\n", "$$" ] }, { "cell_type": "markdown", "id": "4828b45f", "metadata": {}, "source": [ "We refer to $H_{P} \\equiv H_{P(G)}$ as the *problem Hamiltonian*. This Hamiltonian essentially encodes the connectivity of the graph in the max-cut problem." ] }, { "cell_type": "markdown", "id": "6c36ccb1", "metadata": {}, "source": [ "$$\n", "\\begin{equation*}\n", "H_{P(G)} = \\frac{1}{2}\\sum_{(i, \\,j) \\in E(G)} (I-Z_i \\,Z_j)\n", "\\end{equation*}\n", "$$\n", "\n", "Here there is an implicit tensor product. We use the notation $Z_i \\, Z_j \\equiv Z_i \\otimes Z_j$. Note also the resemblance between $H_{P(G)}$ and our classical cost function $C(G)$. \n", "\n", "The rule for constructing this problem Hamiltonian is that we include a $Z_i\\, Z_j$ term for every edge $(i, j)$ in the graph. The section below shows how this Hamiltonian looks for a specific graph.\n", "\n", "\n", "The $H_B$ operator is called the *mixer Hamiltonian*. This operator is just a sum of Pauli $X$ operators with one non-identity term on each qubit.\n", "\n", "$$\n", "\\begin{equation*}\n", "H_B = \\sum_i X_i\n", "\\end{equation*}\n", "$$\n", "\n", "Here we use the the convention that $X_i$ means a Pauli $X$ operator will be applied to the \"ith\" qubit and the identity operator will be applied to all other qubits in the circuit. Importantly, this mixer Hamiltonian does not commute with $H_P$. This fact turns out to be important as it will allow us properly explore our solution space." ] }, { "cell_type": "markdown", "id": "1da0a126", "metadata": {}, "source": [ "### Example: cost and mixer Hamiltonian for a three node graph\n", "\n", "Let us look again the three node graph we used in introducing the max-cut problem\n" ] }, { "cell_type": "code", "execution_count": 2, "id": "d3ac9b6c", "metadata": { "execution": { "iopub.execute_input": "2026-06-19T16:04:44.187828Z", "iopub.status.busy": "2026-06-19T16:04:44.187718Z", "iopub.status.idle": "2026-06-19T16:04:44.198114Z", "shell.execute_reply": "2026-06-19T16:04:44.197653Z" } }, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.figure(figsize=(2, 2))\n", "nx.draw(\n", " G,\n", " node_color=[\"red\", \"blue\", \"red\"],\n", " font_size=12,\n", " font_color=\"white\",\n", " node_size=500,\n", " edge_color=\"gray\",\n", " with_labels=True,\n", ")\n", "plt.show()\n" ] }, { "cell_type": "markdown", "id": "6716b311", "metadata": {}, "source": [ "\n", "\n", "For the simple three node graph above the *problem Hamiltonian* is\n", "\n", "$$\n", "H_{P(G)} = \\frac{3}{2} I - \\frac{1}{2} \\Big[ ( Z \\otimes Z \\otimes I ) + ( Z \\otimes I \\otimes Z ) + ( I \\otimes Z \\otimes Z ) \\Big]\n", "$$\n", "\n", "where you will notice that there is a $ Z \\otimes Z$ acting between each node which is connected by an edge.\n", "The mixer Hamiltonian has the form \n", "\n", "$$\n", "H_B = ( X \\otimes I \\otimes I ) + ( I \\otimes X \\otimes I ) + ( I \\otimes I \\otimes X )\n", "$$\n", "\n", "Here there is an $X$ operator acting on each node. The form of this operator is independent of the graph connectivity.\n" ] }, { "cell_type": "markdown", "id": "e1d368bb", "metadata": {}, "source": [ "\n", "\n", "## Building the program\n", "\n", "To start off with, we will need to construct a QAOA circuit for a particular graph and number of layers ($p$). Our circuit for QAOA is constructed by alternating the cost layer ($U_P$) and mixer layer ($U_B$) $p$ times for different parameters. The cost layer is defined by evolving the commuting Hamiltonian $H_{P(G)}$. We can realize this with a layer of ZZPhase gates. For the mixer layer we are evolving the $X$-type Hamiltonian $H_B$. We can realize the evolution with a layer of Rx gates.\n", "\n", "\n", "$$\n", "\\mathrm{Rx}(\\beta)=\n", " \\begin{pmatrix}\n", " \\cos(\\frac{ \\beta}{2}) & -i\\sin(\\frac{ \\beta}{2}) \\\\\n", " -i\\sin(\\frac{ \\beta}{2}) & \\cos(\\frac{ \\beta}{2})\n", " \\end{pmatrix}\\,, \\qquad\n", "\\mathrm{ZZPhase}(\\gamma)=\n", " \\exp(\\frac{- i \\gamma}{2}\\big(Z \\otimes Z \\big))=\n", " \\begin{pmatrix}\n", " e^{\\frac{-i \\gamma}{2}} & 0 & 0 & 0 \\\\\n", " 0 & e^{\\frac{i \\gamma}{2}} & 0 & 0 \\\\\n", " 0 & 0 & e^{\\frac{i \\gamma}{2}} & 0 \\\\\n", " 0 & 0 & 0 & e^{\\frac{-i \\gamma}{2}}\n", " \\end{pmatrix}\n", "\n", "$$\n" ] }, { "cell_type": "markdown", "id": "be5b779b", "metadata": {}, "source": [ "We will define a Python function which will construct a Guppy program implementing QAOA for an $n$ node graph. First we create the uniform superposition state $|+\\rangle^{\\otimes n}$ and then alternate cost and mixer layers as described above.\n", "\n", "The graph topology and the number of layers $p$ are fixed at compile time (loaded with [comptime](https://docs.quantinuum.com/guppy/language_guide/comptime.html) expressions), but the cost and mixer angles are passed as **runtime arguments**: `qaoa_instance` takes two [array](https://docs.quantinuum.com/guppy/api/generated/guppylang.std.builtins.array.html)`[float, p]` arguments. Because the angles are runtime arguments, the program can be compiled once and then re-run with different angle values — exactly what the variational optimization loop below needs." ] }, { "cell_type": "code", "execution_count": 3, "id": "e774a69f", "metadata": { "execution": { "iopub.execute_input": "2026-06-19T16:04:44.199391Z", "iopub.status.busy": "2026-06-19T16:04:44.199317Z", "iopub.status.idle": "2026-06-19T16:04:45.022816Z", "shell.execute_reply": "2026-06-19T16:04:45.022436Z" } }, "outputs": [], "source": [ "from guppylang import guppy\n", "from guppylang.std.quantum import qubit, h, rx\n", "from guppylang.std.qsystem.helios import zz_phase\n", "from guppylang.std.builtins import array\n", "from guppylang.std.angles import pi\n", "from guppylang.defs import GuppyFunctionDefinition\n", "\n", "\n", "def build_qaoa_instance(graph: nx.Graph, n_layers: int) -> GuppyFunctionDefinition:\n", " edges = list(graph.edges)\n", " n_qubits = graph.number_of_nodes()\n", "\n", " @guppy\n", " def qaoa_instance(\n", " cost_angles: array[float, n_layers],\n", " mixer_angles: array[float, n_layers],\n", " ) -> array[qubit, n_qubits]:\n", " qs = array(qubit() for _ in range(n_qubits))\n", " n = len(qs)\n", "\n", " for i in range(n):\n", " h(qs[i])\n", "\n", " for layer in range(n_layers):\n", " # Add cost layer\n", " for i, j in edges:\n", " zz_phase(qs[i], qs[j], -cost_angles[layer] * pi / 2)\n", "\n", " # Add mixer layer\n", " for i in range(n):\n", " rx(qs[i], mixer_angles[layer] * pi)\n", "\n", " return qs\n", "\n", " return qaoa_instance" ] }, { "cell_type": "markdown", "id": "e799bbc7", "metadata": {}, "source": [ "## Calculating expectation values" ] }, { "cell_type": "markdown", "id": "289b4739", "metadata": {}, "source": [ "\n", "We also need to extract our energy expectation values from a `QsysResult` object after our circuit is processed by the Selene simulator. We do this with the `energy_from_result` function below. Note that the fact that the max-cut problem Hamiltonian $H_P$ contains only commuting terms means that we do not need to calculate our energy expectation using multiple measurement circuits.\n" ] }, { "cell_type": "code", "execution_count": 4, "id": "4683c89c", "metadata": { "execution": { "iopub.execute_input": "2026-06-19T16:04:45.024253Z", "iopub.status.busy": "2026-06-19T16:04:45.024180Z", "iopub.status.idle": "2026-06-19T16:04:45.026254Z", "shell.execute_reply": "2026-06-19T16:04:45.025896Z" } }, "outputs": [], "source": [ "from hugr.qsystem.result import QsysResult\n", "\n", "\n", "def energy_from_result(graph: nx.Graph, result: QsysResult, n_shots: int) -> float:\n", " energy = 0.0\n", " dist = result.register_counts()[\"c\"]\n", " for i, j in graph.edges:\n", " for meas, count in dist.items():\n", " prob = count / n_shots\n", " energy += (int(meas[i]) ^ int(meas[j])) * prob\n", "\n", " return energy" ] }, { "cell_type": "markdown", "id": "852d6d0e", "metadata": {}, "source": [ "Now let's define helpers for executing and scoring QAOA parameter values.\n", "\n", "Because the cost and mixer angles are runtime arguments, we compile the program **once** and re-run it for every parameter set. `build_qaoa_program` defines a `main` entrypoint that takes the angles as arguments and returns a built `EmulatorInstance`. `run_qaoa_circuit` executes that instance for specific angle values by passing them to `.run(...)`, and `eval_qaoa_energy` turns the result into the scalar energy needed by the classical optimizer.\n", "\n", "The `p_value` argument defines the number of cost/mixer layers in the QAOA program." ] }, { "cell_type": "code", "execution_count": 5, "id": "f2eb559e", "metadata": { "execution": { "iopub.execute_input": "2026-06-19T16:04:45.027252Z", "iopub.status.busy": "2026-06-19T16:04:45.027182Z", "iopub.status.idle": "2026-06-19T16:04:45.030709Z", "shell.execute_reply": "2026-06-19T16:04:45.030107Z" } }, "outputs": [], "source": [ "import numpy as np\n", "from guppylang.std.quantum import measure_array, collect_measurements\n", "from guppylang.std.builtins import output\n", "from guppylang.emulator import EmulatorInstance\n", "from numpy.typing import NDArray\n", "\n", "\n", "def build_qaoa_program(\n", " graph: nx.Graph,\n", " p_value: int,\n", " seed: int,\n", " shots: int,\n", ") -> EmulatorInstance:\n", " qaoa_instance: GuppyFunctionDefinition = build_qaoa_instance(\n", " graph=graph,\n", " n_layers=p_value,\n", " )\n", "\n", " @guppy\n", " def main(\n", " cost_angles: array[float, p_value],\n", " mixer_angles: array[float, p_value],\n", " ) -> None:\n", " qaoa_qubits = qaoa_instance(cost_angles, mixer_angles)\n", " output(\"c\", collect_measurements(measure_array(qaoa_qubits)))\n", "\n", " # Compiled and built once; reused for every parameter set via `.run(...)`.\n", " return (\n", " main.emulator(n_qubits=graph.number_of_nodes())\n", " .with_shots(shots)\n", " .with_seed(seed)\n", " )\n", "\n", "\n", "def run_qaoa_circuit(\n", " program: EmulatorInstance,\n", " cost_angles: NDArray[np.float64],\n", " mixer_angles: NDArray[np.float64],\n", ") -> QsysResult:\n", " return program.run(\n", " cost_angles=[float(x) for x in cost_angles],\n", " mixer_angles=[float(x) for x in mixer_angles],\n", " )\n", "\n", "\n", "def eval_qaoa_energy(\n", " program: EmulatorInstance,\n", " cost_angles: NDArray[np.float64],\n", " mixer_angles: NDArray[np.float64],\n", " graph: nx.Graph,\n", " shots: int,\n", ") -> float:\n", " qaoa_result = run_qaoa_circuit(program, cost_angles, mixer_angles)\n", " return energy_from_result(graph, qaoa_result, shots)" ] }, { "cell_type": "markdown", "id": "8abc6d45", "metadata": {}, "source": [ "## Setting up the variational loop" ] }, { "cell_type": "markdown", "id": "3a06056b", "metadata": {}, "source": [ "Now that we have the `eval_qaoa_energy` function which does a single \"forward pass\" of our algorithm, we can use a classical optimizer to find a set of parameters which maximizes the energy expectation value.\n", "\n", "To accomplish this, we define a SciPy objective function that accepts a single parameter vector, splits it into QAOA cost and mixer coefficients, evaluates the Guppy program for those coefficients, and returns the negative energy. Minimizing the negative energy is equivalent to maximizing the max-cut energy.\n", "\n", "Now we can put all of this machinery together in a `solve_max_cut_instance` function which, given a graph, attempts to solve the max-cut problem using this variational method. After the optimizer finishes, we run one final QAOA forward pass with the best parameters and use that `QsysResult` for validation and plotting.\n", "\n", "Our function takes the following arguments:\n", "\n", "* `graph`: A networkx graph for which we want to solve the max-cut problem.\n", "* `max_optimizer_iterations`: The maximum number of objective evaluations in the SciPy optimizer.\n", "* `p_value`: The number of alternating cost/mixer layers in our QAOA program.\n", "* `n_shots`: The number of Guppy program executions for each expectation value calculation.\n", "* `seed`: A seed for the random number generator so the initial parameters and emulator executions are reproducible.\n", "\n", "The optimized values below are dimensionless coefficients of Guppy angle constants: the cost layer applies `-cost_angle * pi / 2`, and the mixer layer applies `mixer_angle * pi`. The optimizer works directly with these real-valued coefficients.\n" ] }, { "cell_type": "code", "execution_count": 6, "id": "def010e3", "metadata": { "execution": { "iopub.execute_input": "2026-06-19T16:04:45.031897Z", "iopub.status.busy": "2026-06-19T16:04:45.031822Z", "iopub.status.idle": "2026-06-19T16:04:45.435051Z", "shell.execute_reply": "2026-06-19T16:04:45.434637Z" } }, "outputs": [], "source": [ "from scipy.optimize import OptimizeResult, minimize\n", "\n", "\n", "def pack_qaoa_params(\n", " cost_angles: NDArray[np.float64], mixer_angles: NDArray[np.float64]\n", ") -> NDArray[np.float64]:\n", " return np.concatenate((cost_angles, mixer_angles))\n", "\n", "\n", "def split_qaoa_params(\n", " params: NDArray[np.float64], p_value: int\n", ") -> tuple[NDArray[np.float64], NDArray[np.float64]]:\n", " return params[:p_value], params[p_value:]\n", "\n", "\n", "def solve_max_cut_instance(\n", " graph: nx.Graph,\n", " max_optimizer_iterations: int,\n", " p_value: int,\n", " n_shots: int,\n", " seed: int,\n", ") -> tuple[QsysResult, NDArray[np.float64], NDArray[np.float64], OptimizeResult]:\n", " rng = np.random.default_rng(seed)\n", " initial_params = pack_qaoa_params(\n", " cost_angles=rng.uniform(0, 2 * np.pi, size=p_value),\n", " mixer_angles=rng.uniform(0, 2 * np.pi, size=p_value),\n", " )\n", "\n", " # Compile and build the program once, then reuse it for every objective\n", " # evaluation by supplying the angles as runtime arguments.\n", " program = build_qaoa_program(\n", " graph=graph, p_value=p_value, seed=seed, shots=n_shots\n", " )\n", "\n", " def objective(params: NDArray[np.float64]) -> float:\n", " cost_angles, mixer_angles = split_qaoa_params(params, p_value)\n", " qaoa_energy = eval_qaoa_energy(\n", " program=program,\n", " cost_angles=cost_angles,\n", " mixer_angles=mixer_angles,\n", " graph=graph,\n", " shots=n_shots,\n", " )\n", " return -qaoa_energy\n", "\n", " optimizer_result = minimize(\n", " objective,\n", " initial_params,\n", " method=\"COBYLA\",\n", " options={\"maxiter\": max_optimizer_iterations, \"rhobeg\": 0.5},\n", " )\n", "\n", " best_cost_angles, best_mixer_angles = split_qaoa_params(\n", " optimizer_result.x, p_value\n", " )\n", " best_result = run_qaoa_circuit(program, best_cost_angles, best_mixer_angles)\n", "\n", " return best_result, best_cost_angles, best_mixer_angles, optimizer_result" ] }, { "cell_type": "markdown", "id": "c6b297e8", "metadata": {}, "source": [ "## Solving max-cut for a graph with seven nodes\n", "\n", "Now that we have all of the pieces ready, let's test our QAOA implementation for a very simple graph. \n", "\n", "We will graph where the correct answer for max-cut is very easy to verify manually." ] }, { "cell_type": "code", "execution_count": 7, "id": "90bf1a83", "metadata": { "execution": { "iopub.execute_input": "2026-06-19T16:04:45.436396Z", "iopub.status.busy": "2026-06-19T16:04:45.436270Z", "iopub.status.idle": "2026-06-19T16:04:45.458562Z", "shell.execute_reply": "2026-06-19T16:04:45.458120Z" } }, "outputs": [ { "data": { "image/png": "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+MXhcOijjz7SuXPn9NBDD+mxxx5jywMAhJGID5T7L9Tq5yUnVNcS3AbO4c7r9er27du9WvPcunVL0p2G4EOHDu0VHqOtITiCx+v16tChQ9q9e7dGjhyplStXatCgQUaXBQDwQUQHyt8euqxfbu7/I+ZeWpGn57sdMRdu2tvbex1DWFNTo46ODklSXFycMjMzu5arMzMzlZqaKpstumZnYYxLly7pgw8+kNVq1erVq5WdnW10SQCA7xGxgbLzvOJgCYdQ2b0hePePezUE777XMSEhgVlHGKqxsVElJSW6du2alixZohkzZvDfJACEsIgMlPsv1Or5t8qDPs7bP8oPmeXvuxuC19TUqKampqsheEJCQq/lahqCI5S53W5t375dn332maZOnarly5czSw4AISriAmVju1OP/8O+gPdMfp/OPZW7f/bogD6o43a7VVdX12vWsampSZJksVh6NQNPT09nLxrC1smTJ7V582YNHTpURUVFGjJkiNElAQDuEnGB8j9tPKniY1eCGiY7mU1S0Ywc/fqZKUG5fveG4N2PIby7IXj3ADl06FCejkXEuXHjhoqLi9XS0qKnn35a48aNM7okAEA3ERUor9S3quC1vfLlB5o9aoh+t27OPb/39D8f1PErt30a02SSDrwwP6A+lXc3BO98YKalpUXSnYbgd886ZmRk0BAcUaW9vV0fffSRzp8/r0ceeUTz5s3jjycACBFWowvoTxvKK2UySf5E5LcOXtKJqw09vna5rsXn95u/HfeFxd/fjNnr9aqpqalXa56bN292NQRPSUlRRkaGZsyYQUNwoJvY2FitWbNGf/jDH7R3715VVVVp5cqVnO8OACEgYmYonW6PZryyq+sEnO/TOUP5N+8e09ZT1QGNnRRn09H1C3oc09jR0XHPYwjvbgjevTVPWlqa7HZ7QLUA0eDrr7/Wxo0bZbPZtHr1amVlZRldEgBEtYiZoTxX3eRzmLzboBiL2l0eufu48bKhzalthys02HW7KzjeqyH4fffd1zXrmJSUxKwj0Ef33Xef1q1bp5KSEr311ltaunSppk2bxu8UABgkYmYo3yuv1H/+sMLn13fOUDY7XEqwW+Vye/TZ5Xq9uvWsKqoavv8CPXg11/qNHkhs6bXPMS0tjVYnQJC4XC5t375dR48e1QMPPKBly5bx+wYABoiYGcpTVQ2ymk1y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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "max_cut_graph_edges = [(0, 1), (1, 2), (1, 3), (3, 4), (4, 5), (4, 6)]\n", "n_nodes = 7\n", "\n", "max_cut_graph = nx.Graph()\n", "max_cut_graph.add_edges_from(max_cut_graph_edges)\n", "pos = nx.kamada_kawai_layout(max_cut_graph)\n", "nx.draw(\n", " max_cut_graph,\n", " pos=pos,\n", " labels={node: node for node in max_cut_graph.nodes()},\n", " font_size=12,\n", " font_color=\"white\",\n", " node_size=500,\n", " edge_color=\"gray\",\n", ")" ] }, { "cell_type": "markdown", "id": "51064e84", "metadata": {}, "source": [ "The solution for this graph is a simple alternating coloring which we can represent with the following pair of bitstrings. See the two graphs drawn at the end of this notebook. The bitstrings are the binary complement of one another.\n", "\n", "We have chosen a sparse graph where it is easy to check the mx-cut solution by inspection. For this configuration, the solution is that nodes 1 and 4 are a different color to nodes 0, 2, 3, 5 and 6." ] }, { "cell_type": "markdown", "id": "0482b9ac", "metadata": {}, "source": [ "We can represent a coloring with a binary string where the \"ith\" entry in the string represents the color of node i. Therefore the expected solutions can be represented by the following two strings." ] }, { "cell_type": "code", "execution_count": 8, "id": "ff3572ee", "metadata": { "execution": { "iopub.execute_input": "2026-06-19T16:04:45.459713Z", "iopub.status.busy": "2026-06-19T16:04:45.459640Z", "iopub.status.idle": "2026-06-19T16:04:45.461500Z", "shell.execute_reply": "2026-06-19T16:04:45.461064Z" } }, "outputs": [], "source": [ "expected_result_strings = [\"0100100\", \"1011011\"]" ] }, { "cell_type": "markdown", "id": "b5471c90", "metadata": {}, "source": [ "Note that there are two colourings as all that matters is that we have partitioned the node indices into the sets $S_0=\\{0, 2, 3, 5, 6\\}$ and $S_1=\\{1, 4\\}$. If we have two colors e.g. red and blue, then we have the freedom to colour the nodes in $S_0$ blue and $S_1$ red or vice-versa." ] }, { "cell_type": "markdown", "id": "b56fff11", "metadata": {}, "source": [ "Now we need a problem Hamiltionian which reflects the connectivity of our graph. Recall how the problem Hamiltonian is defined." ] }, { "cell_type": "markdown", "id": "ee9129b7", "metadata": {}, "source": [ "$$\n", "\\begin{equation*}\n", "H_{P(G)} = \\frac{1}{2}\\sum_{(i, \\,j) \\in E(G)} (I-Z_i \\,Z_j)\n", "\\end{equation*}\n", "$$\n" ] }, { "cell_type": "markdown", "id": "ca84035b", "metadata": {}, "source": [ "Four our seven vertex graph, the problem Hamiltonian is the following " ] }, { "cell_type": "markdown", "id": "e9f721df", "metadata": {}, "source": [ "\n", "$$\n", "\\begin{equation*}\n", "H_{P(G)} = 3 I_{(n=7)} -\\frac{1}{2} \\big[ Z_0 Z_1 + Z_1 Z_2 +Z_1 Z_3 +Z_3 Z_4 +Z_4 Z_5 +Z_4 Z_6 \\big]\\, .\n", "\\end{equation*}\n", "$$" ] }, { "cell_type": "markdown", "id": "03474bb7", "metadata": {}, "source": [ "The form of the mixer Hamiltonian $H_B$ depends only on the number of nodes in our graph. The evolution operator $U_B$ can be implemented with a layer of `Rx` gates. See the `build_qaoa_instance` function." ] }, { "cell_type": "code", "execution_count": 9, "id": "9b4dac68", "metadata": { "execution": { "iopub.execute_input": "2026-06-19T16:04:45.462987Z", "iopub.status.busy": "2026-06-19T16:04:45.462907Z", "iopub.status.idle": "2026-06-19T16:05:00.919687Z", "shell.execute_reply": "2026-06-19T16:05:00.919146Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Optimizer status: Return from COBYLA because the trust region radius reaches its lower bound.\n", "Objective evaluations: 77\n", "Optimized energy: 5.0995\n", "Cost angles: [1.736 2.63 4.751]\n", "Mixer angles: [4.831 2.361 2.2 ]\n" ] } ], "source": [ "n_shots = 2000\n", "p_value = 3\n", "random_seed = 12345\n", "max_optimizer_iterations = 100\n", "\n", "qaoa_result, cost_angles, mixer_angles, optimizer_result = solve_max_cut_instance(\n", " n_shots=n_shots,\n", " max_optimizer_iterations=max_optimizer_iterations,\n", " graph=max_cut_graph,\n", " seed=random_seed,\n", " p_value=p_value, # Cost-mixer layers\n", ")\n", "\n", "optimized_energy = -float(optimizer_result.fun)\n", "print(f\"Optimizer status: {optimizer_result.message}\")\n", "print(f\"Objective evaluations: {optimizer_result.nfev}\")\n", "print(f\"Optimized energy: {optimized_energy:.4f}\")\n", "print(f\"Cost angles: {np.round(cost_angles, 3)}\")\n", "print(f\"Mixer angles: {np.round(mixer_angles, 3)}\")\n" ] }, { "cell_type": "markdown", "id": "7666389a", "metadata": {}, "source": [ "**Optimizer status note.** COBYLA is a derivative-free trust-region optimizer. If it reports that the trust-region radius reached its lower bound, that is a normal termination condition: the local search radius has shrunk to the configured tolerance. If it reports that the maximum number of function evaluations was exceeded, the configured `maxiter` budget was exhausted.\n", "\n", "The optimizer objective above maximizes the expected max-cut energy. This is related to, but not identical to, maximizing the probability of sampling one of the two exact optimal colorings." ] }, { "cell_type": "markdown", "id": "06837a03", "metadata": {}, "source": [ "Lets define a function that checks that the most frequent measurement outcomes correspond to the expected graph colorings." ] }, { "cell_type": "code", "execution_count": 10, "id": "b9d8299e", "metadata": { "execution": { "iopub.execute_input": "2026-06-19T16:05:00.921684Z", "iopub.status.busy": "2026-06-19T16:05:00.921577Z", "iopub.status.idle": "2026-06-19T16:05:00.924178Z", "shell.execute_reply": "2026-06-19T16:05:00.923879Z" } }, "outputs": [], "source": [ "def validate_qaoa_experiment(\n", " result: QsysResult, expected_colorings: list[str], n_shots: int\n", ") -> float:\n", " counts_dict = result.register_counts()[\"c\"]\n", " sorted_shots = counts_dict.most_common()\n", " most_common_states = [entry[0] for entry in sorted_shots[:2]]\n", "\n", " if set(most_common_states) != set(expected_colorings):\n", " raise ValueError(\n", " \"The most frequently measured outcomes \"\n", " f\"{most_common_states} did not correspond to the expected graph coloring.\"\n", " )\n", "\n", " num_successful_shots = sum(entry[1] for entry in sorted_shots[:2])\n", " return num_successful_shots / n_shots\n" ] }, { "cell_type": "code", "execution_count": 11, "id": "0bc07733", "metadata": { "execution": { "iopub.execute_input": "2026-06-19T16:05:00.925297Z", "iopub.status.busy": "2026-06-19T16:05:00.925229Z", "iopub.status.idle": "2026-06-19T16:05:00.931454Z", "shell.execute_reply": "2026-06-19T16:05:00.931069Z" } }, "outputs": [ { "data": { "text/plain": [ "'Success ratio: 0.4015'" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "success_ratio = validate_qaoa_experiment(\n", " qaoa_result, expected_result_strings, n_shots\n", ")\n", "f\"Success ratio: {success_ratio:.4f}\"\n" ] }, { "cell_type": "markdown", "id": "0d982b6d", "metadata": {}, "source": [ "The success ratio above counts only samples that land in the two optimal colorings. To compare it with the optimized energy objective, we can group all sampled bitstrings by their max-cut value." ] }, { "cell_type": "code", "execution_count": 12, "id": "de10918b", "metadata": { "execution": { "iopub.execute_input": "2026-06-19T16:05:00.932600Z", "iopub.status.busy": "2026-06-19T16:05:00.932516Z", "iopub.status.idle": "2026-06-19T16:05:00.939604Z", "shell.execute_reply": "2026-06-19T16:05:00.939227Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Expected energy from sampled distribution: 5.0995\n", "Probability of optimal colorings: 0.4015\n", "Probability by cut value:\n", " cut=1: 0.0005\n", " cut=2: 0.0175\n", " cut=3: 0.0425\n", " cut=4: 0.1625\n", " cut=5: 0.3755\n", " cut=6: 0.4015\n" ] } ], "source": [ "from collections import Counter\n", "\n", "\n", "def cut_value(bitstring: str, graph: nx.Graph) -> int:\n", " return sum(int(bitstring[i]) ^ int(bitstring[j]) for i, j in graph.edges)\n", "\n", "\n", "def summarize_cut_distribution(\n", " result: QsysResult, graph: nx.Graph, optimal_colorings: list[str]\n", ") -> None:\n", " counts = result.register_counts()[\"c\"]\n", " total_shots = sum(counts.values())\n", " counts_by_cut = Counter()\n", "\n", " for bitstring, count in counts.items():\n", " counts_by_cut[cut_value(bitstring, graph)] += count\n", "\n", " expected_energy = sum(\n", " cut * count for cut, count in counts_by_cut.items()\n", " ) / total_shots\n", " optimal_probability = sum(\n", " counts.get(bitstring, 0) for bitstring in optimal_colorings\n", " ) / total_shots\n", "\n", " print(f\"Expected energy from sampled distribution: {expected_energy:.4f}\")\n", " print(f\"Probability of optimal colorings: {optimal_probability:.4f}\")\n", " print(\"Probability by cut value:\")\n", " for cut, count in sorted(counts_by_cut.items()):\n", " print(f\" cut={cut}: {count / total_shots:.4f}\")\n", "\n", "\n", "summarize_cut_distribution(qaoa_result, max_cut_graph, expected_result_strings)" ] }, { "cell_type": "markdown", "id": "80e4eb59", "metadata": {}, "source": [ "Finally, we can plot the most common measurement outcomes. If we have done this correctly then the two most common measurement outcomes should correspond to the graph colorings which solve our instance of the max-cut problem " ] }, { "cell_type": "code", "execution_count": 13, "id": "3db27afd", "metadata": { "execution": { "iopub.execute_input": "2026-06-19T16:05:00.940678Z", "iopub.status.busy": "2026-06-19T16:05:00.940609Z", "iopub.status.idle": "2026-06-19T16:05:00.988205Z", "shell.execute_reply": "2026-06-19T16:05:00.987894Z" } }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAABAsAAAI1CAYAAACwmnNQAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAARxdJREFUeJzt3Xu4XfOdP/D3zv3mJBKSI4NIEWnUNXU5da8QxK2iRanQoKNxTauVFhFlomowNJiqJtoyOpT2J26NuI2KW5qMCEUV0eEkbkkkSCJZvz862WM1QQ7n5ES8Xs+znyf7+/2utT5r75W1936fdakURVEEAAAA4H+1aO4CAAAAgFWLsAAAAAAoERYAAAAAJcICAAAAoERYAAAAAJQICwAAAIASYQEAAABQIiwAAAAASoQFAAAAQImwAADgYxg3blwqlUpeeOGF5i4FABqdsAAAmsnSH5uVSiUPPPDAMv1FUWS99dZLpVLJvvvu2wwVNq7bbrstZ5999gqP33XXXauvT6VSSfv27bP55pvnkksuyZIlS5qu0E/g8ssvz7hx45q7DAD4xIQFANDM2rVrl+uuu26Z9vvuuy9/+9vf0rZt22aoqvHddtttGTVqVIOmWXfddfOrX/0qv/rVrzJ69Oi0a9cup556as4888wmqvKTERYAsLoQFgBAM9tnn31yww035L333iu1X3fddenfv39qa2ubqbLm17lz5xxxxBE54ogjcsopp+T+++9Pr169ctlll2Xx4sXNXR4ArLaEBQDQzA477LC8/vrrmTBhQrVt4cKFufHGG/P1r399udNceOGF+dKXvpRu3bqlffv26d+/f2688cbSmLFjx6ZSqeQXv/hFqf1f/uVfUqlUctttt31kbe+++27OPvvs9OnTJ+3atcs666yTgw46KM8991yS5N57702lUsm9995bmu6FF15IpVKp/pX9qKOOypgxY5KkdGpBQ7Vr1y7bbLNN3nrrrcyaNavU9+tf/zr9+/dP+/bt07Vr1xx66KF56aWXSmOeffbZDB48OLW1tWnXrl3WXXfdHHrooZkzZ85y636/SqXyoadRbLDBBpk+fXruu+++6vrtuuuuSZJFixZl1KhR2XjjjdOuXbt069YtO+64Y+k9B4BVSavmLgAAPus22GCD1NXV5T/+4z+y9957J0luv/32zJkzJ4ceemguvfTSZab5t3/7t+y///45/PDDs3Dhwlx//fX56le/mvHjx2fQoEFJkqOPPjo33XRThg8fnj322CPrrbdepk2bllGjRmXo0KHZZ599PrSuxYsXZ999983EiRNz6KGH5uSTT85bb72VCRMm5IknnsiGG264wuv4rW99Ky+//HImTJiQX/3qVw14dZa19Ad9ly5dqm3nnXdezjzzzHzta1/LMccck1dffTWXXXZZdt5550yZMiVdunTJwoULM3DgwCxYsCAnnnhiamtr8z//8z8ZP358Zs+enc6dO3+iui655JKceOKJ6dSpU374wx8mSXr06JEkOfvsszN69Ogcc8wx2XbbbTN37tw89thj+dOf/pQ99tjjEy0XAJqCsAAAVgFf//rXM2LEiLzzzjtp3759rr322uyyyy7p2bPncsc/88wzad++ffX5CSeckK233joXXXRRNSxIkquuuiqbbrpphg4dmvHjx2fIkCGpra3NRRdd9JE1/fKXv8zEiRNz0UUX5dRTT622n3766SmKokHrV1dXlz59+mTChAk54ogjVni6xYsX57XXXkuSvP7667n66qvz2GOPZdCgQdX1f/HFFzNy5Mice+65+cEPflCd9qCDDspWW22Vyy+/PD/4wQ/y5JNP5vnnn88NN9yQgw8+uDrurLPOatC6fJADDzwwZ5xxRtZaa61l1vHWW2/NPvvsk5/97GeNsiwAaGpOQwCAVcDXvva1vPPOOxk/fnzeeuutjB8//gNPQUhSCgrefPPNzJkzJzvttFP+9Kc/lcbV1tZmzJgxmTBhQnbaaadMnTo1v/jFL1JTU/ORNf32t7/NWmutlRNPPHGZvo9zCsHH8ec//zlrr7121l577fTt2zc/+clPsv/++5dOE7jpppuyZMmSfO1rX8trr71WfdTW1mbjjTfOPffckyTVIwfuvPPOvP322yul/qW6dOmS6dOn59lnn12pywWAj8uRBQCwClh77bUzYMCAXHfddXn77bezePHi0l+//9H48eNz7rnnZurUqVmwYEG1fXk/4g899ND8+te/zq233prjjjsuu+++e6n/1VdfLV0ssFOnTunUqVOee+65bLLJJmnVqvm+LmywwQa56qqrsmTJkjz33HM577zz8uqrr6Zdu3bVMc8++2yKosjGG2+83Hm0bt06SdK7d+8MHz48F110Ua699trstNNO2X///XPEEUd84lMQPso555yTAw44IH369MkXvvCF7LXXXvnGN76RzTffvEmXCwAfl7AAAFYRX//613Psscemvr4+e++9d+mc/Pf7r//6r+y///7Zeeedc/nll2edddZJ69atM3bs2OXegvH111/PY489liR58skns2TJkrRo8X8HF26zzTZ58cUXq89Hjhz5oRfye78POsKgse5U0LFjxwwYMKD6fIcddsjWW2+dH/zgB9VrOSxZsiSVSiW33357WrZsucw8OnXqVP33v/7rv+aoo47K73//+/zhD3/ISSedlNGjR+ehhx7Kuuuu22Trs/POO+e5556rLvfnP/95Lr744lx55ZU55phjPtG8AaApCAsAYBXxla98Jd/61rfy0EMP5Te/+c0Hjvvtb3+bdu3a5c4770zbtm2r7WPHjl3u+GHDhuWtt97K6NGjM2LEiFxyySUZPnx4tf/aa6/NO++8U33+uc99Lkmy4YYb5uGHH86iRYuqf53/R2uuuWaSZPbs2aX294cPSzXGqQubb755jjjiiPz7v/97vvvd72b99dfPhhtumKIo0rt37/Tp0+cj57HZZptls802yxlnnJEHH3wwO+ywQ6688sqce+65DVqf5fmwdezatWuOPvroHH300Zk3b1523nnnnH322cICAFZJrlkAAKuITp065YorrsjZZ5+d/fbb7wPHtWzZMpVKpfTX7hdeeCG/+93vlhl744035je/+U3OP//8nH766Tn00ENzxhln5JlnnqmO2WGHHTJgwIDqY2lYMHjw4Lz22mv56U9/usx8l17gsFevXmnZsmXuv//+Uv/ll1++zDQdO3ZMsuwP8Yb63ve+l0WLFlUv0njQQQelZcuWGTVq1DIXXiyKIq+//nqSZO7cuXnvvfdK/ZtttllatGhRPZWjpqYma6211gqtz/J07Nhxueu3tIalOnXqlI022qh0CgkArEocWQAAq5AhQ4Z85JhBgwbloosuyl577ZWvf/3rmTVrVsaMGZONNtoojz/+eHXcrFmzcvzxx2e33XbLCSeckCT56U9/mnvuuSdHHXVUHnjggdLpCP/oyCOPzC9/+csMHz48jzzySHbaaafMnz8/d911V7797W/ngAMOSOfOnfPVr341l112WSqVSjbccMOMHz8+s2bNWmZ+/fv3T5KcdNJJGThwYFq2bJlDDz20oS9R+vXrl3322Sc///nPc+aZZ2bDDTfMueeemxEjRuSFF17IgQcemDXWWCPPP/98br755hx33HH57ne/m7vvvjsnnHBCvvrVr6ZPnz5577338qtf/SotW7bM4MGDq/M/5phjcv755+eYY47JF7/4xdx///2lcOXD9O/fP1dccUXOPffcbLTRRunevXu+/OUvp1+/ftl1113Tv3//dO3aNY899lhuvPHG6vsCAKucAgBoFmPHji2SFI8++uiHjuvVq1cxaNCgUtvVV19dbLzxxkXbtm2Lvn37FmPHji1GjhxZvP+j/aCDDirWWGON4oUXXihN+/vf/75IUvz4xz/+yBrffvvt4oc//GHRu3fvonXr1kVtbW1x8MEHF88991x1zKuvvloMHjy46NChQ7HmmmsW3/rWt4onnniiSFKMHTu2Ou69994rTjzxxGLttdcuKpVK8VFfQ3bZZZdi0003XW7fvffeWyQpRo4cWW377W9/W+y4445Fx44di44dOxZ9+/Ythg0bVjz99NNFURTFX//61+Kb3/xmseGGGxbt2rUrunbtWuy2227FXXfdtcw6Dx06tOjcuXOxxhprFF/72teKWbNmLbO8pe/f888/X22rr68vBg0aVKyxxhpFkmKXXXYpiqIozj333GLbbbctunTpUrRv377o27dvcd555xULFy780NcAAJpLpSgaeKNkAAAAYLXmmgUAAABAibAAAAAAKBEWAAAAACXNGhacffbZqVQqpUffvn2r/e+++26GDRuWbt26pVOnThk8eHBmzpxZmseMGTMyaNCgdOjQId27d89pp522zG2RAAAAgBXX7LdO3HTTTXPXXXdVn7dq9X8lnXrqqbn11ltzww03pHPnzjnhhBNy0EEH5Y9//GOSZPHixRk0aFBqa2vz4IMP5pVXXsmRRx6Z1q1b51/+5V9W+roAAADA6qBZ74Zw9tln53e/+12mTp26TN+cOXOy9tpr57rrrsvBBx+cJPnzn/+cz3/+85k0aVK233773H777dl3333z8ssvp0ePHkmSK6+8Mt///vfz6quvpk2bNitzdQAAAGC10OxHFjz77LPp2bNn2rVrl7q6uowePTrrr79+Jk+enEWLFmXAgAHVsX379s36669fDQsmTZqUzTbbrBoUJMnAgQNz/PHHZ/r06dlqq62Wu8wFCxZkwYIF1edLlizJG2+8kW7duqVSqTTdygIAAEAzKooib731Vnr27JkWLT74ygTNGhZst912GTduXDbZZJO88sorGTVqVHbaaac88cQTqa+vT5s2bdKlS5fSND169Eh9fX2SpL6+vhQULO1f2vdBRo8enVGjRjXuygAAAMCnxEsvvZR11133A/ubNSzYe++9q//efPPNs91226VXr175z//8z7Rv377JljtixIgMHz68+nzOnDlZf/3189JLL6WmpqbJlgsAAADNae7cuVlvvfWyxhprfOi4Zj8N4f26dOmSPn365C9/+Uv22GOPLFy4MLNnzy4dXTBz5szU1tYmSWpra/PII4+U5rH0bglLxyxP27Zt07Zt22Xaa2pqhAUAAACs9j7qFPxmvXXiP5o3b16ee+65rLPOOunfv39at26diRMnVvuffvrpzJgxI3V1dUmSurq6TJs2LbNmzaqOmTBhQmpqatKvX7+VXj8AAACsDpr1yILvfve72W+//dKrV6+8/PLLGTlyZFq2bJnDDjssnTt3ztChQzN8+PB07do1NTU1OfHEE1NXV5ftt98+SbLnnnumX79++cY3vpELLrgg9fX1OeOMMzJs2LDlHjkAAAAAfLRmDQv+9re/5bDDDsvrr7+etddeOzvuuGMeeuihrL322kmSiy++OC1atMjgwYOzYMGCDBw4MJdffnl1+pYtW2b8+PE5/vjjU1dXl44dO2bIkCE555xzmmuVAAAA4FOvUhRF0dxFNLe5c+emc+fOmTNnjmsWAAAAsNpa0d+/q9Q1CwAAAIDmJywAAAAASoQFAAAAQImwAAAAACgRFgAAAAAlwgIAAACgRFgAAAAAlAgLAAAAgBJhAQAAAFAiLAAAAABKhAUAAABAibAAAAAAKBEWAAAAACXCAgAAAKBEWAAAAACUCAsAAACAEmEBAAAAUCIsAAAAAEqEBQAAAECJsAAAAAAoERYAAAAAJcICAAAAoERYAAAAAJQICwAAAIASYQEAAABQIiwAAAAASoQFAAAAQImwAAAAACgRFgAAAAAlwgIAAACgRFgAAAAAlAgLAAAAgBJhAQAAAFAiLAAAAABKhAUAAABAibAAAAAAKBEWAAAAACXCAgAAAKBEWAAAAACUCAsAAACAEmEBAAAAUCIsAAAAAEqEBQAAAECJsAAAAAAoERYAAAAAJcICAAAAoERYAAAAAJQICwAAAIASYQEAAABQ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2GCDBs3riiuuyOabb56amprU1NSkrq4ut99+e7X/3XffzbBhw9KtW7d06tQpgwcPzsyZM0vzmDFjRgYNGpQOHTqke/fuOe200/Lee+81dLUAAACA/9XgsGDMmDGpq6vLq6++mt/+9rfp1q1bkmTy5Mk57LDDGjSvddddN+eff34mT56cxx57LF/+8pdzwAEHZPr06UmSU089NbfccktuuOGG3HfffXn55Zdz0EEHVadfvHhxBg0alIULF+bBBx/MNddck3HjxuWss85q6GoBAAAA/6tSFEXRkAlmzJiRddddNy1alHOGoijy0ksvZf311/9EBXXt2jU/+clPcvDBB2fttdfOddddl4MPPjhJ8uc//zmf//znM2nSpGy//fa5/fbbs+++++bll19Ojx49kiRXXnllvv/97+fVV19NmzZtVmiZc+fOTefOnTNnzpzU1NR8ovpXhsqoSnOXQBMrRjbov2WjsW2t3ppruwIAYNWxor9/G3xkQe/evfPaa68t0/7GG2+kd+/eDZ1d1eLFi3P99ddn/vz5qaury+TJk7No0aIMGDCgOqZv375Zf/31M2nSpCR/vxvDZpttVg0KkmTgwIGZO3du9eiE5VmwYEHmzp1begAAAAB/1+Cw4IMORJg3b17atWvX4AKmTZuWTp06pW3btvnnf/7n3HzzzenXr1/q6+vTpk2bdOnSpTS+R48eqa+vT5LU19eXgoKl/Uv7Psjo0aPTuXPn6mO99dZrcN0AAACwulrhWycOHz48SVKpVHLWWWelQ4cO1b7Fixfn4YcfzpZbbtngAjbZZJNMnTo1c+bMyY033pghQ4bkvvvua/B8GmLEiBHV9Un+fhiGwAAAAAD+boXDgilTpiT5+5EF06ZNK10PoE2bNtliiy3y3e9+t8EFtGnTJhtttFGSpH///nn00Ufzb//2bznkkEOycOHCzJ49u3R0wcyZM1NbW5skqa2tzSOPPFKa39K7JSwdszxt27ZN27ZtG1wrAAAAfBascFhwzz33JEmOPvro/Nu//VuTXQhwyZIlWbBgQfr375/WrVtn4sSJGTx4cJLk6aefzowZM1JXV5ckqaury3nnnZdZs2ale/fuSZIJEyakpqYm/fr1a5L6AAAAYHW3wmHBUmPHjq3++29/+1uSv98C8eMYMWJE9t5776y//vp56623ct111+Xee+/NnXfemc6dO2fo0KEZPnx4unbtmpqampx44ompq6vL9ttvnyTZc889069fv3zjG9/IBRdckPr6+pxxxhkZNmyYIwcAAADgY2rwBQ6XLFmSc845J507d06vXr3Sq1evdOnSJT/60Y+yZMmSBs1r1qxZOfLII7PJJptk9913z6OPPpo777wze+yxR5Lk4osvzr777pvBgwdn5513Tm1tbW666abq9C1btsz48ePTsmXL1NXV5YgjjsiRRx6Zc845p6GrBQAAAPyvSvFBtzf4ACNGjMjVV1+dUaNGZYcddkiSPPDAAzn77LNz7LHH5rzzzmuSQpvSit5nclVRGVVp7hJoYsXIBv23bDS2rdVbc21XAACsOlb092+DT0O45ppr8vOf/zz7779/tW3zzTfPP/3TP+Xb3/72pzIsAAAAAP5Pg09DeOONN9K3b99l2vv27Zs33nijUYoCAAAAmk+Dw4ItttgiP/3pT5dp/+lPf5otttiiUYoCAAAAmk+DT0O44IILMmjQoNx1113VWxhOmjQpL730Um677bZGLxAAAABYuRp8ZMEuu+ySZ555Jl/5ylcye/bszJ49OwcddFCefvrp7LTTTk1RIwAAALASNfjIgiTp2bOnCxkCAADAaupjhQWzZ8/OI488klmzZmXJkiWlviOPPLJRCgMAAACaR4PDgltuuSWHH3545s2bl5qamlQq/3df9kqlIiwAAACAT7kGX7PgO9/5Tr75zW9m3rx5mT17dt58883qw60TAQAA4NOvwWHB//zP/+Skk05Khw4dmqIeAAAAoJk1OCwYOHBgHnvssaaoBQAAAFgFrNA1C/7f//t/1X8PGjQop512Wp588slsttlmad26dWns/vvv37gVAgAAACvVCoUFBx544DJt55xzzjJtlUolixcv/sRFAQAAAM1nhcKCf7w9IgAAALD6avA1CwAAAIDV2wqHBZMmTcr48eNLbb/85S/Tu3fvdO/ePccdd1wWLFjQ6AUCAAAAK9cKhwXnnHNOpk+fXn0+bdq0DB06NAMGDMjpp5+eW265JaNHj26SIgEAAICVZ4XDgqlTp2b33XevPr/++uuz3Xbb5aqrrsrw4cNz6aWX5j//8z+bpEgAAABg5VnhsODNN99Mjx49qs/vu+++7L333tXn22yzTV566aXGrQ4AAABY6VY4LOjRo0eef/75JMnChQvzpz/9Kdtvv321/6233krr1q0bv0IAAABgpVrhsGCfffbJ6aefnv/6r//KiBEj0qFDh+y0007V/scffzwbbrhhkxQJAAAArDytVnTgj370oxx00EHZZZdd0qlTp1xzzTVp06ZNtf8Xv/hF9txzzyYpEgAAAFh5VjgsWGuttXL//fdnzpw56dSpU1q2bFnqv+GGG9KpU6dGLxAAAABYuVY4LFiqc+fOy23v2rXrJy4GAAAAaH4rfM0CAAAA4LNBWAAAAACUCAsAAACAkhUKC7beeuu8+eabSZJzzjknb7/9dpMWBQAAADSfFQoLnnrqqcyfPz9JMmrUqMybN69JiwIAAACazwrdDWHLLbfM0UcfnR133DFFUeTCCy/8wNsknnXWWY1aIAAAALByrVBYMG7cuIwcOTLjx49PpVLJ7bffnlatlp20UqkICwAAAOBTboXCgk022STXX399kqRFixaZOHFiunfv3qSFAQAAAM1jhcKC91uyZElT1AEAAACsIhocFiTJc889l0suuSRPPfVUkqRfv345+eSTs+GGGzZqcQAAAMDKt0J3Q3i/O++8M/369csjjzySzTffPJtvvnkefvjhbLrpppkwYUJT1AgAAACsRA0+suD000/PqaeemvPPP3+Z9u9///vZY489Gq04AAAAYOVr8JEFTz31VIYOHbpM+ze/+c08+eSTjVIUAAAA0HwaHBasvfbamTp16jLtU6dOdYcEAAAAWA00+DSEY489Nscdd1z++te/5ktf+lKS5I9//GN+/OMfZ/jw4Y1eIAAAALByNTgsOPPMM7PGGmvkX//1XzNixIgkSc+ePXP22WfnpJNOavQCAQAAgJWrwWFBpVLJqaeemlNPPTVvvfVWkmSNNdZo9MIAAACA5tHgsOD9hAQAAACw+mnwBQ4BAACA1ZuwAAAAACgRFgAAAAAlDQoLFi1alN133z3PPvtsU9UDAAAANLMGhQWtW7fO448/3lS1AAAAAKuABp+GcMQRR+Tqq69uiloAAACAVUCDb5343nvv5Re/+EXuuuuu9O/fPx07diz1X3TRRY1WHAAAALDyNTgseOKJJ7L11lsnSZ555plSX6VSaZyqAAAAgGbT4LDgnnvuaYo6AAAAgFXEx7514l/+8pfceeedeeedd5IkRVE0WlEAAABA82lwWPD6669n9913T58+fbLPPvvklVdeSZIM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gBJhAQAAAFAiLAAAAABKhAUAAABAibAAAAAAKBEWAAAAACXCAgAAAKBEWAAAAACUNGtYcP/992e//fZLz549U6lU8rvf/a7UXxRFzjrrrKyzzjpp3759BgwYkGeffbY05o033sjhhx+empqadOnSJUOHDs28efNW4loAAADA6qVZw4L58+dniy22yJgxY5bbf8EFF+TSSy/NlVdemYcffjgdO3bMwIED8+6771bHHH744Zk+fXomTJiQ8ePH5/77789xxx23slYBAAAAVjutmnPhe++9d/bee+/l9hVFkUsuuSRnnHFGDjjggCTJL3/5y/To0SO/+93vcuihh+app57KHXfckUcffTRf/OIXkySXXXZZ9tlnn1x44YXp2bPnSlsXAAAAWF2sstcseP7551NfX58BAwZU2zp37pztttsukyZNSpJMmjQpXbp0qQYFSTJgwIC0aNEiDz/88AfOe8GCBZk7d27pAQAAAPzdKhsW1NfXJ0l69OhRau/Ro0e1r76+Pt27dy/1t2rVKl27dq2OWZ7Ro0enc+fO1cd6663XyNUDAADAp9cqGxY0pREjRmTOnDnVx0svvdTcJQEAAMAqY5UNC2pra5MkM2fOLLXPnDmz2ldbW5tZs2aV+t9777288cYb1THL07Zt29TU1JQeAAAAwN+tsmFB7969U1tbm4kTJ1bb5s6dm4cffjh1dXVJkrq6usyePTuTJ0+ujrn77ruzZMmSbLfddiu9ZgAAAFgdNOvdEObNm5e//OUv1efPP/98pk6dmq5du2b99dfPKaecknPPPTcbb7xxevfunTPPPDM9e/bMgQcemCT5/Oc/n7322ivHHntsrrzyyixatCgnnHBCDj30UHdCAAAAgI+pWcOCxx57LLvttlv1+fDhw5MkQ4YMybhx4/K9730v8+fPz3HHHZfZs2dnxx13zB133JF27dpVp7n22mtzwgknZPfdd0+LFi0yePDgXHrppSt9XQAAAGB10axhwa677pqiKD6wv1Kp5Jxzzsk555zzgWO6du2a6667rinKAwAAgM+kVfaaBQAAAEDzEBYAAAAAJcICAAAAoERYAAAAAJQICwAAAIASYQEAAABQIiwAAAAASoQFAAAAQImwAAAAACgRFgAAAAAlwgIAAACgRFgAAAAAlAgLAAAAgBJhAQAAAFAiLAAAAABKhAUAAABAibAAAAAAKBEWAAAAACXCAgAAAKBEWAAAAACUCAsAAACAEmEBAAAAUCIsAAAAAEqEBQAAAECJsAAAAAAoERYAAAAAJcICAAAAoERYAAAAAJQICwAAAIASYQEAAABQIiwAAAAASoQFAAAAQImwAAAAACgRFgAAAAAlwgIAAACgRFgAAAAAlAgLAAAAgBJhAQAAAFAiLAAAAABKhAUAAABAibAAAAAAKBEWAAAAACXCAgAAAKBEWAAAAACUCAsAAACAEmEBAAAAUCIsAAAAAEqEBQAAAECJsAAAAAAoERYAAAAAJcICAAAAoERYAAAAAJQICwAAAIASYQEAAABQIiwAAAAASoQFAAAAQImwAAAAACgRFgAAAAAlwgIAAACgRFgAAAAAlAgLAAAAgBJhAQAAAFAiLAAAAABKhAUAAABAibAAAAAAKBEWAAAAACXCAgAAAKBEWAAAAACUCAsAAACAEmEBAAAAUCIsAAAAAEqEBQAAAECJsAAAAAAoERYAAAAAJcICAAAAoERYAAAAAJQICwAAAIASYQEAAABQIiwAAAAASoQFAAAAQImwAAAAACgRFgAAAAAlwgIAAACgRFgAAAAAlAgLAAAAgJLVJiwYM2ZMNthgg7Rr1y7bbbddHnnkkeYuCQAAAD6VVouw4De/+U2GDx+ekSNH5k9/+lO22GKLDBw4MLNmzWru0gAAAOBTZ7UICy666KIce+yxOfroo9OvX79ceeWV6dChQ37xi180d2kAAADwqdOquQv4pBYuXJjJkydnxIgR1bYWLVpkwIABmTRp0nKnWbBgQRYsWFB9PmfOnCTJ3Llzm7bYxvJucxdAU2u2bdG2tVprtu3q7eZZLCuRbYumYLuiqdi2aAqflt+S+b/vhEVRfOi4T31Y8Nprr2Xx4sXp0aNHqb1Hjx7585//vNxpRo8enVGjRi3Tvt566zVJjdBQnc/v3NwlsBqyXdFkjrVt0QRsVzQV2xZN4VO4Xb311lvp3PmD6/7UhwUfx4gRIzJ8+PDq8yVLluSNN95It27dUqlUmrEy/tHcuXOz3nrr5aWXXkpNTU1zl8NqxLZFU7Bd0VRsWzQF2xVNxba1aiuKIm+99VZ69uz5oeM+9WHBWmutlZYtW2bmzJml9pkzZ6a2tna507Rt2zZt27YttXXp0qWpSqQR1NTU2NHQJGxbNAXbFU3FtkVTsF3RVGxbq64PO6JgqU/9BQ7btGmT/v37Z+LEidW2JUuWZOLEiamrq2vGygAAAODT6VN/ZEGSDB8+PEOGDMkXv/jFbLvttrnkkksyf/78HH300c1dGgAAAHzqrBZhwSGHHJJXX301Z511Vurr67PlllvmjjvuWOaih3z6tG3bNiNHjlzmtBH4pGxbNAXbFU3FtkVTsF3RVGxbq4dK8VH3SwAAAAA+Uz711ywAAAAAGpewAAAAACgRFgAAAAAlwgIAAACgRFjAxzJmzJhssMEGadeuXbbbbrs88sgj1b6f/exn2XXXXVNTU5NKpZLZs2cvM/0bb7yRww8/PDU1NenSpUuGDh2aefPmlcY8/vjj2WmnndKuXbust956ueCCC0r906dPz+DBg7PBBhukUqnkkksuaXCtSfLuu+9m2LBh6datWzp16pTBgwdn5syZH++F4WO7//77s99++6Vnz56pVCr53e9+V+oviiJnnXVW1llnnbRv3z4DBgzIs88+Wxpz3nnn5Utf+lI6dOiQLl26LHc5J510Uvr375+2bdtmyy23XO6Yxtj2Pmp9WHmaen/17rvv5qijjspmm22WVq1a5cADD1xuHffee2+23nrrtG3bNhtttFHGjRtX6l+Rbeamm27KnnvumW7duqVSqWTq1Kkf4xWhMaysfdaMGTMyaNCgdOjQId27d89pp52W9957r9r/yiuv5Otf/3r69OmTFi1a5JRTTlnufG644Yb07ds37dq1y2abbZbbbrutwfXS9FaVz8LG2q8lH/09jJVnVfj+nnz0/mhFPutWpF4+OWEBDfab3/wmw4cPz8iRI/OnP/0pW2yxRQYOHJhZs2YlSd5+++3stdde+cEPfvCB8zj88MMzffr0TJgwIePHj8/999+f4447rto/d+7c7LnnnunVq1cmT56cn/zkJzn77LPzs5/9rDrm7bffzuc+97mcf/75qa2t/Vi1Jsmpp56aW265JTfccEPuu+++vPzyyznooIM+6ctEA82fPz9bbLFFxowZs9z+Cy64IJdeemmuvPLKPPzww+nYsWMGDhyYd999tzpm4cKF+epXv5rjjz/+Q5f1zW9+M4cccshy+xpr2/uo9WHlWBn7q8WLF6d9+/Y56aSTMmDAgOXO4/nnn8+gQYOy2267ZerUqTnllFNyzDHH5M4776yOWZFtZv78+dlxxx3z4x//uKEvBY1sZeyzFi9enEGDBmXhwoV58MEHc80112TcuHE566yzqmMWLFiQtddeO2eccUa22GKL5c7nwQcfzGGHHZahQ4dmypQpOfDAA3PggQfmiSeeaFC9NL1V5bOwsfZrK/I9jJVjVfn+viL7oxX5rFuRemkEBTTQtttuWwwbNqz6fPHixUXPnj2L0aNHl8bdc889RZLizTffLLU/+eSTRZLi0UcfrbbdfvvtRaVSKf7nf/6nKIqiuPzyy4s111yzWLBgQXXM97///WKTTTZZbk29evUqLr744gbXOnv27KJ169bFDTfcUB3z1FNPFUmKSZMmfcQrQVNJUtx8883V50uWLClqa2uLn/zkJ9W22bNnF23bti3+4z/+Y5npx44dW3Tu3PlDlzFy5Mhiiy22WKa9sba9D1sfVp6Vsb96vyFDhhQHHHDAMu3f+973ik033bTUdsghhxQDBw5cbt0ftc08//zzRZJiypQpHziGlaep9lm33XZb0aJFi6K+vr7adsUVVxQ1NTWlfdRSu+yyS3HyyScv0/61r32tGDRoUKltu+22K771rW99rHpZOZrzs/D9Psl+bUX3wTS9VeX7+0ftj95vRT7rPqheGocjC2iQhQsXZvLkyaWUuUWLFhkwYEAmTZq0QvOYNGlSunTpki9+8YvVtgEDBqRFixZ5+OGHq2N23nnntGnTpjpm4MCBefrpp/Pmm282Wq2TJ0/OokWLSmP69u2b9ddff4XXh6b3/PPPp76+vvQ+de7cOdttt12jv0+Nse2xalhZ+6sVnc8//nVu4MCB9jOrqcbaZ02aNCmbbbZZevToUW0bOHBg5s6dm+nTpzdoPh+2/a3MfSwf36r2Pn3UdtUY+2Aax6r0/d3n4aeLsIAGee2117J48eLSF5ck6dGjR+rr61doHvX19enevXuprVWrVunatWt1HvX19ctdxtK+xqq1vr4+bdq0WeacvoasD01v6XvxSba7hizrk257rBpW1v5qReezvDrmzp2bd955Z4Xnw6dDY+2zGmt/9EHzef9nYWPUS9Na1d6nj9qvNcY+mMaxKn1//6j9EasWYQEAAABQIiygQdZaa620bNlymbsFzJw58wMv9PaPamtrl7mwzXvvvZc33nijOo/a2trlLmNpX2PVWltbm4ULFy5zBdWGrA9Nb+l78Um2u4Ys65Nue6waVtb+akXns7w6ampq0r59+xWeD58OjbXPaqz90QfN5/2fhY1RL01rVXufPmq/1hj7YBrHqvT9/aP2R6xahAU0SJs2bdK/f/9MnDix2rZkyZJMnDgxdXV1KzSPurq6zJ49O5MnT6623X333VmyZEm222676pj7778/ixYtqo6ZMGFCNtlkk6y55pqNVmv//v3TunXr0pinn346M2bMWOH1oen17t07tbW1pfdp7ty5efjhhxv9fWqMbY9Vw8raX63ofN5fR/L37cp+ZvXUWPusurq6TJs2rfQFfcKECampqUm/fv0aNJ8P2/5W5j6Wj29Ve58+artqjH0wjWNV+v7u8/BTprmvsMinz/XXX1+0bdu2GDduXPHkk08Wxx13XNGlS5fq1ZpfeeWVYsqUKcVVV11VJCnuv//+YsqUKcXrr79encdee+1VbLXVVsXDDz9cPPDAA8XGG29cHHbYYdX+2bNnFz169Ci+8Y1vFE888URx/fXXFx06dCj+/d//vTpmwYIFxZQpU4opU6YU66yzTvHd7363mDJlSvHss8+ucK1FURT//M//XKy//vrF3XffXTz22GNFXV1dUVdX15QvIcvx1ltvVd/PJMVFF11UTJkypXjxxReLoiiK888/v+jSpUvx+9//vnj88ceLAw44oOjdu3fxzjvvVOfx4osvFlOmTClGjRpVdOrUqTq/t956qzrm2WefLaZMmVJ861vfKvr06VMds/TKvY217X3U+rByrIz9VVEUxfTp04spU6YU++23X7HrrrtW3/ul/vrXvxYdOnQoTjvttOKpp54qxowZU7Rs2bK44447qmNWZJt5/fXXiylTphS33nprkaS4/vrriylTphSvvPJKE72CfJCVsc967733ii984QvFnnvuWUydOrW44447irXXXrsYMWJEqZal0/Xv37/4+te/XkyZMqWYPn16tf+Pf/xj0apVq+LCCy8snnrqqWLkyJFF69ati2nTplXHrEi9NL1V5bOwKBpnv7Yi38NYOVaV7+8rsj9akc+6FamXT05YwMdy2WWXFeuvv37Rpk2bYtttty0eeuihat/IkSOLJMs8xo4dWx3z+uuvF4cddljRqVOnoqampjj66KNLH2JFURT//d//Xey4445F27Zti3/6p38qzj///FL/0tup/ONjl112WeFai6Io3nnnneLb3/52seaaaxYdOnQovvKVr/ji3QyW3vrmHx9DhgwpiuLvt4w688wzix49ehRt27Ytdt999+Lpp58uzWPIkCHLncc999xTHbPLLrssd8zzzz9fHdMY295HrQ8rz8rYX/Xq1Wu583m/e+65p9hyyy2LNm3aFJ/73OdKy1ja/1HbzNixY5c7ZuTIkY31crGCVtY+64UXXij23nvvon379sVaa61VfOc73ykWLVpUms/y5tGrV6/SmP/8z/8s+vTpU7Rp06bYdNNNi1tvvbXUvyL10vRWpc/CxtivFcVHfw9j5VkVvr8XxUfvj1bks25F6uWTqxRFUQQAAADgf7lmAQAAAFAiLAAAAABKhAUAAABAibAAAAAAKBEWAAAAACXCAgAAAKBEWAAAAACUCAsAAACAEmEBANAoxo0bly5dujR3GQBAIxAWAMBnwFFHHZVKpVJ9dOvWLXvttVcef/zxRlvGIYcckmeeeeZjT//f//3f2X///dO9e/e0a9cuG2ywQQ455JDMmjUrSXLvvfemUqlk9uzZDZrvCy+8kEqlkqlTp37s2gDgs0ZYAACfEXvttVdeeeWVvPLKK5k4cWJatWqVfffdt9Hm3759+3Tv3v1jTfvqq69m9913T9euXXPnnXfmqaeeytixY9OzZ8/Mnz+/0WoEAFaMsAAAPiPatm2b2tra1NbWZsstt8zpp5+el156Ka+++mp1zPe///306dMnHTp0yOc+97mceeaZWbRoUbX/v//7v7PbbrtljTXWSE1NTfr375/HHnssybKnIXzY2H/0xz/+MXPmzMnPf/7zbLXVVundu3d22223XHzxxendu3deeOGF7LbbbkmSNddcM5VKJUcddVSS5I477siOO+6YLl26pFu3btl3333z3HPPVefdu3fvJMlWW22VSqWSXXfdtdr385//PJ///OfTrl279O3bN5dffvkneo0BYHXRqrkLAABWvnnz5uXXv/51Ntpoo3Tr1q3avsYaa2TcuHHp2bNnpk2blmOPPTZrrLFGvve97yVJDj/88Gy11Va54oor0rJly0ydOjWtW7de7jIaMra2tjbvvfdebr755hx88MGpVCql/vXWWy+//e1vM3jw4Dz99NOpqalJ+/btkyTz58/P8OHDs/nmm2fevHk566yz8pWvfCVTp05NixYt8sgjj2TbbbfNXXfdlU033TRt2rRJklx77bU566yz8tOf/jRbbbVVpkyZkmOPPTYdO3bMkCFDPvFrDACfZpWiKIrmLgIAaFpHHXVUfv3rX6ddu3ZJ/v4De5111sn48eOz9dZbf+B0F154Ya6//vrqEQE1NTW57LLLlvtjety4cTnllFOq1xT4sLHL88Mf/jAXXHBBampqsu222+bLX/5yjjzyyPTo0SPJ369ZsNtuu+XNN9/80Aspvvbaa1l77bUzbdq0fOELX8gLL7yQ3r17Z8qUKdlyyy2r4zbaaKP86Ec/ymGHHVZtO/fcc3PbbbflwQcfXKGaAWB15TQEAPiM2G233TJ16tRMnTo1jzzySAYOHJi99947L774YnXMb37zm+ywww6pra1Np06dcsYZZ2TGjBnV/uHDh+eYY47JgAEDcv7555cO9/9HDRmbJOedd17q6+tz5ZVXZtNNN82VV16Zvn37Ztq0aR863bPPPpvDDjssn/vc51JTU5MNNtggSUp1/6P58+fnueeey9ChQ9OpU6fq49xzz/3IOgHgs0BYAACfER07dsxGG22UjTbaKNtss01+/vOfZ/78+bnqqquSJJMmTcrhhx+effbZJ+PHj8+UKVPywx/+MAsXLqzO4+yzz8706dMzaNCg3H333enXr19uvvnm5S6vIWOX6tatW7761a/mwgsvzFNPPZWePXvmwgsv/NBp9ttvv7zxxhu56qqr8vDDD+fhhx9OklLd/2jevHlJkquuuqoaoEydOjVPPPFEHnrooQ9dHgB8FrhmAQB8RlUqlbRo0SLvvPNOkuTBBx9Mr1698sMf/rA65v1HHSzVp0+f9OnTJ6eeemoOO+ywjB07Nl/5yleWu4yGjP1Hbdq0yYYbbli9G8LSaw0sXry4Oub111/P008/nauuuio77bRTkuSBBx5YZj7/OF2PHj3Ss2fP/PWvf83hhx++QvUAwGeJsAAAPiMWLFiQ+vr6JMmbb76Zn/70p5k3b17222+/JMnGG2+cGTNm5Prrr88222yTW2+9tXQkwDvvvJPTTjstBx98cHr37p2//e1vefTRRzN48OBlltWQsUkyfvz4XH/99Tn00EPTp0+fFEWRW265JbfddlvGjh2bJOnVq1cqlUrGjx+fffbZJ+3bt8+aa66Zbt265Wc/+1nWWWedzJgxI6effnpp3t27d0/79u1zxx13ZN111027du3SuXPnjBo1KieddFI6d+6cvfbaKwsWLMhjjz2WN998M8OHD2+U1xwAPrUKAGC1N2TIkCJJ9bHGGmsU22yzTXHjjTeWxp122mlFt27dik6dOhWHHHJIcfHFFxedO3cuiqIoFixYUBx66KHFeuutV7Rp06bo2bNnccIJJxTvvPNOURRFMXbs2BUe+4+ee+654thjjy369OlTtG/fvujSpUuxzTbbFGPHji2NO+ecc4ra2tqiUqkUQ4YMKYqiKCZMmFB8/vOfL9q2bVtsvvnmxb333lskKW6++ebqdFdddVWx3nrrFS1atCh22WWXavu1115bbLnllkWbNm2KNddcs9h5552Lm2666WO/zgCwunA3BAAAAKDEBQ4BAACAEmEBAAAAUCIsAAAAAEqEBQAAAECJsAAAAAAoERYAAAAAJcICAAAAoERYAAAAAJQICwAAAIASYQEAAABQIiwAAAAASv4/E1sV/F4qt7AAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "\n", "\n", "def plot_max_cut_results(result: QsysResult, n_strings: int) -> None:\n", " \"\"\"\n", " Plots Max-cut results in a barchart with the two most common bitstrings highlighted in green.\n", " \"\"\"\n", " counts_dict = result.register_counts()[\"c\"]\n", " sorted_shots = counts_dict.most_common()\n", " n_shots = sum(counts_dict.values())\n", "\n", " n_most_common_strings = sorted_shots[:n_strings]\n", " x_axis_values = [str(entry[0]) for entry in n_most_common_strings] # basis states\n", " y_axis_values = [entry[1] for entry in n_most_common_strings] # counts\n", "\n", " fig = plt.figure()\n", " ax = fig.add_axes([0, 0, 1.5, 1])\n", " color_list = [\"green\"] * 2 + ([\"orange\"] * (len(x_axis_values) - 2))\n", " ax.bar(\n", " x=x_axis_values,\n", " height=y_axis_values,\n", " color=color_list,\n", " )\n", " ax.set_title(label=\"Max-cut Results\")\n", " plt.ylim([0, 0.25 * n_shots])\n", " plt.xlabel(\"Basis State\")\n", " plt.ylabel(\"Number of Shots\")\n", " plt.show()\n", "\n", "\n", "plot_max_cut_results(qaoa_result, n_strings=6)" ] }, { "cell_type": "markdown", "id": "f86889de", "metadata": {}, "source": [ "The two green bars correspond to the expected colorings of our seven vertex graph. These colorings are equivalent up to the swapping of blue and red nodes." ] }, { "cell_type": "code", "execution_count": 14, "id": "bd2b90be", "metadata": { "execution": { "iopub.execute_input": "2026-06-19T16:05:00.989398Z", "iopub.status.busy": "2026-06-19T16:05:00.989327Z", "iopub.status.idle": "2026-06-19T16:05:01.020603Z", "shell.execute_reply": "2026-06-19T16:05:01.020270Z" } }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAA90AAAGGCAYAAABmGOKbAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAa7JJREFUeJzt3Xd4XNW19/HvFPUuy3LFuGBcIcY2rti4dxnbSJcEEgIhoSekEu7NhZByeVNubmiBmEASQoAEyd2WK+5g3AvgXnFVsyxbstrMnPePgwbbkvHMaEZnJP0+z6PHnqM5Zy/xGK1Z5+y9l80wDAMRERERERERCTq71QGIiIiIiIiINFUqukVERERERERCREW3iIiIiIiISIio6BYREREREREJERXdIiIiIiIiIiGioltEREREREQkRFR0i4iIiIiIiISIim4RERERERGREFHRLSIiIiIiIhIiKrpFwsjRo0ex2Wz8/e9/D+p1n332WWw2W1CvKSIi0lwpX4uIP1R0i0hI7du3jx/84AcMGTKE6OhobDYbR48etTosERERucTs2bO566676Ny5M7GxsXTr1o0f/ehHnDt3zurQRBo9Fd0izcB///d/U15ebsnYGzZs4MUXX+TChQv06NHDkhhEREQaAyvz9YMPPsiePXv4+te/zosvvsiECRN4+eWXGTx4sGUxiTQVTqsDEJHQKSsrIy4uDqfTidNpzf/uU6dO5dy5cyQkJPC///u/7Nixw5I4REREwlU45OucnBxGjBhx2bF+/frxzW9+k7fffptvf/vblsQl0hToSbdIEJw8eZIHHniAtm3bEhUVRadOnXjkkUeoqqryvufw4cNkZWWRmppKbGwsgwYNYtGiRT5df+XKlQwbNoy4uDiSk5O544472LNnz2XvqVkHtnv3bu6++25SUlK47bbbLvvepWw2G48//jhz586ld+/eREVF0atXL5YsWVJr/NWrV9O/f3+io6Pp0qULM2fO9HndWWpqKgkJCT79nCIiIqGkfH11VxbcANOnTweo9TOIiH/0pFuknk6dOsWAAQM4d+4cDz74IN27d+fkyZPk5ORw8eJFIiMjycvLY8iQIVy8eJHvfe97tGjRgjfffJOpU6eSk5PjTWp1WbFiBRMnTqRz5848++yzlJeX89JLLzF06FC2bdtGx44dL3t/VlYWXbt25bnnnsMwjC+Nff369cyePZtHH32UhIQEXnzxRe68804+++wzWrRoAcD27duZMGECbdq04Re/+AVut5tf/vKXtGzZst7/7URERBqK8rX/zpw5A0BaWlrA1xARwBCRern33nsNu91ubN68udb3PB6PYRiG8f3vf98AjHXr1nm/d+HCBaNTp05Gx44dDbfbbRiGYRw5csQAjL/97W/e9/Xp08dIT083ioqKvMd27txp2O1249577/Ue+/nPf24Axte+9rVacdR871KAERkZaRw8ePCy6wLGSy+95D2WkZFhxMbGGidPnvQeO3DggOF0Omtd81p+//vfG4Bx5MgRv84TERGpL+Vr/z3wwAOGw+Ew9u/fH9D5ImLS9HKRevB4PMydO5eMjAz69+9f6/s107lyc3MZMGCAd/oYQHx8PA8++CBHjx5l9+7ddV7/9OnT7Nixg/vuu4/U1FTv8ZtvvpmxY8eSm5tb65yHH37Y5/jHjBlDly5dLrtuYmIihw8fBsDtdrNixQqmTZtG27Ztve+74YYbmDhxos/jiIiIWEn52n/vvPMOb7zxBj/60Y/o2rVrQNcQEZOKbpF6KCgo4Pz58/Tu3ftL33fs2DG6detW63jNbt7Hjh276nnAVc8tLCykrKzssuOdOnXyKXaADh061DqWkpJCcXExAPn5+ZSXl3PDDTfUel9dx0RERMKR8rV/1q1bxwMPPMD48eP5n//5H7/PF5HLqegWaWJiYmJ8fq/D4ajzuHGNtWUiIiJSP+Gar3fu3MnUqVPp3bs3OTk5lu2mLtKUqOgWqYeWLVuSmJjIJ5988qXvu/7669m3b1+t43v37vV+/2rnAVc9Ny0tjbi4OH/D9ll6ejrR0dEcPHiw1vfqOiYiIhKOlK99c+jQISZMmEB6ejq5ubnEx8cHM0yRZktFt0g92O12pk2bxoIFC9iyZUut79fcgZ40aRKbNm1iw4YN3u+VlZXx2muv0bFjR3r27Fnn9du0aUOfPn148803OXfunPf4J598wrJly5g0aVJwf6ArOBwOxowZw9y5czl16pT3+MGDB1m8eHFIxxYREQkW5etrO3PmDOPGjcNut7N06VJ1KREJIs0XEamn5557jmXLlnH77bfz4IMP0qNHD06fPk12djbr168nOTmZp556infffZeJEyfyve99j9TUVN58802OHDnCrFmzsNuvfv/r97//PRMnTmTw4ME88MAD3hYkSUlJPPvssyH/+Z599lmWLVvG0KFDeeSRR3C73bz88sv07t2bHTt2XPP8kpISXnrpJQA++OADAF5++WWSk5NJTk7m8ccfD2X4IiIigPL1tUyYMIHDhw/z5JNPsn79etavX+/9XqtWrRg7dmwIoxdp2lR0i9RTu3bt2LhxI08//TRvv/0258+fp127dkycOJHY2FjATFYffvghP/3pT3nppZeoqKjg5ptvZsGCBUyePPlLrz9mzBiWLFnCz3/+c5555hkiIiK4/fbb+e1vf+vXJiyB6tevH4sXL+bHP/4xTz/9NNdddx2//OUv2bNnj3e63ZcpLi7m6aefvuzYH/7wB8CcjqeiW0REGoLy9ZfbuXMnAL/73e9qfe/2229X0S1SDzZDOyaJSACmTZvGp59+yoEDB6wORURERK5C+VrEelrTLSLXVF5eftnrAwcOkJuby4gRI6wJSERERGpRvhYJT3rSLSLX1KZNG+677z46d+7MsWPHePXVV6msrGT79u107drV6vBEREQE5WuRcKU13SJyTRMmTODdd9/lzJkzREVFMXjwYJ577jklcBERkTCifC0SnvSkW0RERERERCREtKZbREREREREJERUdIuIiIiIiIiEiIpuERERERERkRBR0S0iIiIiIiISIiq6RUREREREREJERbeIiIiIiIhIiKjoFhEREREREQkRFd0iIiIiIiIiIaKiW0RERERERCREVHSLiIiIiIiIhIiKbhEREREREZEQUdEtIiIiIiIiEiIqukVERERERERCREW3iIiIiIiISIio6BYREREREREJERXdIiIiIiIiIiGioltEREREREQkRJxWByDSqJw6BVu2wNatsGcPlJaCzQYJCdC7N/TrB/37Q8uWVkcqIiLSbFVVwa5dZrretg3OnIHKSoiOhrZtv0jXvXqBU5+GRSTEbIZhGFYHIRLWqqth7lx46SVYt8485nSCx2N+AdjtZvHtdpt/jh8Pjz8OEyaAw2FZ6CIiIs3J4cPw5z/Da69BSYmZkh0OcLm+eE9EhJnawbxH/uij8J3vQLt21sQsIk2fim6RL7NgATz4oHmL3OEwi2pf1Ly3Uyf429/g9ttDG6eIiEgzdvYsfP/78M9/mvfBfU3XYL4f4LHH4P/9P4iLC0mIItKMqegWqUtxMXzve19k75on2v6q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/whpaaG9d22zQUwMvP66+XeR5k4bqYlIcLjd5u3suXPNp9HB5nCY258uWaK+IyIiIvWwYYP51LuqKvgp22YzC/oFC8wn3SKiJ90iEiwOB7zzDkyeHPzb2nY7DB5sZnAV3CIiIvUyeDAsXGh2/QzmVHO73bzev/+tglvkUiq6RSR4oqJg9mz47nfN1/XN5DVz3+65B5Ytg/j4+l1PREREABg9GtasgbZtgzPV3OGAFi1g8WK48876X0+kKVHRLSLB5XTCCy/AqlXQrp351DuQJ992u5m9FywwN06LiQl+rCIiIs3YgAGwezc8+qj5OpBGJDXn3H037NsHY8YELz6RpkJrukUkdMrK4O9/hxdfhP37zczsdsPVfu1EREB1NXToYD4t//a3ITm5ISMWERFplrZuNdP1u++Cy2U+uXa56n6v02muBbfZYMYMM2UPG9aw8Yo0Jiq6RST0DAPWroXly2HzZvOruPiL7yckwK23ml+jRpm3ydUSTEREpMEVFUFODmzaBB99BHv3frHZmt0OXbrAoEFmys7MhDZtrI1XpDFQ0S0i1qiuhspKcx14RITV0YiIiEgdPB4zXRsGREfrnrhIIFR0i4iIiIiIiISI7lWJiIiIiIiIhIiKbhEREREREZEQUdEtIiIiIiIiEiIqukVERERERERCREW3iIiIiIiISIio6BYREREREREJERXdIiIiIiIiIiGioltEREREREQkRFR0i4iIiIiIiISIim4RERERERGREFHRLSIiIiIiIhIiKrpFREREREREQkRFt4iIiIiIiEiIqOgWERERERERCREV3SIiIiIiIiIhoqJbREREREREJERUdIuIiIiIiIiEiIpuERERERERkRBR0S0iIiIiIiISIiq6RUREREREREJERbeIiIiIiIhIiKjoFhEREREREQmR/w/bR98BzOMxCQAAAABJRU5ErkJggg==", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "G = nx.Graph()\n", "G.add_edges_from(max_cut_graph_edges)\n", "\n", "H = nx.Graph()\n", "H.add_edges_from(max_cut_graph_edges)\n", "\n", "# Use same layout for both graphs\n", "pos = nx.kamada_kawai_layout(G)\n", "\n", "fig, axes = plt.subplots(1, 2, figsize=(10, 4))\n", "\n", "# First coloring\n", "nx.draw(\n", " G,\n", " pos=pos,\n", " ax=axes[0],\n", " with_labels=True,\n", " node_color=[\"red\", \"blue\", \"red\", \"red\", \"blue\", \"red\", \"red\"],\n", " node_size=500,\n", " edge_color=\"gray\",\n", " width=2,\n", " font_size=12,\n", " font_color=\"white\",\n", ")\n", "axes[0].set_title(\"coloring 1\")\n", "axes[0].set_axis_off()\n", "\n", "# Second coloring\n", "nx.draw(\n", " H,\n", " pos=pos,\n", " ax=axes[1],\n", " with_labels=True,\n", " node_color=[\"blue\", \"red\", \"blue\", \"blue\", \"red\", \"blue\", \"blue\"],\n", " node_size=500,\n", " edge_color=\"gray\",\n", " width=2,\n", " font_size=12,\n", " font_color=\"white\",\n", ")\n", "axes[1].set_title(\"coloring 2\")\n", "axes[1].set_axis_off()\n", "\n", "plt.tight_layout()\n", "plt.show()" ] } ], "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.12.12" } }, "nbformat": 4, "nbformat_minor": 5 }