TSP_EN.ipynb 78.4 KB
Newer Older
Q
Quleaf 已提交
1 2 3 4 5 6 7 8
{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "# Travelling Salesman Problem\n",
    "\n",
    "<em> Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved. </em>"
Q
Quleaf 已提交
9 10
   ],
   "metadata": {}
Q
Quleaf 已提交
11 12 13 14 15 16 17 18
  },
  {
   "cell_type": "markdown",
   "source": [
    "## Overview\n",
    "\n",
    "One of the most famous NP-hard problems in combinatorial optimization, the travelling salesman problem (TSP) considers the following question: \"Given a list of cities and the distances between each pair of cities, what is the shortest possible route that visits each city exactly once and returns to the origin city?\" \n",
    "\n",
Q
Quleaf 已提交
19
    "This question can also be formulated in the language of graph theory. Given a weighted undirected complete graph $G = (V,E)$, where each vertex $i \\in V$ corresponds to city $i$ and the weight $w_{i,j}$ of each edge $(i,j,w_{i,j}) \\in E$ represents the distance between cities $i$ and $j$, the TSP is to find the shortest Hamiltonian cycle in $G$, where a Hamiltonian cycle is a closed loop on a graph in which every vertex is visited exactly once. Note that because $G$ is an undirected graph, weights are symmetric, i.e., $w_{i,j} = w_{j,i}$. "
Q
Quleaf 已提交
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "## Use QNN to solve TSP\n",
    "\n",
    "To use QNN to solve travelling salesman problem, we need to first encode the classical problem to quantum. \n",
    "The encoding consists of two parts:\n",
    "\n",
    "1. The route how the salesman visits each city is encoded in quantum states -- ${\\rm qubit}_{i,t} = |1\\rangle$ corresponds to salesman visiting city $i$ at time $t$. \n",
    "    1. As an example, if there are two cities $\\{A,B\\}$, visiting $A$ then $B$ will be in state $|1001\\rangle$, as the salesman visits the city $A$ at time $1$ and the city $B$ at time $2$.\n",
    "    2. Similary, $|0110\\rangle$ means visiting $B$ then $A$.\n",
    "    3. Note: $|0101\\rangle$ means visiting $A$ and $B$ both at time $2$, so it is infeasible. To aviod such states, a penalty function will be used (see the next section for details.)\n",
    "\n",
    "2. The total distance is encoded in a loss function: \n",
    "\n",
    "$$\n",
    "L(\\psi(\\vec{\\theta})) = \\langle\\psi(\\vec{\\theta})|H_C|\\psi(\\vec{\\theta})\\rangle,\n",
    "\\tag{1}\n",
    "$$\n",
    "\n",
    "where $|\\psi(\\vec{\\theta})\\rangle$ is the output state from a parameterized quantum circuit. \n",
    "\n",
    "The details about how to encode the classical problem to quantum is given in detail in the next section. \n",
    "After optimizing the loss function, we will obtain the optimal quantum state. Then a decoding process will be performed to get the final route."
   ],
   "metadata": {}
Q
Quleaf 已提交
49 50 51 52
  },
  {
   "cell_type": "markdown",
   "source": [
Q
Quleaf 已提交
53
    "### Encoding the TSP\n",
Q
Quleaf 已提交
54
    "\n",
Q
Quleaf 已提交
55 56 57
    "To transform the TSP into a problem applicable for parameterized quantum circuits, we need to encode the TSP into a Hamiltonian. \n",
    "\n",
    "We realize the encoding by first constructing an integer programming problem. Suppose there are $n=|V|$ vertices in graph $G$. Then for each vertex $i \\in V$, we define $n$ binary variables $x_{i,t}$, where $t \\in [0,n-1]$, such that\n",
Q
Quleaf 已提交
58 59 60 61 62 63 64
    "\n",
    "$$\n",
    "x_{i, t}=\n",
    "\\begin{cases}\n",
    "1, & \\text {if in the resulting Hamiltonian cycle, vertex } i \\text { is visited at time } t\\\\\n",
    "0, & \\text{otherwise}\n",
    "\\end{cases}.\n",
Q
Quleaf 已提交
65
    "\\tag{2}\n",
Q
Quleaf 已提交
66 67 68 69 70 71
    "$$\n",
    "\n",
    "As there are $n$ vertices, we have $n^2$ variables in total, whose value we denote by a bit string $x=x_{1,1}x_{1,2}\\dots x_{n,n}$. Assume for now that the bit string $x$ represents a Hamiltonian cycle. Then for each edge $(i,j,w_{i,j}) \\in E$, we will have $x_{i,t} = x_{j,t+1}=1$, i.e., $x_{i,t}\\cdot x_{j,t+1}=1$, if and only if the Hamiltonian cycle visits vertex $i$ at time $t$ and vertex $j$ at time $t+1$; otherwise, $x_{i,t}\\cdot x_{j,t+1}$ will be $0$. Therefore the length of a Hamiltonian cycle is\n",
    "\n",
    "$$\n",
    "D(x) = \\sum_{i,j} w_{i,j} \\sum_{t} x_{i,t} x_{j,t+1}.\n",
Q
Quleaf 已提交
72
    "\\tag{3}\n",
Q
Quleaf 已提交
73 74 75 76 77 78
    "$$\n",
    "\n",
    "For $x$ to represent a valid Hamiltonian cycle, the following constraint needs to be met:\n",
    "\n",
    "$$\n",
    "\\sum_t x_{i,t} = 1 \\quad  \\forall i \\in [0,n-1] \\quad \\text{ and } \\quad \\sum_i x_{i,t} = 1 \\quad  \\forall t \\in [0,n-1],\n",
Q
Quleaf 已提交
79
    "\\tag{4}\n",
Q
Quleaf 已提交
80 81 82 83 84 85
    "$$\n",
    "\n",
    "where the first equation guarantees that each vertex is only visited once and the second guarantees that only one vertex is visited at each time $t$. Then the cost function under the constraint can be formulated below, with $A$ being the penalty parameter set to ensure that the constraint is satisfied:\n",
    "\n",
    "$$\n",
    "C(x) = D(x)+ A\\left( \\sum_{i} \\left(1-\\sum_t  x_{i,t}\\right)^2 +  \\sum_{t} \\left(1-\\sum_i  x_{i,t}\\right)^2  \\right).\n",
Q
Quleaf 已提交
86
    "\\tag{5}\n",
Q
Quleaf 已提交
87 88 89 90 91 92 93 94 95
    "$$\n",
    "\n",
    "Note that as we would like to minimize the length $D(x)$ while ensuring $x$ represents a valid Hamiltonian cycle, we had better set $A$ large, at least larger than the largest weight of edges.\n",
    "\n",
    "We now need to transform the cost function $C(x)$ into a Hamiltonian to realize the encoding of the TSP. Each variable $x_{i,j}$ has two possible values, $0$ and $1$, corresponding to quantum states $|0\\rangle$ and $|1\\rangle$. **Note that every variable corresponds to a qubit and so $n^2$ qubits are needed for solving the TSP.** Similar as in the Max-Cut problem, we consider the Pauli $Z$ operator as it has two eigenstates, $|0\\rangle$ and $|1\\rangle$. Their corresponding eigenvalues are 1 and -1, respectively.\n",
    "\n",
    "Now we would like to consider the mapping\n",
    "\n",
    "$$\n",
Q
Quleaf 已提交
96
    "x_{i,t} \\mapsto \\frac{I-Z_{i,t}}{2}, \\tag{6}\n",
Q
Quleaf 已提交
97 98
    "$$\n",
    "\n",
Q
Quleaf 已提交
99
    "where $Z_{i,t} = I \\otimes I \\otimes \\ldots \\otimes Z \\otimes \\ldots \\otimes I$ with $Z$ operates on the qubit at position $(i,t)$. Under this mapping, if a qubit $(i,t)$ is in state $|1\\rangle$, then $x_{i,t}|1\\rangle = \\frac{I-Z_{i,t}}{2} |1\\rangle = 1 |1\\rangle$, which means vertex $i$ is visited at time $t$. Also, for a qubit $(i,t)$ in state $|0\\rangle$, $x_{i,t} |0\\rangle= \\frac{I-Z_{i,t}}{2} |0\\rangle = 0|0\\rangle$.\n",
Q
Quleaf 已提交
100 101 102
    "\n",
    "Thus using the above mapping, we can transform the cost function $C(x)$ into a Hamiltonian $H_C$ for the system of $n^2$ qubits and realize the quantumization of the TSP. Then the ground state of $H_C$ is the optimal solution to the TSP. In the following section, we will show how to use a parametrized quantum circuit to find the ground state, i.e., the eigenvector with the smallest eigenvalue.\n",
    "\n"
Q
Quleaf 已提交
103 104
   ],
   "metadata": {}
Q
Quleaf 已提交
105 106 107 108 109 110 111
  },
  {
   "cell_type": "markdown",
   "source": [
    "## Paddle Quantum Implementation\n",
    "\n",
    "To investigate the TSP using Paddle Quantum, there are some required packages to import, which are shown below. The ``networkx`` package is the tool to handle graphs."
Q
Quleaf 已提交
112 113
   ],
   "metadata": {}
Q
Quleaf 已提交
114 115 116 117 118 119 120 121
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "source": [
    "# Import related modules from Paddle Quantum and PaddlePaddle\n",
    "import paddle\n",
    "from paddle_quantum.circuit import UAnsatz\n",
Q
Quleaf 已提交
122 123 124 125 126 127 128
    "\n",
    "# Functions for Salesman Problem\n",
    "from paddle_quantum.QAOA.tsp import tsp_hamiltonian  # Get the Hamiltonian for salesman problem\n",
    "from paddle_quantum.QAOA.tsp import solve_tsp_brute_force  # Solve the salesman problem by brute force\n",
    "\n",
    "# Create Graph\n",
    "import networkx as nx\n",
Q
Quleaf 已提交
129 130 131 132
    "\n",
    "# Import additional packages needed\n",
    "from numpy import pi as PI\n",
    "import matplotlib.pyplot as plt\n",
Q
Quleaf 已提交
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
    "import random\n",
    "import time"
   ],
   "outputs": [],
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-05-17T08:24:17.197426Z",
     "start_time": "2021-05-17T08:24:12.896488Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "### Generate a weighted complete graph"
   ],
   "metadata": {}
Q
Quleaf 已提交
150 151 152 153 154
  },
  {
   "cell_type": "markdown",
   "source": [
    "Next, we generate a weighted complete graph $G$ with four vertices. For the convenience of computation, the vertices here are labeled starting from $0$."
Q
Quleaf 已提交
155 156
   ],
   "metadata": {}
Q
Quleaf 已提交
157 158 159 160 161 162 163
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "source": [
    "# n is the number of vertices in the graph G\n",
    "n = 4\n",
Q
Quleaf 已提交
164
    "E = [(0, 1, 3), (0, 2, 2), (0, 3, 10), (1, 2, 6), (1, 3, 2), (2, 3, 6)]  # Parameters for edges: (vertex1, vertex2, weight(distance))\n",
Q
Quleaf 已提交
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
    "G = nx.Graph()\n",
    "G.add_weighted_edges_from(E)\n",
    "\n",
    "# Print out the generated graph G\n",
    "pos = nx.spring_layout(G)\n",
    "options = {\n",
    "    \"with_labels\": True,\n",
    "    \"font_weight\": \"bold\",\n",
    "    \"font_color\": \"white\",\n",
    "    \"node_size\": 2000,\n",
    "    \"width\": 2\n",
    "}\n",
    "nx.draw_networkx(G, pos, **options)\n",
    "nx.draw_networkx_edge_labels(G, pos=pos, edge_labels=nx.get_edge_attributes(G,'weight'))\n",
    "ax = plt.gca()\n",
    "ax.margins(0.20)\n",
    "plt.axis(\"off\")\n",
    "plt.show()"
Q
Quleaf 已提交
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
   ],
   "outputs": [
    {
     "output_type": "display_data",
     "data": {
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ],
      "image/png": "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"
     },
     "metadata": {}
    }
   ],
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-05-17T08:24:24.302458Z",
     "start_time": "2021-05-17T08:24:24.060967Z"
    }
   }
Q
Quleaf 已提交
202 203 204 205 206 207
  },
  {
   "cell_type": "markdown",
   "source": [
    "### Encoding Hamiltonian\n",
    "\n",
Q
Quleaf 已提交
208
    "In Paddle Quantum, a Hamiltonian can be input in the form of ``list``. Here we construct the Hamiltonian $H_C$ of Eq. (4) with the replacement in Eq. (5). It can be realized with a build-in function \"tsp_hamiltonian(G, A, n)\".\n",
Q
Quleaf 已提交
209
    "\n",
Q
Quleaf 已提交
210 211 212
    "**Note:** For the salesman problem, the number of qubits can be reduced to $(n-1)^2$ since we can always select city $0$ to be the first city."
   ],
   "metadata": {}
Q
Quleaf 已提交
213 214 215 216
  },
  {
   "cell_type": "code",
   "execution_count": 3,
Q
Quleaf 已提交
217 218 219 220 221 222
   "source": [
    "# Construct the Hamiltonian H_C in the form of list -- with build-in function tsp_hamiltonian(G, A, n)\n",
    "A = 20 # Penalty parameter\n",
    "H_C_list = tsp_hamiltonian(G, A, n)"
   ],
   "outputs": [],
Q
Quleaf 已提交
223 224 225 226 227
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-05-17T08:24:25.956145Z",
     "start_time": "2021-05-17T08:24:25.950463Z"
    }
Q
Quleaf 已提交
228
   }
Q
Quleaf 已提交
229 230 231 232 233 234 235 236
  },
  {
   "cell_type": "markdown",
   "source": [
    "### Calculating the loss function \n",
    "\n",
    "In the [Max-Cut tutorial](./MAXCUT_EN.ipynb), we use a circuit given by QAOA to find the ground state, but we can also use other circuits to solve combinatorial optimization problems. For the TSP, we adopt a parametrized quantum circuit constructed by $U_3(\\vec{\\theta})$ and $\\text{CNOT}$ gates, which we call the [`complex entangled layer`](https://qml.baidu.com/api/paddle_quantum.circuit.uansatz.html).\n",
    "\n",
Q
Quleaf 已提交
237 238 239 240
    "<img src=\"./figures/tsp-fig-circuit.png\" width=\"900px\" /> \n",
    "<center> Figure 1: Parametrized Quantum Circuit used for TSM Problem </center>\n",
    "\n",
    "After running the quantum circuit, we obtain the output state $|\\psi(\\vec{\\theta})\\rangle$. From the output state of the circuit we can calculate the objective function, and also the loss function of the TSP:\n",
Q
Quleaf 已提交
241 242
    "\n",
    "$$\n",
Q
Quleaf 已提交
243 244
    "L(\\psi(\\vec{\\theta})) = \\langle\\psi(\\vec{\\theta})|H_C|\\psi(\\vec{\\theta})\\rangle.\n",
    "\\tag{7}\n",
Q
Quleaf 已提交
245 246 247
    "$$\n",
    "\n",
    "We then use a classical optimization algorithm to minimize this function and find the optimal parameters $\\vec{\\theta}^*$. The following code shows a complete network built with Paddle Quantum and PaddlePaddle."
Q
Quleaf 已提交
248 249
   ],
   "metadata": {}
Q
Quleaf 已提交
250 251 252 253
  },
  {
   "cell_type": "code",
   "execution_count": 4,
Q
Quleaf 已提交
254 255 256 257 258 259 260
   "source": [
    "# In this tutorial we use build-in PQC: complex_entangled_layer()\n",
    "def cir_TSP(N, DEPTH, theta):\n",
    "    cir = UAnsatz(N)\n",
    "    cir.complex_entangled_layer(theta, DEPTH)\n",
    "    return cir"
   ],
Q
Quleaf 已提交
261
   "outputs": [],
Q
Quleaf 已提交
262 263 264 265 266
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 5,
Q
Quleaf 已提交
267
   "source": [
Q
Quleaf 已提交
268 269 270 271 272 273
    "class Opt_TSP(paddle.nn.Layer):\n",
    "    def __init__(self, G, DEPTH, H_ls, dtype=\"float64\",):\n",
    "        # Input: Graph, G; PQC Layer number, DEPTH; Hamiltonian in Pauli list form, H_ls\n",
    "        super(Opt_TSP, self).__init__()\n",
    "        self.DEPTH = DEPTH\n",
    "        self.theta = self.create_parameter(shape=[self.DEPTH, (len(G.nodes) - 1) ** 2, 3],\n",
Q
Quleaf 已提交
274 275 276
    "                                        default_initializer=paddle.nn.initializer.Uniform(low=0.0, high=2 * PI),\n",
    "                                        dtype=dtype, is_bias=False)\n",
    "        self.H_ls = H_ls\n",
Q
Quleaf 已提交
277
    "        self.num_qubits = (len(G) - 1) ** 2  # Total qubits number: (city number-1)**2\n",
Q
Quleaf 已提交
278 279 280
    "\n",
    "    def forward(self):\n",
    "        # Define a circuit with complex entangled layers\n",
Q
Quleaf 已提交
281
    "        cir = cir_TSP(self.num_qubits, self.DEPTH, self.theta)\n",
Q
Quleaf 已提交
282 283 284 285 286 287
    "        # Run the quantum circuit\n",
    "        cir.run_state_vector()\n",
    "        # Calculate the loss function\n",
    "        loss = cir.expecval(self.H_ls)\n",
    "\n",
    "        return loss, cir"
Q
Quleaf 已提交
288 289 290 291 292 293 294 295
   ],
   "outputs": [],
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-05-17T08:24:26.790290Z",
     "start_time": "2021-05-17T08:24:26.768068Z"
    }
   }
Q
Quleaf 已提交
296 297 298 299 300 301
  },
  {
   "cell_type": "markdown",
   "source": [
    "### Training the quantum neural network\n",
    "\n",
Q
Quleaf 已提交
302 303 304
    "After defining the quantum neural network, we use gradient descent method to update the parameters to minimize the expectation value in Eq. (7). "
   ],
   "metadata": {}
Q
Quleaf 已提交
305 306 307
  },
  {
   "cell_type": "code",
Q
Quleaf 已提交
308 309 310 311 312 313 314 315
   "execution_count": 6,
   "source": [
    "DEPTH = 2   # Number of layers in the quantum circuit\n",
    "ITR = 120   # Number of training iterations\n",
    "LR = 0.5    # Learning rate of the optimization method based on gradient descent\n",
    "SEED = 1000 # Set a global RNG seed "
   ],
   "outputs": [],
Q
Quleaf 已提交
316 317 318 319 320
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-05-17T08:24:27.958085Z",
     "start_time": "2021-05-17T08:24:27.952965Z"
    }
Q
Quleaf 已提交
321
   }
Q
Quleaf 已提交
322 323 324 325 326
  },
  {
   "cell_type": "markdown",
   "source": [
    "Here, we optimize the network defined above in PaddlePaddle."
Q
Quleaf 已提交
327 328
   ],
   "metadata": {}
Q
Quleaf 已提交
329 330 331
  },
  {
   "cell_type": "code",
Q
Quleaf 已提交
332
   "execution_count": 7,
Q
Quleaf 已提交
333 334 335
   "source": [
    "# Fix paddle random seed\n",
    "paddle.seed(SEED)\n",
Q
Quleaf 已提交
336 337
    "# Record run time\n",
    "time_start = time.time()\n",
Q
Quleaf 已提交
338
    "\n",
Q
Quleaf 已提交
339
    "myLayer = Opt_TSP(G, DEPTH, H_C_list)\n",
Q
Quleaf 已提交
340
    "# Use Adam optimizer\n",
Q
Quleaf 已提交
341
    "opt = paddle.optimizer.Adam(learning_rate=LR, parameters=myLayer.parameters())\n",
Q
Quleaf 已提交
342 343 344
    "# Gradient descent iteration\n",
    "for itr in range(1, ITR + 1):\n",
    "    # Run the network defined above\n",
Q
Quleaf 已提交
345
    "    loss, cir = myLayer()\n",
Q
Quleaf 已提交
346 347 348 349 350
    "    # Calculate the gradient and optimize\n",
    "    loss.backward()\n",
    "    opt.minimize(loss)\n",
    "    opt.clear_grad()\n",
    "    if itr % 10 == 0:\n",
Q
Quleaf 已提交
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
    "        print(\"iter:\", itr, \" loss:\", \"%.4f\"% loss.numpy(), \"run time:\", time.time()-time_start)\n",
    "        \n",
    "# The final minimum distance from QNN\n",
    "print('The final minimum distance from QNN:', loss.numpy())"
   ],
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "iter: 10  loss: 46.0232 run time: 7.641107082366943\n",
      "iter: 20  loss: 22.6648 run time: 15.020977258682251\n",
      "iter: 30  loss: 16.6194 run time: 22.464542627334595\n",
      "iter: 40  loss: 14.3719 run time: 30.163496732711792\n",
      "iter: 50  loss: 13.5547 run time: 38.4432737827301\n",
      "iter: 60  loss: 13.1736 run time: 46.77324390411377\n",
      "iter: 70  loss: 13.0661 run time: 55.22942876815796\n",
      "iter: 80  loss: 13.0219 run time: 63.490843057632446\n",
      "iter: 90  loss: 13.0035 run time: 72.72753691673279\n",
      "iter: 100  loss: 13.0032 run time: 82.62676620483398\n",
      "iter: 110  loss: 13.0008 run time: 91.19076180458069\n",
      "iter: 120  loss: 13.0004 run time: 99.36567878723145\n",
      "The final minimum distance from QNN: [13.00038342]\n"
     ]
    }
   ],
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-05-17T08:26:08.098742Z",
     "start_time": "2021-05-17T08:24:28.741155Z"
    }
   }
Q
Quleaf 已提交
383 384 385 386 387
  },
  {
   "cell_type": "markdown",
   "source": [
    "Note that ideally the training network will find the shortest Hamiltonian cycle, and the final loss above would correspond to the total weights of the optimal cycle, i.e. the distance of the optimal path for the salesman. If not, then one should adjust parameters of the parameterized quantum circuits above for better training performance."
Q
Quleaf 已提交
388 389
   ],
   "metadata": {}
Q
Quleaf 已提交
390 391 392 393 394 395
  },
  {
   "cell_type": "markdown",
   "source": [
    "### Decoding the quantum solution\n",
    "\n",
Q
Quleaf 已提交
396
    "After obtaining the minimum value of the loss function and the corresponding set of parameters $\\vec{\\theta}^*$, our task has not been completed. In order to obtain an approximate solution to the TSP, it is necessary to decode the solution to the classical optimization problem from the quantum state $|\\psi(\\vec{\\theta})^*\\rangle$ output by the circuit. Physically, to decode a quantum state, we need to measure it and then calculate the probability distribution of the measurement results, where a measurement result is a bit string that represents an answer for the TSP: \n",
Q
Quleaf 已提交
397 398
    "\n",
    "$$\n",
Q
Quleaf 已提交
399 400
    "p(z) = |\\langle z|\\psi(\\vec{\\theta})^*\\rangle|^2.\n",
    "\\tag{8}\n",
Q
Quleaf 已提交
401 402 403 404 405
    "$$\n",
    "\n",
    "Usually, the greater the probability of a certain bit string, the greater the probability that it corresponds to an optimal solution of the TSP.\n",
    "\n",
    "Paddle Quantum provides a function to read the probability distribution of the measurement results of the state output by the quantum circuit:"
Q
Quleaf 已提交
406 407
   ],
   "metadata": {}
Q
Quleaf 已提交
408 409 410
  },
  {
   "cell_type": "code",
Q
Quleaf 已提交
411 412 413 414 415 416 417
   "execution_count": 8,
   "source": [
    "# Repeat the simulated measurement of the circuit output state 1024 times\n",
    "prob_measure = cir.measure(shots=1024)\n",
    "reduced_salesman_walk = max(prob_measure, key=prob_measure.get)\n",
    "print(\"The reduced bit string form of the walk found:\", reduced_salesman_walk)"
   ],
Q
Quleaf 已提交
418 419 420
   "outputs": [
    {
     "output_type": "stream",
Q
Quleaf 已提交
421
     "name": "stdout",
Q
Quleaf 已提交
422 423 424 425 426
     "text": [
      "The reduced bit string form of the walk found: 010001100\n"
     ]
    }
   ],
Q
Quleaf 已提交
427 428 429 430 431 432
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-05-17T08:26:08.152206Z",
     "start_time": "2021-05-17T08:26:08.103516Z"
    }
   }
Q
Quleaf 已提交
433 434 435 436 437 438 439 440 441 442 443
  },
  {
   "cell_type": "markdown",
   "source": [
    "As we have slightly modified the TSP Hamiltonian to reduce the number of qubits used, the bit string found above has lost the information for our fixed vertex $n-1$ and the status of other vertices at time $n-1$. So we need to extend the found bit string to include these information.\n",
    "\n",
    "We need to add a $0$ after every $(n-1)$ bits to represent $x_{i,n-1} = 0$ for $i \\in [0, n-2]$. Then at last, we need to add the bit string representation for vertex $n-1$, i.e. '00...01' with $n-1$ 0s to represent $x_{n-1,t} = 0$ for all $t \\in [0,n-2]$. \n",
    "\n",
    "After measurement, we have found the bit string with the highest probability of occurrence, the optimal walk in the form of the bit string. Each qubit contains the information of $x_{i,t}$ defined in Eq. (1). The following code maps the bit string back to the classic solution in the form of `dictionary`, where the `key` represents the vertex labeling and the `value` represents its order, i.e. when it is visited. \n",
    "\n",
    "Also, we have compared it with the solution found by the brute-force algorithm, to verify the correctness of the quantum algorithm."
Q
Quleaf 已提交
444 445
   ],
   "metadata": {}
Q
Quleaf 已提交
446 447 448
  },
  {
   "cell_type": "code",
Q
Quleaf 已提交
449
   "execution_count": 9,
Q
Quleaf 已提交
450 451 452 453 454 455 456 457 458 459 460 461 462 463
   "source": [
    "# Optimal walk found by parameterized quantum circuit\n",
    "str_by_vertex = [reduced_salesman_walk[i:i + n - 1] for i in range(0, len(reduced_salesman_walk) + 1, n - 1)]\n",
    "salesman_walk = '0'.join(str_by_vertex) + '0' * (n - 1) + '1'\n",
    "solution = {i:t for i in range(n) for t in range(n) if salesman_walk[i * n + t] == '1'}\n",
    "distance = sum([G[u][v][\"weight\"] if solution[u] == (solution[v] + 1) % n \n",
    "                or solution[v] == (solution[u] + 1) % n else 0\n",
    "                for (u, v) in G.edges])\n",
    "print(\"The walk found by parameterized quantum circuit:\", solution, \"with distance\", distance)\n",
    "\n",
    "# Optimal walk found by brute-force algorithm for comparison\n",
    "salesman_walk_brute_force, distance_brute_force = solve_tsp_brute_force(G)\n",
    "solution_brute_force = {i:salesman_walk_brute_force.index(i) for i in range(n)}\n",
    "print(\"The walk found by the brute-force algorithm:\", solution_brute_force, \"with distance\", distance_brute_force)"
Q
Quleaf 已提交
464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480
   ],
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "The walk found by parameterized quantum circuit: {0: 1, 1: 2, 2: 0, 3: 3} with distance 13\n",
      "The walk found by the brute-force algorithm: {0: 0, 1: 1, 2: 3, 3: 2} with distance 13\n"
     ]
    }
   ],
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-05-17T08:26:08.169372Z",
     "start_time": "2021-05-17T08:26:08.156656Z"
    }
   }
Q
Quleaf 已提交
481 482 483 484 485 486 487 488
  },
  {
   "cell_type": "markdown",
   "source": [
    "Here, we draw the corresponding optimal walk in the form of graph representation suggested to the salesman:\n",
    "* The first number in the vertex represents the city number.\n",
    "* The second number in the vertex represents the order the salesman visits the corresponding city.\n",
    "* The red edges represent the found optimal route for the salesman."
Q
Quleaf 已提交
489 490
   ],
   "metadata": {}
Q
Quleaf 已提交
491 492 493
  },
  {
   "cell_type": "code",
Q
Quleaf 已提交
494
   "execution_count": 10,
Q
Quleaf 已提交
495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515
   "source": [
    "label_dict = {i: str(i) + \", \" + str(t) for i, t in solution.items()}\n",
    "edge_color = [\"red\" if solution[u] == (solution[v] + 1) % n\n",
    "              or solution[v] == (solution[u] + 1) % n else \"black\"\n",
    "              for (u, v) in G.edges]\n",
    "label_dict_bf = {i: str(i) + \", \" + str(t) for i, t in solution_brute_force.items()}\n",
    "edge_color_bf = [\"red\" if solution_brute_force[u] == (solution_brute_force[v] + 1) % n\n",
    "                 or solution_brute_force[v] == (solution_brute_force[u] + 1) % n else \"black\"\n",
    "                 for (u, v) in G.edges]\n",
    "\n",
    "# Draw the walk corresponding to the dictionary presented above on the graph\n",
    "fig, ax = plt.subplots(1, 2, figsize=(15, 4))\n",
    "for i, a in enumerate(ax):\n",
    "    a.axis('off')\n",
    "    a.margins(0.20)\n",
    "nx.draw(G, pos=pos, labels=label_dict, edge_color=edge_color, ax=ax[0], **options)\n",
    "nx.drawing.nx_pylab.draw_networkx_edge_labels(G, pos=pos, ax=ax[0], edge_labels=nx.get_edge_attributes(G, 'weight'))\n",
    "nx.draw(G, pos=pos, labels=label_dict_bf, edge_color=edge_color_bf, ax=ax[1], **options)\n",
    "nx.drawing.nx_pylab.draw_networkx_edge_labels(G, pos=pos, ax=ax[1], edge_labels=nx.get_edge_attributes(G, 'weight'))\n",
    "plt.axis(\"off\")\n",
    "plt.show()"
Q
Quleaf 已提交
516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534
   ],
   "outputs": [
    {
     "output_type": "display_data",
     "data": {
      "text/plain": [
       "<Figure size 1080x288 with 2 Axes>"
      ],
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA1MAAADnCAYAAAD7CwxiAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Z1A+gAAAACXBIWXMAAAsTAAALEwEAmpwYAABgVklEQVR4nO3dd3iTZfcH8O+T0TTdtKUMKZTWMsoUqCBLxQniZiivOPiJuFBRHKgoiAgqoqiooOLA8QooDl5xgSIupuwWChQos4XSlu6meX5/HEoLdCRpmudJ8v1clxe00uRmNCfnvs99jqKqqgoiIiIiIiJyikHrBRAREREREXkjJlNEREREREQuYDJFRERERETkAiZTRERERERELmAyRURERERE5AImU0RERERERC5gMkVEREREROQCJlNEREREREQuYDJFRERERETkAiZTRERERERELmAyRURERERE5AImU0RERERERC5gMkVEREREROQCk9YLICJqaHa7ir3ZhUg/mo/iMjvKyu0wGw0INBvQOjoErSKDYDAoWi+TiIjIoxgf64/JFBH5HLtdxZ+7jmJ5aibW7MlGWmY+DIoCk0GBChWqCigKoECBza7CrqpIjAlBclwkBrSLQZ+EaAYPIiLyOYyP7qeoqqpqvQgiInfILSrDgrUZeHflbhSU2FBYWg5nXuAUAEEBRgRbTBjdLx7DesQi3GpuqOUSERF5BONjw2EyRURer6i0HNOWpuCLtRlQFKC4zF7vx7SaDbCrwPAesZgwsD2sAUY3rJSIiMhzGB8bHpMpIvJqq9Ozcf/n65FXVIZiW/2DxJkCTQaEWc2YPaIbkuMi3f74REREDYHx0TOYTBGRVyqxlWPKkm1YtH6/W3ba6hJoNmBItxaYODgJFpN/78IREZF+MT56FpMpIvI6BSU23PL+KqQcymuQ3baaBJoMSGoehvmjeiLYwv49RESkL4yPnsdkioi8SkGJDUPm/IXdWQUo8WCgqGAxGRDfOBiLxvT2u4BBRET6xfioDQ7tJSKvUWIrxy3vr9IsUMga7NidVYCR81ahxFauyRqIiIiqYnzUDpMpIvIaU5ZsQ8qhPM0CRYUSmx3bDuZhypIUTddBREQEMD5qickUEXmF1enZcplW40BRodhmx6L1GVizJ1vrpRARkR9jfNQWkyki0r2i0nLc//l6j3QlckZxmR33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6b90gYiI/ANjpOuYTBGR3wi2mLBoTG90aB7m8XKGQJMBHZqHYdGY3l4zKJGIiPwHY6RrFFXVe4d5IiL3KrGVY8qSFCxan4HiMnuDP1+gWeq/Jw5u71W7bURE5H8YI53DZIqI/NaaPdm477P1yCsqQ7HN/QEj0GRAmNWM2SO6IdlLLtISEREBjJGOYjJFRH6tqLQc035IwRdrMmBQgCI37MJZzQbYVWB4ciwmXNneK1q7EhERnYkxsm5MpoiIAOQWlWHh2gzMXbkb+SU2FJWVw5lXR0UBrGYjQiwm3NUvHkN76H9qOxERkSMYI2vGZIqIqAq7XcWfu47i1+1ZWJ1+DGmZ+TAoCkwGBSoAVVWhKAoUADa7Cruqok2TECTHRWFAuxj0jo+CwaBo/dsgIiJyO8bIszGZIiKqhd2uYl92IdKPFqDYVo5Smx0BJgMCTUa0jg5Gq6ggKIpvBQYiIiJHMEYymSIiIiIiInIJ50wRERERERG5gMkUERERERGRC5hMERERERERuYDJFBERERERkQuYTBEREREREbmAyRQREREREZELmEwRERERERG5gMkUERERERGRC5hMERERERERuYDJFBERERERkQuYTBEREREREbmAyRQREREREZELmEwRERERERG54P8BpYClOim4ApQAAAAASUVORK5CYII="
     },
     "metadata": {}
    }
   ],
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-05-17T08:26:08.431841Z",
     "start_time": "2021-05-17T08:26:08.172882Z"
    }
   }
Q
Quleaf 已提交
535 536 537 538 539
  },
  {
   "cell_type": "markdown",
   "source": [
    "The left graph given above shows a solution found by the parameterized quantum circuit, while the right graph given above shows a solution found by the brute-force algorithm. It can be seen that even if the order of the vertices are different, the routes are essentially the same, which verifies the correctness of using parameterized quantum circuit to solve the TSP."
Q
Quleaf 已提交
540 541
   ],
   "metadata": {}
Q
Quleaf 已提交
542 543 544 545 546 547 548 549 550 551 552 553 554
  },
  {
   "cell_type": "markdown",
   "source": [
    "##  Applications\n",
    "\n",
    "The TSP naturally applies in many transportation and logistics applications, for example, the problem of arranging school bus routes. The school bus application provides the motivation for Merrill Flood, a pioneer in the field of management science, to study TSP research in the 1940s. More recent applications involve food delivery route management [1] and power delivery for cable firms [2]. \n",
    "\n",
    "Other than those transportation applications, TSP also has wide usefulness in other management problems like scheduling of a machine to drill holes in a circuit board [3], reconstructing an unknown fragment of DNA [4] and scheduling optimal route in construction management [5]. Some consulting companies like [Nexus](https://nexustech.com.ph/company/newsletter/article/Finding-the-shortest-path-Optimizing-food-trips) have utilized this to provide management service.\n",
    "\n",
    "The TSP, as one of the most famous optimization problems, also provides a platform for the study of general methods in solving combinatorial problem. This is usually the first several problems that researchers give a try for experiments of new algorithms.\n",
    "\n",
    "More applications, formulations and solution approaches can be found in [6]."
Q
Quleaf 已提交
555 556
   ],
   "metadata": {}
Q
Quleaf 已提交
557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575
  },
  {
   "cell_type": "markdown",
   "source": [
    "_______\n",
    "\n",
    "## References\n",
    "\n",
    "[1] Bräysy, Olli, et al. \"An optimization approach for communal home meal delivery service: A case study.\" [Journal of Computational and Applied Mathematics 232.1 (2009): 46-53.](https://www.sciencedirect.com/science/article/pii/S0377042708005438)\n",
    "\n",
    "[2] Sloane, Thomas H., Frank Mann, and H. Kaveh. \"Powering the last mile: an alternative to powering FITL.\" [Proceedings of Power and Energy Systems in Converging Markets. IEEE, 1997.](https://ieeexplore.ieee.org/document/646046)\n",
    "\n",
    "[3] Onwubolu, Godfrey C. \"Optimizing CNC drilling machine operations: traveling salesman problem-differential evolution approach.\" [New optimization techniques in engineering. Springer, Berlin, Heidelberg, 2004. 537-565.](https://link.springer.com/chapter/10.1007/978-3-540-39930-8_22)\n",
    "\n",
    "[4] Caserta, Marco, and Stefan Voß. \"A hybrid algorithm for the DNA sequencing problem.\" [Discrete Applied Mathematics 163 (2014): 87-99.](https://www.sciencedirect.com/science/article/pii/S0166218X12003253)\n",
    "\n",
    "[5] Klanšek, Uroš. \"Using the TSP solution for optimal route scheduling in construction management.\" [Organization, technology & management in construction: an international journal 3.1 (2011): 243-249.](https://www.semanticscholar.org/paper/Using-the-TSP-Solution-for-Optimal-Route-Scheduling-Klansek/3d809f185c03a8e776ac07473c76e9d77654c389)\n",
    "\n",
    "[6] Matai, Rajesh, Surya Prakash Singh, and Murari Lal Mittal. \"Traveling salesman problem: an overview of applications, formulations, and solution approaches.\" [Traveling salesman problem, theory and applications 1 (2010).](https://www.sciencedirect.com/topics/computer-science/traveling-salesman-problem)"
Q
Quleaf 已提交
576 577
   ],
   "metadata": {}
Q
Quleaf 已提交
578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595
  }
 ],
 "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",
Q
Quleaf 已提交
596
   "version": "3.7.11"
Q
Quleaf 已提交
597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
Q
Quleaf 已提交
614
}