{ "cells": [ { "attachments": {}, "cell_type": "markdown", "id": "6ddb8a88-779a-43f7-ae14-115463bd87f5", "metadata": {}, "source": [ "# Portfolio Optimization\n", "\n", "In this tutorial, we demonstrate the transformation of financial portfolio optimization into a quadratic unconstrained binary optimization (QUBO) problem. Subsequently, we employ the Quantum Approximate Optimization Algorithm (QAOA) to solve it. We will conduct a comparative analysis between the outcomes obtained through QAOA and those derived from classical brute force searching. Additionally, we explore the potential for enhancing results by customizing the QAOA 'mixer' component.\n", "\n", "## Introduction\n", "\n", "Consider the following scenario: Xiaoming, an astute individual, possesses a sum of money represented by $B$ and is contemplating investing it in the stock market. The market contains $n$ shares, each having an identical price. Xiaoming's objective is to maximize returns while minimizing risk, taking into account the varying levels of risk tolerance among individuals. Xiaoming's personal risk tolerance is represented by $q$. In light of these considerations, the question arises: Which shares should Xiaoming choose to construct an optimal portfolio?\n", "\n", "Xiaoming's predicament falls under the purview of portfolio optimization problems. These problems are classified as Quadratic Unconstrained Binary Optimization (QUBO) problems, wherein binary numbers are utilized to represent decisions. In this case, \"1\" signifies selection, while \"0\" denotes the opposite. To address the challenge of portfolio optimization, the Quantum Approximate Optimization Algorithm (QAOA) is employed.\n", "\n", "## Solving portfolio optimization problems with QAOA\n", "\n", "In a simple boolean Markowitz portfolio optimization problem, we wish to solve \n", "\n", "$$\n", "\\min_{x\\in\\{0,1\\}^n}\\quad q x^T \\Sigma x - \\mu^T x\n", "$$\n", "\n", "subject to a constraint\n", "\n", "$$\n", "1^T x = B\n", "$$\n", "\n", "where \n", "* $n$: number of assets under consideration\n", "* $q > 0 $: risk-appetite\n", "* $\\Sigma \\in \\mathbb{R}^{n\\times n}$: covariance matrix of the assets\n", "* $\\mu\\in\\mathbb{R}^n$: mean return of the assets\n", "* $B$: budget (i.e., the total number of assets out of $n$ that can be selected)\n", "\n", "Our first step is to convert this constrained quadratic programming problem into a QUBO. We do this by adding a penalty factor $t$ and considering the alternative problem:\n", "\n", "$$\n", "\\min_{x\\in\\{0,1\\}^n}\\quad q x^T \\Sigma x - \\mu^Tx + t(1^Tx-B)^2\n", "$$\n", "\n", "The linear terms $\\mu^Tx = \\mu_1 x_1 + \\mu_2 x_2+\\ldots$ can all be transformed into squared forms, exploiting the properties of boolean variables where $0^2=0$ and $1^2=1$. The same trick is applied to the middle term of $t(1^Tx-B)^2$. Then the function is written as\n", "\n", "$$\n", "\\min_{x\\in\\{0,1\\}^n}\\quad q x^T \\Sigma x - \\sum_{i=1}^n\\mu_i x_i^2 + t(1^Tx-B)^2\n", "$$\n", "\n", "which is a QUBO problem\n", "\n", "$$\n", "\\min_{x\\in\\{0,1\\}^n}\\quad x^T Q x + tB^2\n", "$$\n", "\n", "where matrix $Q$ is\n", "\n", "$$\n", "Q = q\\Sigma -\\mu\\begin{pmatrix}1 & \\\\ & 1\\\\ & & \\ddots\\end{pmatrix} + t\\begin{pmatrix}1 -2B & 1 & \\ldots & 1 \\\\\n", "1 & 1-2B & 1 & \\ldots \\\\1 & 1 & 1-2B \\\\\n", "\\vdots\\end{pmatrix}\n", "$$\n", "\n", "and we ignore the constant term $t B^2$. We can now solve this by QAOA.\n", "\n", "## Set up" ] }, { "cell_type": "code", "execution_count": 2, "id": "4f4feab6", "metadata": {}, "outputs": [], "source": [ "import tensorcircuit as tc\n", "import numpy as np\n", "import tensorflow as tf\n", "import matplotlib.pyplot as plt\n", "\n", "from tensorcircuit.templates.ansatz import QAOA_ansatz_for_Ising\n", "from tensorcircuit.templates.conversions import QUBO_to_Ising\n", "from tensorcircuit.applications.optimization import QUBO_QAOA, QAOA_loss\n", "from tensorcircuit.applications.finance.portfolio import StockData, QUBO_from_portfolio\n", "\n", "K = tc.set_backend(\"tensorflow\")\n", "tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR)" ] }, { "cell_type": "markdown", "id": "55659298", "metadata": {}, "source": [ "## Import data\n", "\n", "To optimize a portfolio, it is essential to utilize historical data from various stocks within the same time frame. Websites such as [Nasdaq](Nasdaq.com) and [Yahoo Finance](https://finance.yahoo.com/) provide access to such data. The next step involves transforming this data into an annualized return ($\\mu$) and covariance matrix ($\\sigma$), which can be recognized by the Quantum Approximate Optimization Algorithm (QAOA). To simplify this process, we can utilize the `StockData` class. This class performs the necessary calculations for annualized return and covariance, as outlined in this [paper](https://doi.org/10.1007/s11128-022-03766-5). They are:\n", "\n", "$$\n", "\\mu = \\left[\\prod ^m_{k=1}\\left(1+r_k^{(i)}\\right)\\right]^{\\frac{252}{m}}\\\\\n", "\\sigma_{ij}=\\frac{252}{m}\\sum^m_{k=1}\\left(r_k^{(i)}-\\overline{r^{(i)}}\\right)\\left(r_k^{(j)}-\\overline{r^{(j)}}\\right)\n", "$$\n", "\n", "Here is a demonstration of how to use this class:" ] }, { "cell_type": "code", "execution_count": 12, "id": "62bf0673", "metadata": {}, "outputs": [], "source": [ "import random\n", "\n", "# randomly generate historical data of 6 stocks in 1000 days\n", "data = [[random.random() for i in range(1000)] for j in range(6)]\n", "stock_data = StockData(data) # Create an instance\n", "\n", "# calculate the annualized return and covariance matrix\n", "mu = stock_data.get_return()\n", "sigma = stock_data.get_covariance()\n", "\n", "# some other information can also be obtained from this class\n", "n_stocks = stock_data.n_stocks # number of stocks\n", "n_days = stock_data.n_days # length of the time span\n", "daily_change = stock_data.daily_change # relative change of each day" ] }, { "cell_type": "markdown", "id": "0fb1d227", "metadata": {}, "source": [ "In this analysis, we have carefully chosen six prominent stocks: Apple Inc. (AAPL), Microsoft Corporation (MSFT), NVIDIA Corporation (NVDA), Pfizer Inc. (PFE), Levi Strauss & Co. (LEVI), and Cisco Systems, Inc. (CSCO). We acquired their historical data spanning from 09/07/2022 to 09/07/2023 from Yahoo Finance. Here are the return and covariance associated with this dataset" ] }, { "cell_type": "code", "execution_count": 4, "id": "a7eb3a74", "metadata": {}, "outputs": [], "source": [ "# real-world stock data, calculated using the class above\n", "# stock name: aapl, msft, nvda, pfe, levi, csco\n", "# from 09/07/2022 to 09/07/2023\n", "mu = [1.21141, 1.15325, 2.06457, 0.63539, 0.63827, 1.12224]\n", "\n", "sigma = np.array(\n", " [\n", " [0.08488, 0.06738, 0.09963, 0.02124, 0.05516, 0.04059],\n", " [0.06738, 0.10196, 0.11912, 0.02163, 0.0498, 0.04049],\n", " [0.09963, 0.11912, 0.31026, 0.01977, 0.10415, 0.06179],\n", " [0.02124, 0.02163, 0.01977, 0.05175, 0.01792, 0.02137],\n", " [0.05516, 0.0498, 0.10415, 0.01792, 0.19366, 0.0432],\n", " [0.04059, 0.04049, 0.06179, 0.02137, 0.0432, 0.05052],\n", " ]\n", ")" ] }, { "attachments": {}, "cell_type": "markdown", "id": "f6dc53d4-7ed0-436d-aa1f-8674c56e756e", "metadata": {}, "source": [ "Using this mean and covariance data, we can now define our portfolio optimization problem, convert it to a QUBO matrix, and then extract the Pauli terms and weights, which is similar to what we do in the [QUBO tutorial](https://tensorcircuit.readthedocs.io/en/latest/tutorials/qubo_problem.html)." ] }, { "cell_type": "code", "execution_count": 6, "id": "3f6edcd5-3c10-49fc-86ea-160fc6d3187e", "metadata": {}, "outputs": [], "source": [ "q = 0.5 # the risk preference of investor\n", "budget = 4 # Note that in this example, there are 6 assets, but a budget of only 4\n", "penalty = 1.2\n", "\n", "Q = QUBO_from_portfolio(sigma, mu, q, budget, penalty)\n", "portfolio_pauli_terms, portfolio_weights, portfolio_offset = QUBO_to_Ising(Q)" ] }, { "cell_type": "markdown", "id": "730da712", "metadata": {}, "source": [ "## Classical method\n", "\n", "We first use brute force to calculate the cost of each combination, which is the expectation value $x^TQx$ for each $x\\in\\{0, 1\\}^n$ ($n$ is the number of stocks). It will give us a clue about the performance of QAOA." ] }, { "cell_type": "code", "execution_count": 31, "id": "168f7c36", "metadata": {}, "outputs": [], "source": [ "def print_Q_cost(Q, wrap=False, reverse=False):\n", " n_stocks = len(Q)\n", " states = []\n", " for i in range(2**n_stocks):\n", " a = f\"{bin(i)[2:]:0>{n_stocks}}\"\n", " n_ones = 0\n", " for j in a:\n", " if j == \"1\":\n", " n_ones += 1\n", " states.append(a)\n", "\n", " cost_dict = {}\n", " for selection in states:\n", " x = np.array([int(bit) for bit in selection])\n", " cost_dict[selection] = np.dot(x, np.dot(Q, x))\n", " cost_sorted = dict(sorted(cost_dict.items(), key=lambda item: item[1]))\n", " if reverse == True:\n", " cost_sorted = dict(\n", " sorted(cost_dict.items(), key=lambda item: item[1], reverse=True)\n", " )\n", " num = 0\n", " print(\"\\n-------------------------------------\")\n", " print(\" selection\\t |\\t cost\")\n", " print(\"-------------------------------------\")\n", " for k, v in cost_sorted.items():\n", " print(\"%10s\\t |\\t%.4f\" % (k, v))\n", " num += 1\n", " if (num >= 8) & (wrap == True):\n", " break\n", " print(\" ...\\t |\\t ...\")\n", " print(\"-------------------------------------\")" ] }, { "cell_type": "code", "execution_count": 32, "id": "6a9d41c9", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "-------------------------------------\n", " selection\t |\t cost\n", "-------------------------------------\n", " 111001\t |\t-24.0487\n", " 101101\t |\t-23.7205\n", " 111100\t |\t-23.6414\n", " 011101\t |\t-23.6340\n", " 101011\t |\t-23.5123\n", " 011011\t |\t-23.4316\n", " 111010\t |\t-23.4269\n", " 111101\t |\t-23.3742\n", " ...\t |\t ...\n", "-------------------------------------\n" ] } ], "source": [ "print_Q_cost(Q, wrap=True)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "c34f3398", "metadata": {}, "source": [ "### Use QAOA\n", "\n", "Here, a standard QAOA ansatz with 12 layers is used. This circuit will be trained for 1000 iterations." ] }, { "cell_type": "code", "execution_count": 33, "id": "9249ea96", "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiIAAAGdCAYAAAAvwBgXAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAAApzUlEQVR4nO3de5RU1YHv8V+9urq7qAYUbAQRlYDEgBIQH4nxES5qTHwt7oKok8RkmfiYZMaZ+OpxvBd1EoxOxATbSS5O8IX3xsTr3CSYaHCRGFExgIgPNFEewQYamlf1s577/lFVp7uaFhrpU7tgfz9rndVVp86ps2s7Yf9m7332CUgyAgAAsCBouwAAAMBdBBEAAGANQQQAAFhDEAEAANYQRAAAgDUEEQAAYA1BBAAAWEMQAQAA1oRtF2B/Ro4cqdbWVtvFAAAAByAej2vz5s37Pa6ig8jIkSPV1NRkuxgAAOBjGDVq1H7DSEUHkWJPyKhRo+gVAQDgEBGPx9XU1NSvtruig0hRa2srQQQAgMMQk1UBAIA1BBEAAGANQQQAAFhDEAEAANYQRAAAgDUEEQAAYA1BBAAAWEMQAQAA1hBEAACANb4GkZEjR+rxxx9XS0uLOjo6tGbNGk2dOtXPSwIAgEOIb0u8DxkyRMuWLdPSpUv1hS98Qdu3b9e4ceO0a9cuvy4JAAAOMb4FkVtvvVWbNm3SN77xDW/fhg0b/LocAAA4BPk2NHPJJZdoxYoVeuqpp9Tc3KxVq1bpmmuu2ec5VVVVisfjJZsfjjtlki695UaddvnFvnw/AADoH9+CyAknnKDrr79ef/3rX3XBBRfoP/7jP/TjH/9YX/3qVz/ynIaGBiUSCW9ramrypWwjxo/V2V+ZrZPO+awv3w8AAPrHtyASDAa1atUq3X777Vq9erUWLFigBQsW6LrrrvvIc+bOnau6ujpvGzVqlC9lM7mcJCkQ8OXrAQBAP/kWRLZs2aJ33nmnZN/atWt17LHHfuQ5qVRKra2tJZsfTM5IkgIB7l4GAMAm31riZcuW6cQTTyzZN378eG3cuNGvS/abMYUekSBBBAAAm3xriefNm6czzjhDDQ0NGjt2rK644gp961vfUmNjo1+X7D9T6BEJMjYDAIBNvgWRFStW6PLLL9cVV1yht956S3fccYduvPFGPfnkk35dst9yhaEZJokAAGCXb+uISNLixYu1ePFiPy/xsRSHZoIEEQAArHJykoQ3WZU5IgAAWOVmS2y4awYAgErgZEvsrSPCZFUAAKxyMojkDJNVAQCoBE4GEXpEAACoDI4GkXyPSJA5IgAAWOVoS8xdMwAAVAInW+Li0IwYmQEAwCong0iOh94BAFARnGyJux96R5cIAAA2ORlEuh965+bPBwCgUjjZEntLvDNJBAAAq9wMIgzNAABQEdwMIjz0DgCAiuBkS5wrrqzKEu8AAFjlZBBhsioAAJXByZbYFIMIPSIAAFjlZhBhaAYAgIrgaBBhaAYAgErgZEtsvIfe0SMCAIBNbgYRhmYAAKgIjgYRHnoHAEAlcLIlZmVVAAAqg5tBhMmqAABUBCdbYtYRAQCgMjgaRJisCgBAJXAziDA0AwBARXCyJeb2XQAAKoObQYSH3gEAUBGcbImZrAoAQGVwM4gwNAMAQEVwNIgwNAMAQCVwsiVmZVUAACqDo0GEZ80AAFAJnGyJux96R48IAAA2uRlEGJoBAKAiuBlEcgzNAABQCZxsibsXNKNHBAAAmxwNIvmhGTFHBAAAq9wMIoWhmSDriAAAYJWTLXFxZVWJO2cAALDJzSBSmCMisboqAAA2OdkKlwQRekQAALDGzSDSY2iGCasAANjjaBBhaAYAgErgZCvs3b4rKchaIgAAWONoEOl+zeqqAADY42QrXDpHxF45AABwnZtBpMfQDHNEAACwx8lWuGSyKkMzAABY42Qr3HNohsmqAADY42QQ6YmhGQAA7HG2Fc4Ve0XoEAEAwBpng0hxeIY5IgAA2ONsK1x83gxDMwAA2ONuK1wIIkGeNQMAgDVlCyK33nqrjDGaN29euS65T94tvAQRAACsKUsQOfXUU3XttdfqjTfeKMfl+qU4WTXA7bsAAFjjexCJxWJatGiRvvnNb2rXrl1+X67fiqurMkcEAAB7fG+FGxsbtXjxYr3wwgv7PbaqqkrxeLxk80txaIa7ZgAAsCfs55fPnj1bU6ZM0bRp0/p1fENDg+bMmeNnkbp5d80wNAMAgC2+dQccc8wx+tGPfqSrrrpKyWSyX+fMnTtXdXV13jZq1Ci/itd9+y6TVQEAsMa3HpGpU6eqvr5eq1at6r5YOKyzzz5b3/72txWNRrtXNy1IpVJKpVJ+FalE94JmBBEAAGzxLYi88MILmjhxYsm+hQsX6t1339UPfvCDvUJIuXXfNcMcEQAAbPEtiLS1tentt98u2dfe3q4dO3bstd8mgggAAPY42wp3D81YLggAAA7z9a6Z3s4777xyXm6fuH0XAAD7nG2Fuxc0o0sEAABbnA0i3mRVekQAALDG3Va4+Mw7JqsCAGCNs62wNzTDyAwAANa4G0SKk1XpEQEAwBpnW2HDHBEAAKxzthU2PPQOAADrCCJMEgEAwBp3gwgPvQMAwDp3g4hhsioAALY52wobnr4LAIB1zrbCzBEBAMA+d4NIjiACAIBt7gYRHnoHAIB17gYRr0fE2SoAAMA6Z1th7poBAMA+Z1thHnoHAIB97gYRHnoHAIB1zrbCrKwKAIB97gYR5ogAAGCds60wQQQAAPucbYW9oRnL5QAAwGXuBhF6RAAAsM7ZVrj7oXf0iQAAYIuzQUSGlVUBALDN2VY4VwgirGgGAIA9zgaR4tBMkKEZAACscTiIMDQDAIBt7rbC3l0z9IgAAGCLs0HEe+gdt+8CAGCNs61wLsdkVQAAbHM2iPDQOwAA7HM3iBTmiAQZmgEAwBp3W2EmqwIAYJ2zQaQ4NMNj7wAAsMfdIMJD7wAAsM7ZVjjHQ+8AALDO2SCiwt27QVZWBQDAGmdb4e4FzegRAQDAFneDCAuaAQBgncNBpLigmbNVAACAdc62wjmGZgAAsM7ZIFKcrMrtuwAA2ONsK8yzZgAAsM/dIFJc0IwgAgCANe4GEW9BM2erAAAA65xthQ0PvQMAwDp3g0iuODTjbBUAAGCds62wt7Iqc0QAALDG3SCSY2gGAADbHA4irKwKAIBtzrbCRvSIAABgm7tBJMc6IgAA2OZwEGFoBgAA25xthVlHBAAA+wgirKwKAIA1vrbCt912m1577TUlEgk1NzfrmWee0fjx4/28ZL/x0DsAAOzzNYicc845amxs1BlnnKEZM2YoEono+eefV21trZ+X7Zccz5oBAMC6sJ9f/oUvfKHk/dVXX63t27dr6tSp+tOf/uTnpfer2CMSJIgAAGCNr0Gkt8GDB0uSdu7c2efnVVVVikaj3vt4PO5bWXj6LgAA9pWtFQ4EAnrggQf00ksv6e233+7zmIaGBiUSCW9ramryrTxej0iIIAIAgC1la4UbGxs1ceJEffnLX/7IY+bOnau6ujpvGzVqlG/lyWXpEQEAwLayDM3Mnz9fX/rSl3T22Wfvs5cjlUoplUqVo0jeZFXmiAAAYI/vQWT+/Pm6/PLLde6552rDhg1+X67fmCMCAIB9vgaRxsZGXXnllbr00kvV2tqq+vp6SdKePXvU1dXl56X3iyACAIB9vrbCN9xwg4YMGaI//vGP2rp1q7fNnj3bz8v2C0MzAADY52uPSCWvWspdMwAA2OdsK+zdNcPTdwEAsMbZVtiYQhChRwQAAGucbYVZRwQAAPucbYWLPSJMVgUAwB5nW2GTLQaRkOWSAADgLmeDSM5bR6Ry7+wBAOBw52wQ8RY0Y7IqAADWONsKFyerBrl9FwAAa5xthbl9FwAA+5xthXNMVgUAwDpng4jJZSUxWRUAAJscDiJGEj0iAADY5GwQ4fZdAADsczaIeLfvsrIqAADWONsKF3tEgiGGZgAAsMXZIGKyhcmqAYZmAACwxd0gUpysSo8IAADWOBtEcty+CwCAdc4GkWKPCJNVAQCwx9lWuNgjwtAMAAD2uBtECku8M1kVAAB7nA0ixjBZFQAA29wNIty+CwCAde4GEXpEAACwztkgkiv2iHDXDAAA1jjbCvPQOwAA7HM2iBQfehcMMjQDAIAt7gaRLD0iAADY5mwQyRUnq9IjAgCANc4GEe/23ZCzVQAAgHXOtsI5b46Is1UAAIB1zrbCxcmqErfwAgBgi7MtcK4kiDBhFQAAG5wNIj17RJiwCgCAHQQRSUEmrAIAYIWzLXAu22NoJuBsNQAAYJWzLXDJZFV6RAAAsMLZFrhksio9IgAAWOFsC8wcEQAA7HO6BWZRMwAA7HK6Be5+8J3T1QAAgDVOt8DG0CMCAIBNTrfAOXpEAACwyukWuNgjwu27AADY4XQLXOwRYWgGAAA7nG6Bi7fwMjQDAIAdTrfAhtt3AQCwyukWOEePCAAAVjndAjM0AwCAXU63wN7Kqtw1AwCAFU63wLlsVhIPvQMAwBanW2CTM5LoEQEAwBanW2DmiAAAYJfTLTC37wIAYJfTLbB3+24oZLkkAAC4yfcgcsMNN2j9+vXq7OzUq6++qmnTpvl9yX7rnqwasFwSAADc5GsQmTVrlu6//37deeedmjJlit544w0999xzGj58uJ+X7TdjipNV6REBAMAGX4PIP//zP2vBggV65JFHtHbtWl133XXq6OjQN77xDT8v22+m8NA7ekQAALDDtyASiUQ0depULVmyxNtnjNGSJUt05pln9nlOVVWV4vF4yeannGFBMwAAbPKtBR42bJjC4bCam5tL9jc3N2vEiBF9ntPQ0KBEIuFtTU1NfhVPUo8ekSBDMwAA2FBRXQFz585VXV2dt40aNcrX6+Vy+cmqwSBDMwAA2BD264tbWlqUyWRUX19fsr++vl5bt27t85xUKqVUKuVXkfZSXFmVHhEAAOzwrUcknU5r5cqVmj59urcvEAho+vTpeuWVV/y67AEp9ogE6BEBAMAK33pEJOn+++/Xo48+qhUrVui1117TjTfeqFgspoULF/p52X7rftYMPSIAANjgaxB56qmnNHz4cN11110aMWKEVq9erQsvvFDbtm3z87L9VpysyhLvAADY4WsQkaTGxkY1Njb6fZmPhaEZAADscrorgMmqAADY5XQQ4fZdAADscjqI0CMCAIBdjgeRQo8IS7wDAGCF0y1wznvondPVAACANU63wMYU1xFxuhoAALDG6RY4l+X2XQAAbHI6iBR7RJisCgCAHU4HkWKPCCurAgBgh9MtsMkVJqsSRAAAsMLpFrj7oXdOVwMAANY43QJ7k1W5fRcAACucboFzhaGZYJjJqgAA2OB2EGGyKgAAVjndAucyhSASDlsuCQAAbnI6iGQzGUlSKMTQDAAANjgdRLyhmQg9IgAA2EAQET0iAADY4nQQKQ7NBAkiAABY4XQQKU5WDTFZFQAAK5wOIl6PCOuIAABghdNBxJsjQo8IAABWOB5EmCMCAIBNTgeRbLpw+y5BBAAAK5wOIsUeEYZmAACww/EgUlzinR4RAABscDqIsI4IAAB2OR1EWEcEAAC7nA4i9IgAAGCX00GEdUQAALDL6SCSZbIqAABWOR1EcgzNAABgldNBJMtkVQAArHI6iHjriNAjAgCAFU4HEZ6+CwCAXU4HEdYRAQDALqeDCOuIAABgl9NBhHVEAACwiyAigggAALY4HUQyyZQkKRytslwSAADc5HQQSXV2SpIi0agCQaerAgAAK5xufZOdXd7rm55+XKddfrHF0gAA4B6ng0gmmVQul5MkjfjECbrstn+yXCIAANzidBCRpFRHp/c6WltjsSQAALjH+SCSTiZL3tcNH2apJAAAuMf5IBKpjpa8HzpyhKWSAADgHueDSHUsVvI+NmSInYIAAOAg54NIb7Ghg20XAQAAZxBEehk0dIjtIgAA4Azng8iqZ5+XJHUkEpIYmgEAoJycDyI/v+N7mjf76/rDwiclSbEjhtgtEAAADnE+iGRSKX34zrvq2JPvEamJxy2XCAAAdzgfRIq62tslSdWDYvs5EgAADBSCSEFXa5skqTo+yHJJAABwB0GkoKutEERi9IgAAFAuBJEChmYAACg/X4LImDFj9PDDD2vdunXq6OjQ+++/rzlz5igSifhxuQHR1UoQAQCg3MJ+fOmECRMUDAZ17bXX6v3339fEiRO1YMECxWIx3XzzzX5c8qB1FoZmItGoQpGIsum05RIBAHD4C0gy5bjQTTfdpOuvv15jx47t9znxeFyJREJ1dXVqbW31sXRSIBjUv7+xTJL0P8+5SG07d/l6PQAADlcH0n770iPSl8GDB2vnzp37PKaqqkrRaPfTcONlXNPD5HLqam9XdSymaCxGEAEAoAzKMll17Nix+s53vqOf/vSn+zyuoaFBiUTC25qamspRPE9XW36eSE2ceSIAAJTDAQWRuXPnyhizz+3EE08sOWfkyJH63e9+p1/84hd6+OGH9/v9dXV13jZq1KgD/0UHoRhEqgexlggAAOVwQEMzP/zhD/XII4/s85h169Z5r48++mgtXbpUL7/8sr71rW/t9/tTqZRSqdSBFGlAeWuJcOcMAABlcUBBpKWlRS0tLf06duTIkVq6dKlWrlypr3/96zKmLHNiD0r3Lbz0iAAAUA6+TFYdOXKk/vCHP2jjxo266aabNHz4cO+z5uZmPy45IFjUDACA8vIliMyYMUPjxo3TuHHj9ppwGggE/LjkgPCeN0MQAQCgLHy5a+bRRx9VIBDoc6tkTFYFAKC8eNZMD8nC0Ew0Vmu5JAAAuIEg0kNXR4ckhmYAACgXgkgPycLQTLSWHhEAAMqBINJDsj3fI8LQDAAA5UEQ6aE4NEMQAQCgPAgiPRSHZqpjzBEBAKAcCCI9dDE0AwBAWRFEekgWh2aYrAoAQFkQRHrovmumRsFQyHJpAAA4/BFEeigOzUhSVW2NxZIAAOAGgkgP2XRamXRaklTN8AwAAL4jiPTCWiIAAJQPQaSX4oPvoizzDgCA7wgivRTvnKmmRwQAAN8RRHrxhmaYIwIAgO8IIr10tRdWV2VoBgAA3xFEemGyKgAA5UMQ6aV7aIYeEQAA/EYQ6aU4NEOPCAAA/iOI9FLsEWGOCAAA/iOI9MJdMwAAlA9BpBcmqwIAUD4EkV6823djDM0AAOA3gkgv9IgAAFA+BJFektw1AwBA2RBEemFoBgCA8iGI9NK+a48kKTZ0sOWSAABw+COI9NK2c5ckKVxVpZq6uOXSAABweCOI9JJJpdSRSEiS4kceYbk0AAAc3ggifWjbke8VIYgAAOAvgkgfEttbJEnnXn2VZt5xi2545CHVjz3ecqkAADj8EET68P6fV0mSTjrns/rMrMs1duqndfbfzbZcKgAADj8EkT688otn9to3dtoUCyUBAODwRhDpQ9uOXbr502dpx4dN3r7hY0ZrcP1wi6UCAODwQxD5CLlMVvO/cq1+cMmX9bc335Ekfe4qhmcAABhIBJF9aG3ZoW3rN2rZ/3laknTe16/Sp849y3KpAAA4fBBE+mHFr57VHx/735KkS275R9UOrrNcIgAADg8EkX5a+rMnlE4mNWz0Mbrzj89q0vRzbBcJAIBDHkGkn1p37NQz3/+hMqmUgqGQZt5xC0vAAwBwkAgiB2D5//21/uX06dr6wXrFjzxC1z/8oAYdMdR2sQAAOGQRRA5QNpPRkw1z1Lpjp0Z9cry+8u//pkh11HaxAAA4JBFEPoamtX/RQ1+/QV3t7frEtCn67i8e04hxY20XCwCAQw5B5GPatn6jfvbtm7WnebuGH3esrp43l54RAAAOEEHkIHyw4nX9+8y/0+6tzRo+ZrSu/P7/VDAcsl0sAAAOGQSRg9SxJ6En/+UuZVIpnTzjPH3lvn9T3fBhtosFAMAhgSAyAD748yot/Mdb82Hkv52rO5b8P82a06Boba3togEAUNEIIgPk3Zde1f+67p+0buVqBYNBnT7zEn336cc09tRP2y4aAAAVKyDJ2C7ER4nH40okEqqrq1Nra6vt4vTbCVMn64rv/Q8dMepoSdL619fo9Wef17vLlmvHpg8tlw4AAH8dSPtNEPFJNFarL954g87475cqFA57+xMtO7Rh9Zva8PoabXjjTX34znvKptMWSwoAwMAiiFSQ+LAjNfWLF+ikc8/SmJM/pXBVVcnn6WRSm95aq83v/VUtf/tQLZualNi+Xa07dqlt507lMllLJQcA4OMhiFSocFWVjjlpgo7/9CQdN3mSjpt88n6XiG/fvUddbW1KdnQq2d6hVEdH/nVHp1KdnUp2dOT3d3Upk0wpk0ork0oq7b1O5bdkSuker4v708kUPTIAgAFFEDmEDBszWsdPnqSjjh+jI0cfo2Gjj1F82BGKDR1SMqTjt3QyqUwqrWw6rVwup1w2q1wmm/+bzSqbyXivi/uzhfemx2vvnMJ3mFxOuWxOuVz+s57vTTaXP67wWS6XK+zr8Vm2+/uM9705mR7neO8L55hcVtk+r1U4xitX6TU/8vuKv9NU7P9UAKCiHEj7Xb6WDn1q2bhJLRs37bU/EAiodshgxY88QtFYraK1NaqqKfytrVF1rFZVtd3vozU1CkUiCldVKRKtUqgqokhVVOFolcKRiMLRKkWi0ZLXPUWi0b32YW/ZTGbvgPMRwctkc8r2EXqymYyy6XThb0aZdD4AZtPd+zM936fTyqQzyvXan8mklUtnlEln8r1gXUmlU6n832RSmcLfdDL/GUEKQCUiiFQoY4zad+1W+67dvl0jFIkoEq1SuKqwRasUCoUUDIcUDIUUDIUVDAULr0MKlezPHxcqfOadEwwpFAkpEAwpGAwqGArmX4eC+ffhsAKF/cFgSIHi/uL3BIOFfaHCufv5LJy/Zu/PiucEvDIEve/o/VnvcuyzzsrYSzXQMum0F1LSPUJKpleASfcKMOmuLqU6u5Tq6lKqs1OpjsLfzi6lu7qULLzO7+tkXhOAA3Lo/quKg1b8/7aldttFqSh9hZRQKNQddHqEnu7PPiJ47RWIQgqFwwpF8ls4HFEoElEoElKo8DocCRf2Rbxjw8X3kXBhX/dx4apCD1ihVytSXfhbCJlF4UhE4UhENfFBvtZfJp1WurOrRzjpDimprqSS7R3qamtTZ1ubuhKFv23t6ky0qqvH6862dmWSSV/LCsA+ggjQSy6blbJZZQ+DObyBYFCRwlBcJBpVuLpHWKmq6g4tvf6Gi6EmGlWkJqpoTY2qaqpVVVNT2KoVqa7usa/a6y3yAk9d/KDLn0mn86Ek0aqOREIdexLq2F34m0ioY/ee/Os9CbXv3uMd09XadtDXBlAevgeRqqoqLV++XJMnT9bkyZP1xhtv+H1JAAUmlyv0SHT5fq1QJFIIJVEvnPQMLlXV+ffRWK2q4zHVxOOqHhRTzaBBqq4blP87aJBq4oMUHRRTMBhUOBJR/MgjFD/yiAMqSzaTyYeXQkjxwsqefHDp7BleeoSarjZ6B4Fy8z2I3Hvvvdq8ebMmT57s96UAWJRNp9WZTqszcfDfFQgE8oFl0CDV1A1STV2dauvqVDu4TrEh+b81g/P7YkMGq3ZwXWEb7PXODDpi6H5vj9/rN/QRYHr2tBQ/60wk1FHsqdmTUGdrK3NjgI/J1yBy4YUX6vzzz9fMmTN10UUX+XkpAIcRY4y62trV1dau3VubD+jccDSq2rp4PpgMGVyWACNJXe3t3cNIe7qDSvf7hPc+2d6hrvb87yuuBZTLEmTgJt+CyFFHHaUFCxbosssuU0dHR7/OqaqqUrTHLaTx+MGPMQNwSyaZVGJ7UontLQd03v4CTO3gwaqpi6u2ri7/d3D+b3Hyb3UspupYTEOPHvGxyp1fqLBDybZ2dbW3l4aV9g4l29vV1dahZEfhfWdXflJw4a6mdFf+dXFfuitJuMEhwbcg8sgjj+gnP/mJVq5cqTFjxvTrnIaGBs2ZM8evIgHAR/q4ASYYCql6UKwQTOpUWxcvCSp9BZdorDYfXAbFvDuborU1itbWSMOOHLjflEoVwkmyEE66vFWYs+l0fvXl4lo1hdeZVErZVH6dmuIih8VVmrPpwsKGJYsQFhc+LF2E0ORyhWN6fZ7JeGvqGJOTMUYmZ/Kvcyb/vvg6l5MxKrzPSYXXucJnMoXjcznWyTmEHdDKqnPnztVtt922z2MmTJig888/X7NmzdI555yjXC6nMWPGaMOGDfudrNpXj0hTU9NhvbIqALeFIhFVx2oVHRRTtLZW1YPyPSv5OTLd+6KDYqquzR9XHYvl73CqjnqTgCPVUe9upmAwaPtnWZMPQWa/IUfG5AORMb1CTuFzmR5hqDTweK97XUfGyMjkv6t4bPF9z+uocGwxaBXf7/U9Jv95j6DV/T0m33j3OC9/TK/v6aNMPb/HGKMNq9/UG8+9MKD/HXxb4n3YsGE68sh9p/V169bpqaee0sUXX1ySUMPhsDKZjBYtWqSrr766X9dzYYl3ABho4aoqRaqrFa2pVqRwx1L+duv8HU3FdWnCVYV1aAqvQ4Vbr/P7wqV/w/m/+UUEC2vqhHusq1NY0ND7vPfCgT0WJgwW1uUJBAIKBIIKBAMlr/e3sCAG1stPPaOn7753QL/T+rNmRo8erbq6Ou/9yJEj9fzzz2vmzJlavny5mpqa+vU9BBEAcFcgEFAgmA8sKrwOBvOBRQEVPsvvy39eDDNB5U8phJxgUAEFul8HAt3fXTyn5Pz89wV7nK/COcHCOVLp+V4ZAoXPAvLKHAgEFJC8z4vfH1CgZF/3+x7nKpD/rT3PVaC7TnpsJecGivUm77Ngj3N6nvu3t97R20v/NKD/7aw/a2bTptJnp7S15RcX+uCDD/odQgAAbjPGyDDh9rDn7kAiAACwrixLvG/cuLHQXQUAANCNHhEAAGANQQQAAFhDEAEAANYQRAAAgDUEEQAAYA1BBAAAWEMQAQAA1hBEAACANQQRAABgDUEEAABYQxABAADWlOVZMwcrHo/bLgIAAOinA2m3KzqIFH9IU1OT5ZIAAIADFY/H1draus9jApJMeYrz8YwcOXK/P+LjiMfjampq0qhRo3z5fuRRz+VBPZcH9Vw+1HV5+FnP8Xhcmzdv3u9xFd0jIqlfP+JgtLa28n/kZUA9lwf1XB7Uc/lQ1+XhRz339/uYrAoAAKwhiAAAAGucDSLJZFJz5sxRMpm0XZTDGvVcHtRzeVDP5UNdl0cl1HPFT1YFAACHL2d7RAAAgH0EEQAAYA1BBAAAWEMQAQAA1jgZRG644QatX79enZ2devXVVzVt2jTbRTqk3HbbbXrttdeUSCTU3NysZ555RuPHjy85JhqN6sEHH1RLS4taW1v1y1/+UkcddVTJMaNHj9ZvfvMbtbe3q7m5Wffee69CoVA5f8oh5dZbb5UxRvPmzfP2Uc8DY+TIkXr88cfV0tKijo4OrVmzRlOnTi055s4779TmzZvV0dGh3//+9/rEJz5R8vnQoUP1xBNPaM+ePdq1a5cefvhhxWKxcv6MihcMBnXXXXdp3bp16ujo0Pvvv69//dd/3es46vrAfO5zn9OvfvUrNTU1yRijSy+9dK9jBqJOJ02apBdffFGdnZ3629/+pptvvnnAfoNxaZs1a5bp6uoyV199tfnkJz9pfvrTn5qdO3ea4cOHWy/bobL99re/NV/72tfMSSedZE4++WTzm9/8xmzYsMHU1tZ6xzz00ENm48aN5rzzzjNTpkwxL7/8snnppZe8z4PBoFmzZo15/vnnzSmnnGIuvPBCs23bNvO9733P+u+rxO3UU08169atM6tXrzbz5s2jngdwGzJkiFm/fr352c9+ZqZNm2aOO+44M2PGDHPCCSd4x9xyyy1m165d5pJLLjGTJk0y//Vf/2U++OADE41GvWOeffZZ8/rrr5vTTjvNfPaznzV/+ctfzKJFi6z/vkraGhoazPbt281FF11kxowZY2bOnGkSiYT5zne+Q10fxHbhhReau+++21x22WXGGGMuvfTSks8Hok7j8bjZsmWLefzxx81JJ51kZs+ebdrb2803v/nNgfgN9iuxnNurr75q5s+f770PBALmww8/NLfeeqv1sh2q27Bhw4wxxnzuc58zkkxdXZ1JJpNm5syZ3jEnnniiMcaY008/3Uj5/+FkMhlz1FFHecdce+21Zvfu3SYSiVj/TZW0xWIx895775np06ebpUuXekGEeh6Ybe7cuebFF1/c5zGbN2823/3ud733dXV1prOz08yePdtIMhMmTDDGGDN16lTvmAsuuMBks1lz9NFHW/+NlbL9+te/Ng8//HDJvl/+8pfm8ccfp64HaOsriAxEnV533XVmx44dJf9uzJ0716xdu/agy+zU0EwkEtHUqVO1ZMkSb58xRkuWLNGZZ55psWSHtsGDB0uSdu7cKUmaOnWqqqqqSur5vffe08aNG716PvPMM/Xmm29q27Zt3jHPPfecBg8erE996lNlLH3la2xs1OLFi/XCCy+U7KeeB8Yll1yiFStW6KmnnlJzc7NWrVqla665xvv8+OOP19FHH11Sz4lEQsuXLy+p5127dmnlypXeMUuWLFEul9Ppp59evh9T4V5++WVNnz5d48aNkySdfPLJOuuss/Tb3/5WEnXth4Gq0zPPPFMvvvii0um0d8xzzz2nCRMmaMiQIQdVxop/6N1AGjZsmMLhsJqbm0v2Nzc3a8KECZZKdWgLBAJ64IEH9NJLL+ntt9+WJI0YMULJZFJ79uwpOba5uVkjRozwjunrv0PxM+TNnj1bU6ZM6XMeE/U8ME444QRdf/31uv/++/X9739f06ZN049//GOlUik99thjXj31VY8967ln2JOkbDarnTt3Us893HPPPaqrq9O7776rbDarUCik22+/XU8++aQkUdc+GKg6HTFihNavX7/XdxQ/271798cuo1NBBAOvsbFREydO1FlnnWW7KIedY445Rj/60Y80Y8YMlrn2UTAY1IoVK3T77bdLklavXq2JEyfquuuu02OPPWa5dIeXWbNm6aqrrtKVV16pt99+W5MnT9YDDzygzZs3U9cOc2popqWlRZlMRvX19SX76+vrtXXrVkulOnTNnz9fX/rSl3TeeeepqanJ279161ZFo1FvyKaoZz1v3bq1z/8Oxc+QH3qpr6/XqlWrlE6nlU6nde655+of/uEflE6n1dzcTD0PgC1btuidd94p2bd27Vode+yxkrrraV//bmzdunWvu5VCoZCOOOII6rmH++67T/fcc49+/vOf66233tITTzyhefPmqaGhQRJ17YeBqlM//y1xKoik02mtXLlS06dP9/YFAgFNnz5dr7zyisWSHXrmz5+vyy+/XJ///Oe1YcOGks9WrlypVCpVUs/jx4/XmDFjvHp+5ZVXNGnSJA0fPtw7ZsaMGdqzZ89ejYKrXnjhBU2cOFGTJ0/2tj//+c9atGiRJk+erBUrVlDPA2DZsmU68cQTS/aNHz9eGzdulCStX79eW7ZsKanneDyu008/vaSehw4dqilTpnjHfP7zn1cwGNTy5cvL8CsODbW1tcrlciX7stmsgsF8U0RdD7yBqtNXXnlFZ599tsLh7oGUGTNm6N133z2oYZki67N8y7nNmjXLdHZ2mq9+9atmwoQJ5ic/+YnZuXNnyV0FbPveGhsbza5du8zZZ59t6uvrva26uto75qGHHjIbNmww5557rpkyZYpZtmyZWbZsmfd58bbS3/3ud+bkk082559/vmlubua20v1sPe+aoZ4HZjv11FNNKpUyDQ0NZuzYseaKK64wbW1t5sorr/SOueWWW8zOnTvNxRdfbCZOnGieeeaZPm9/XLlypZk2bZr5zGc+Y9577z2nbynta1u4cKHZtGmTd/vuZZddZrZt22buuece6vogtlgsZk455RRzyimnGGOMufHGG80pp5xiRo8ePWB1WldXZ7Zs2WIeffRRc9JJJ5lZs2aZtrY2bt/9uNvf//3fmw0bNpiuri7z6quvmtNOO816mQ6l7aN87Wtf846JRqPmwQcfNDt27DBtbW3m6aefNvX19SXfc+yxx5rFixeb9vZ2s23bNnPfffeZUChk/fdV8tY7iFDPA7N98YtfNGvWrDGdnZ3mnXfeMddcc81ex9x5551my5YtprOz0/z+978348aNK/l86NChZtGiRSaRSJjdu3eb//zP/zSxWMz6b6ukbdCgQWbevHlmw4YNpqOjw7z//vvm7rvv3utWcur6wLZzzjmnz3+TFy5cOKB1OmnSJPPiiy+azs5Os2nTJnPLLbcMSPkDhRcAAABl59QcEQAAUFkIIgAAwBqCCAAAsIYgAgAArCGIAAAAawgiAADAGoIIAACwhiACAACsIYgAAABrCCIAAMAagggAALCGIAIAAKz5/+r+so8y6PhtAAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "iterations = 1000\n", "nlayers = 12\n", "loss_list = []\n", "\n", "\n", "# define a callback function to recode the loss\n", "def record_loss(loss, params):\n", " loss_list.append(loss)\n", "\n", "\n", "# apply QAOA on this portfolio optimization problem\n", "final_params = QUBO_QAOA(Q, nlayers, iterations, callback=record_loss)\n", "\n", "p = plt.plot(loss_list)" ] }, { "cell_type": "markdown", "id": "9126333d", "metadata": {}, "source": [ "Create a function to visualize the results, listing all combinations in descending order of probability." ] }, { "cell_type": "code", "execution_count": 34, "id": "4a2c60e4", "metadata": {}, "outputs": [], "source": [ "def print_result_prob(c, wrap=False, reverse=False):\n", " states = []\n", " n_qubits = c._nqubits\n", " for i in range(2**n_qubits):\n", " a = f\"{bin(i)[2:]:0>{n_qubits}}\"\n", " states.append(a)\n", " # Generate all possible binary states for the given number of qubits\n", "\n", " probs = K.numpy(c.probability()).round(decimals=4)\n", " # Calculate the probabilities of each state using the circuit's probability method\n", "\n", " sorted_indices = np.argsort(probs)[::-1]\n", " if reverse == True:\n", " sorted_indices = sorted_indices[::-1]\n", " state_sorted = np.array(states)[sorted_indices]\n", " prob_sorted = np.array(probs)[sorted_indices]\n", " # Sort the states and probabilities in descending order based on the probabilities\n", "\n", " print(\"\\n-------------------------------------\")\n", " print(\" selection\\t |\\tprobability\")\n", " print(\"-------------------------------------\")\n", " if wrap == False:\n", " for i in range(len(states)):\n", " print(\"%10s\\t |\\t %.4f\" % (state_sorted[i], prob_sorted[i]))\n", " # Print the sorted states and their corresponding probabilities\n", " elif wrap == True:\n", " for i in range(4):\n", " print(\"%10s\\t |\\t %.4f\" % (state_sorted[i], prob_sorted[i]))\n", " print(\" ... ...\")\n", " for i in range(-5, -1):\n", " print(\"%10s\\t |\\t %.4f\" % (state_sorted[i], prob_sorted[i]))\n", " print(\"-------------------------------------\")" ] }, { "cell_type": "code", "execution_count": 35, "id": "680f52d2", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "-------------------------------------\n", " selection\t |\tprobability\n", "-------------------------------------\n", " 111001\t |\t 0.1169\n", " 101101\t |\t 0.0872\n", " 111100\t |\t 0.0823\n", " 101011\t |\t 0.0809\n", " ... ...\n", " 000100\t |\t 0.0000\n", " 010000\t |\t 0.0000\n", " 000010\t |\t 0.0000\n", " 000001\t |\t 0.0000\n", "-------------------------------------\n" ] } ], "source": [ "c_final = QAOA_ansatz_for_Ising(\n", " final_params, nlayers, portfolio_pauli_terms, portfolio_weights\n", ")\n", "print_result_prob(c_final, wrap=True)" ] }, { "cell_type": "markdown", "id": "71c7a0e0", "metadata": {}, "source": [ "The highest probability corresponds to the best combination, which is consistent with what we found with classical brute force search.\n", "\n", "## Use XY mixer to improve the performance\n", "\n", "In the context of QAOA, XY mixers serve as a specific type of quantum gate to augment the optimization process. XY mixers, which are quantum gates introducing qubit interactions through controlled rotations, enable modification of the quantum system's state. The utilization of XY mixers in QAOA provides several advantages. They facilitate more efficient exploration of the solution space, thereby potentially improving the algorithm's overall performance. Moreover, XY mixers can amplify gradients of the objective function during optimization and enhance quantum circuit depth. Notably, in scenarios like portfolio optimization (covered in another tutorial), where constraints exist, XY mixers preserve the constraints associated with individual combinations while allowing for smooth transitions between them.\n", "\n", "It is crucial to consider that the choice of mixers relies on the specific problem under consideration, its unique characteristics, and the quantum hardware available." ] }, { "cell_type": "code", "execution_count": 38, "id": "3d558b9f", "metadata": {}, "outputs": [ { "data": { "image/png": "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VqxYoY6ODrtLGdY4zvHBcY4fjnV8cJzjYygc52E5YRcAAAxfjLwAAICEQngBAAAJhfACAAASCuEFAAAkFMJLP33lK1/RgQMH1NbWpl27dqmwsNDukhLKt771Lf3lL3+Rz+dTbW2tfvvb32rGjBk9+qSkpGj16tWqr69Xc3OzfvOb32jChAk9+kyaNEm///3v1dLSotraWn3/+9+Xy+WK51dJKA888ICMMXr00UcjyzjOsTNx4kQ9/fTTqq+vV2trq958803Nnz+/R58HH3xQR48eVWtrq/7whz9o+vTpPdZnZmZqw4YNampqktfr1bp165Senh7PrzGkOZ1OPfTQQ6qsrFRra6v279+v73znOx/px3GOzic+8Qk999xzqqqqkjFG11577Uf6xOKYzp49Wzt27FBbW5s++OADffOb34zZdzC0vttNN91k2tvbzW233WbOP/988/jjj5uGhgYzfvx422tLlLZlyxbzuc99zlxwwQVmzpw55ve//705ePCgSUtLi/T52c9+Zg4dOmSuuOIKU1BQYF577TWzc+fOyHqn02nefPNNs3XrVjN37lxz5ZVXmrq6OvMf//Eftn+/odguuugiU1lZafbs2WMeffRRjnOM29ixY82BAwfMf/7nf5rCwkJz7rnnmuLiYjN16tRIn/vvv994vV5zzTXXmNmzZ5vf/e535v333zcpKSmRPps3bzZ//etfzcUXX2wuvfRS8+6775qNGzfa/v2GSlu+fLk5duyY+dSnPmUmT55srr/+euPz+cxXv/pVjvMg2pVXXmm++93vmuuuu84YY8y1117bY30sjqnH4zHV1dXm6aefNhdccIG5+eabTUtLi/niF78Yi+9g/0Ec6m3Xrl3msccei7x3OBzmyJEj5oEHHrC9tkRt48aNM8YY84lPfMJIMhkZGaajo8Ncf/31kT4zZ840xhizYMECI3X+xxYMBs2ECRMifb70pS+ZxsZG43a7bf9OQ6mlp6ebd955xyxZssS8/PLLkfDCcY5dW7lypdmxY0effY4ePWr+5V/+JfI+IyPDtLW1mZtvvtlIMvn5+cYYY+bPnx/ps3TpUhMKhUxubq7t33EotOeff96sW7eux7Lf/OY35umnn+Y4x6j1Fl5icUzvuusuc/z48R7/bqxcudLs27dv0DVz2ugM3G635s+fr23btkWWGWO0bds2FRUV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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "loss_list = []\n", "final_params = QUBO_QAOA(Q, nlayers, iterations, mixer=\"XY\", callback=record_loss)\n", "\n", "p = plt.plot(loss_list)" ] }, { "cell_type": "code", "execution_count": 39, "id": "d83fc94c", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "-------------------------------------\n", " selection\t |\tprobability\n", "-------------------------------------\n", " 111001\t |\t 0.1553\n", " 001001\t |\t 0.1260\n", " 101001\t |\t 0.1180\n", " 111000\t |\t 0.0934\n", " ... ...\n", " 100110\t |\t 0.0000\n", " 000111\t |\t 0.0000\n", " 000101\t |\t 0.0000\n", " 000100\t |\t 0.0000\n", "-------------------------------------\n" ] } ], "source": [ "c_final = QAOA_ansatz_for_Ising(\n", " final_params, nlayers, portfolio_pauli_terms, portfolio_weights, mixer=\"XY\"\n", ")\n", "print_result_prob(c_final, wrap=True)" ] }, { "cell_type": "markdown", "id": "917c9415", "metadata": {}, "source": [ "Compared with the standard X mixer, the XY mixer gives a higher probability of measuring the best result." ] } ], "metadata": { "kernelspec": { "display_name": "tc_dev", "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.11.4" } }, "nbformat": 4, "nbformat_minor": 5 }