{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Traveling Salesman on Dirac\n", "#### Device: Dirac-1\n", "\n", "## Introduction\n", "\n", "The traveling salesman problem (TSP) is a longstanding example of the difficulty found in solving combinatorial problems. The typical problem statement is that a list of cities must all be visited, but one can do so in any order. A list of distances between cities is provided, and the goal is to find the order that minimizes the total distance traveled. Despite the simple explanation of the problem, a polynomial-time solution is not known to exist. This example takes 8 random points on the upper right quadrant $(30, 30)$ of the Cartesian plane, calculates the Euclidian distance between them, and formulates a sequential model (visit node $x_i$ first, node $x_j$ second and so forth )." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Importance\n", "\n", "TSP is often used as an archetypal example of a hard optimization problem. It is easy to understand how such a problem arises, the statement is simple and non-technical, and the constraints are easy to understand. Sometimes people even informally use it as a shorthand for all hard combinatorial optimization problems, referring to NP-hard problems as \"travelling salesman type problems\". When formally stating the constraints of the TSP, the best formulation is not to directly constrain \"visit each city at least once\". Instead, the constraints are formally that $n$ cities have to be visited, and each can be visited only once. Since distances between cities are positive, returning to the same city multiple times is clearly suboptimal, and therefore such routes do not need to be included among the possibilities. Note that it is perfectly possible that the shortest route goes through another city, but this case does not need any special treatment. The second constraint is one which is physically obvious but still needs to be explicitly encoded: the salesperson can only be in once city at a time. The constraint structure is therefore what is called a two-way one-hot structure. Variables correspond to visiting a city at a certain time in the tour, if we arrange these in rows corresponding to cities and columns corresponding to times, the sum of each row and column must be one. Since it involves constraints, we format the TSP as a [quadratic linearly constrained binary optimization](https://quantumcomputinginc.com/learn/tutorials-and-use-cases/qlcbo-on-dirac) problem. This constraint pattern can be found in other problems as well, for example the [quadratic assignment problem](https://quantumcomputinginc.com/learn/tutorials-and-use-cases/quadratic-assignment-on-dirac)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Applications\n", "The most obvious application of this problem can be deduced from the name. Imagine a door-to-door salesperson who has to visit a set of cities to sell goods. The order is not important, but every city must be visited. However, the salesperson has to buy fuel and spend time driving, so they want to minimize the distance. This stereotypical application has even made it into popular culture, for example, in [xkcd 399](https://xkcd.com/399). One can also imagine many situations in logistics where the same problem could arise. For example, if a driver were making deliveries or picking items up instead of selling products. Less obvious examples are summarized in [this book](https://core.ac.uk/download/478116421.pdf). For example, this problem can also arise in manufacturing, when holes must be drilled in a board, but can be done so in any order. Similarly, if a circuit is to be wired with connected pins, but only two wires are allowed to connect to each. A completely different example comes up in x-ray crystallography where a single sensor must be moved to measure at different places, but the measurements can be taken in any order." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Using Dirac-1 Through the Cloud" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### I. Imports" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "These imports bring in various libraries and modules for different functionalities, such as: \n", "- `os.path`: Provides functions for working with file paths.\n", "- `numpy as np`: Numerical computing library for arrays and mathematical operations.\n", "- `matplotlib.pyplot as plt`: Plotting library for creating visualizations.\n", "- `Dirac1CloudSolver` from `eqc_models.solvers`: Client class for interacting with an external service.\n", "- `QAPModel` from `eqc_models.assignment`: Class for quadratic assignment problem models" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import os.path\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "from eqc_models.solvers import Dirac1CloudSolver\n", "from eqc_models.assignment import QAPModel" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### II. Plot of random points" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Visualize the set up of the initial conditions for solving the TSP by generating city coordinates." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "n = 8\n", "np.random.seed(n)\n", "coords = np.random.randint(1, 30, (n, 2))" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "image/png": "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AADJEqsAACRLrAIAkCyxCgBAssQqAADJEqsAACRLrAIAkCyxCgBAssQqAADJEqsAACRLrAIAkCyxCgBAssQqAADJEqsAACRLrAIAkCyxCgBAssQqAADJEqsAACRLrAIAkCyxCgBAssQqAADJEqsAACRLrAIAkCyxCgBAssQqAADJEqsAACRLrAIAkCyxCgBAssQqAADJEqsAACRLrAIAkCyxCgBAssQqAADJEqsAACRLrAIAkCyxCgBAssQqAADJEqsAACQrr1hdtmxZXH/99VFWVhaVlZUxb9682L17d5d9pk+fHplMpsvXH//xH5/xuLlcLh555JGorq6OYcOGxS233BJvvfVW/mcDAMCAklesbtiwIRYuXBhbtmyJtWvXRjabjVmzZkVra2uX/e6///5obGzs/Hr88cfPeNzHH388vv/978eTTz4ZW7dujQsvvDBmz54dbW1t+Z8RAAADxgX57NzQ0NDl8TPPPBOVlZWxffv2uPHGGzu3Dx8+PKqqqs7pmLlcLp544on4zne+E7fddltERPzoRz+K0aNHx0svvRR33HFHPksEAGAAyStWP6q5uTkiIioqKrps//GPfxwrV66MqqqqmDt3bjz88MMxfPjwHo+xb9++aGpqiltuuaVzW3l5eUydOjU2b97cY6y2t7dHe3t75+OWlpaIiMhms5HNZj/OKfW7k+sv9PMYzMyw8JlhYTO/wmeGha+nGfZ2nplcLpfrzQs7Ojri1ltvjSNHjsSmTZs6t/+3//bf4vLLL4+ampp444034lvf+lZMmTIlfvrTn/Z4nN/85jfxuc99Lg4cOBDV1dWd27/4xS9GJpOJF154odtrli5dGvX19d22r1q16rRRDABA/zl+/Hjcdddd0dzcHCNGjDjn1/X6J6sLFy6MXbt2dQnViIgHHnig87+vuuqqqK6ujhkzZsTevXtj3Lhxvf3nunjooYdi8eLFnY9bWlpi7NixMWvWrLxOPkXZbDbWrl0bM2fOjOLi4v5eDr1ghoXPDAub+RU+Myx8Pc3w5G/C89WrWF20aFG88sorsXHjxhgzZswZ9506dWpEROzZs6fHWD15bevBgwe7/GT14MGDcc011/R4zJKSkigpKem2vbi4eMB8Uw+kcxmszLDwmWFhM7/CZ4aF79QZ9naWed0NIJfLxaJFi2L16tXx2muvRW1t7Vlfs3Pn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LFu27LRx297eHu3t7Z2PW1paIuLDyxCy2Wyfrb0/nFx/oZ/HYGaGhc8MC5v5FT4zLHw9zbC388zkcrlcbxeSyWRi9erVMW/evB6fb2tri8997nMxYcKE+PGPf3za47z66qtx7NixuPLKK6OxsTHq6+vjn//5n2PXrl1RVlbWbf+lS5dGfX19t+2rVq2K4cOH9/Z0AAD4hBw/fjzuuuuuaG5ujhEjRpzz6z6xWM1ms3H77bfHO++8E+vXr89rUUeOHInLL788vve978V9993X7fmefrI6duzYOHToUF7/Toqy2WysXbs2Zs6cGcXFxf29HHrBDAufGRY28yt8Zlj4epphS0tLjBo1Ku9Y/UQuA8hms/HFL34x/s//+T/x2muv5R2QF198cXz605+OPXv29Ph8SUlJlJSUdNteXFw8YL6pB9K5DFZmWPjMsLCZX+Ezw8J36gx7O8s+v8/qyVB966234le/+lWMHDky72McO3Ys9u7dG9XV1X29PAAACkjesXrs2LHYuXNn7Ny5MyIi9u3bFzt37oy33347stls/Pt//+/j9ddfjx//+Mdx4sSJaGpqiqampvjggw86jzFjxoz4wQ9+0Pn461//emzYsCH2798fv/nNb+Lzn/98FBUVxZ133vnxzxAAgIKV92UAr7/+etx0002djxcvXhwREfPnz4+lS5fGyy+/HBER11xzTZfX/frXv47p06dHRMTevXvj0KFDnc+98847ceedd8Z7770Xl156adxwww2xZcuWuPTSS/NdHgAAA0jesTp9+vQ4099kncvfa+3fv7/L4+effz7fZQAAMAj0+TWrAADQV8QqAADJEqsAACRLrAIAkCyxCgBAssQqAADJEqsAACRLrAIAkCyxCgBAssQqAADJEqsAACRLrAIAkCyxCgBAssQqAADJEqsAACRLrAIAkCyxCgBAssQqAADJEqsAACRLrAIAkCyxCgBAssQqAADJEqsAACRLrAIAkCyxCgBAssQqAADJEqsAACRLrAIAkCyxCgBAssQqAADJEqsAACRLrAIAkCyxCgBAssQqAADJEqsAACRLrAIAkCyxCgBAssQqAAPGiY5cbNt3OCIitu07HCc6cv28IuDjEqsADAgNuxrjhr96Lb7y7D9ERMRXnv2HuOGvXouGXY39vDLg4xCrABS8hl2NsWDljmhsbuuyvam5LRas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RMRdd90Vl19+edTU1MQbb7wR3/rWt2L37t3x05/+tB9Xy6l++9vfxrRp06KtrS0uuuiiWL16dUycODF27tzZZ+8/sZqIOXPmdP731VdfHVOnTo3LL788/sf/+B9x33339ePKYHC64447Ov/7qquuiquvvjrGjRsX69evjxkzZvTjyujJwoULY9euXa71L1Cnm98DDzzQ+d9XXXVVVFdXx4wZM2Lv3r0xbty4871MenDllVfGzp07o7m5OX7yk5/E/PnzY8OGDX36b7gMIFEXX3xxfPrTn449e/b091LohaqqqoiIbn/1ePDgwc7nKCxXXHFFjBo1ynsyQYsWLYpXXnklfv3rX8eYMWM6t1dVVcUHH3wQR44c6bK/92FaTje/nkydOjUiwvswIUOHDo3x48fHddddF8uWLYvJkyfH3/7t3/bp+0+sJurYsWOxd+/eqK6u7u+l0Au1tbVRVVUV69at69zW0tISW7dujWnTpvXjyuitd955J9577z3vyYTkcrlYtGhRrF69Ol577bWora3t8vx1110XxcXFXd6Hu3fvjrffftv7MAFnm19Pdu7cGRHhfZiwjo6OaG9v79P3n8sAEvH1r3895s6dG5dffnkcOHAglixZEkVFRXHnnXf299I4jWPHjnX5f/f79u2LnTt3RkVFRVx22WXx4IMPxmOPPRZ/8Ad/ELW1tfHwww9HTU1NzJs3r/8WTaczza+ioiLq6+vj9ttvj6qqqti7d29885vfjPHjx8fs2bP7cdWcauHChbFq1ar42c9+FmVlZZ3XwZWXl8ewYcOivLw87rvvvli8eHFUVFTEiBEj4qtf/WpMmzYtPvvZz/bz6jnb/Pbu3RurVq2Kf/fv/l2MHDky3njjjfja174WN954Y1x99dX9vHoiIh566KGYM2dOXHbZZXH06NFYtWpVrF+/Pn7xi1/07fuvb29YQG996UtfylVXV+eGDh2a+1f/6l/lvvSlL+X27NnT38viDH7961/nIqLb1/z583O53Ie3r3r44Ydzo0ePzpWUlORmzJiR2717d/8umk5nmt/x48dzs2bNyl166aW54uLi3OWXX567//77c01NTf29bE7R0/wiIvf000937vP+++/n/uRP/iR3ySWX5IYPH577/Oc/n2tsbOy/RdPpbPN7++23czfeeGOuoqIiV1JSkhs/fnzuG9/4Rq65ubl/F06nr3zlK7nLL788N3To0Nyll16amzFjRu6Xv/xl5/N99f7L5HK53MctawAA+CS4ZhUAgGSJVQAAkiVWAQBIllgFACBZYhUAgGSJVQAAkiVWAQBIllgFACBZYhUAgGSJVQAAkiVWAQBI1v8PMQ39CzuAlsEAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig = plt.figure(figsize=(8, 8))\n", "plt.scatter(coords[:,0], coords[:, 1])\n", "plt.grid()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### III. Problem formulation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`tsp_objective`, below, computes the components of the objective function for the Traveling Salesman Problem (TSP) based on the given distance matrix. The components are components of quadratic assignment problems, tailored towards TSP.\n", "\n", "- Input: `distance_matrix` is a square matrix representing the distances between various locations (nodes) in the TSP.\n", "\n", "- Output: The function returns three components of the TSP objective function:\n", "\n", " 1. Distance Matrix (`D`): This matrix represents the distances between locations. It's essentially a copy of the input `distance_matrix`.\n", "\n", " 2. Flow Matrix (`flow`): This matrix represents the flow or connections between locations. It's a diagonal matrix with ones along the secondary diagonal and one additional one to close the loop (from the last node back to the first).\n", "\n", " 3. Fixed Cost Matrix (`fixed_cost`): This matrix represents fixed costs associated with visiting each location. The first row indicates the fixed cost for each location, and it's set to 4 for all locations except the first (which is set to 0). The values are then normalized so that their sum equals the average cost per location.\n", " \n", "These components are used to formulate the objective function for optimization algorithms solving the TSP." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "def tsp_objective(distance_matrix):\n", " n = distance_matrix.shape[0]\n", " D = distance_matrix\n", " flow = np.diag(np.ones(n-1), 1)\n", " flow[n-1, 0] = 1\n", " fixed_cost = np.zeros((n, n))\n", " fixed_cost[0, :] = 4 * np.ones(n)\n", " fixed_cost[0, 0] = 0.0\n", " fixed_cost /= (np.sum(fixed_cost) / n)\n", " return D, flow, fixed_cost" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Compute the pairwise distances between each pair of coordinates to be used in the problem instance." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "def dist(coord1, coord2):\n", " return np.sqrt(np.sum(np.power(coord1-coord2, 2), axis=1))\n", "\n", "distance_matrix = np.zeros((n, n))\n", "for i in range(n):\n", " distance_matrix[i,:] = dist(coords, coords[i])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "After constructing the necessary data structures QAP needs for the TSP, create a model instance." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "A, B, C = tsp_objective(distance_matrix)\n", "qapmodel = QAPModel(A, B, C)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### IV. Obtain a Solver Client\n", "The `Dirac1CloudSolver` class is used to manage access to the cloud service for running jobs on Dirac-1. The constructor accepts two parameters\n", "\n", "- `url` which is the same as the QCI_API_URL environment variable for `QciClient`\n", "- `api_token` which is same as the QCI_TOKEN environment variable for `QciClient`\n", "\n", "If these variables are not supplied, the shell environment is used for client configuration. This is the preferred method and is used here. Once the solver is instantiated, it can be used to solve any subclass of `eqc_models.base.EQCModel` that provides the `qubo` operator." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "solver = Dirac1CloudSolver()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Solve**\n", "\n", "Model parameters:\n", "- `penalty_multiplier`: 20\n", "\n", "Method parameters:\n", "- `num_samples`: 5\n" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2025-01-07 11:04:57 - Dirac allocation balance = 0 s (unmetered)\n", "2025-01-07 11:04:57 - Job submitted: job_id='677d6cc98dd54d8a9ea605ec'\n", "2025-01-07 11:04:57 - QUEUED\n", "2025-01-07 11:04:59 - RUNNING\n", "2025-01-07 11:06:04 - COMPLETED\n", "2025-01-07 11:06:07 - Dirac allocation balance = 0 s (unmetered)\n" ] } ], "source": [ "qapmodel.penalty_multiplier = 20\n", "response = solver.solve(qapmodel, num_samples=5)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'counts': [1, 1, 1, 1, 1],\n", " 'energies': [-254.43588545796047,\n", " -252.56479170796047,\n", " -251.30307295796047,\n", " -249.74154952046047,\n", " -247.97543623921047],\n", " 'solutions': [[0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0],\n", " [0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0],\n", " [0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0],\n", " [0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0],\n", " [0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 1,\n", " 0,\n", " 1,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0,\n", " 0]]}" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "results = response[\"results\"]\n", "results" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### V. Evaluate solution" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Visualization of a route based on a given solution to the Traveling Salesman Problem (TSP)." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "def plot_route(coords, solution, N):\n", " pairs = []\n", " order = [None for i in range(N)]\n", " for i in range(N):\n", " for j in range(N):\n", " if solution[i*N + j] == 1:\n", " order[j] = i\n", " for i in range(N):\n", " u = order[i-1]\n", " v = order[i]\n", " if u is None or v is None:\n", " continue\n", " pt1 = coords[u, :]\n", " pt2 = coords[v, :]\n", " x = [pt1[0], pt2[0]]\n", " y = [pt1[1], pt2[1]]\n", " plt.plot(x, y, \"r-\")\n", " plt.scatter(coords[:,0], coords[:, 1], c=\"k\", marker=\"o\")" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAqsAAAKTCAYAAAA+MkExAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/GU6VOAAAACXBIWXMAAA9hAAAPYQGoP6dpAACEx0lEQVR4nO3dd3jUVdrG8e9kSAKB0EsSQkdFWSmyCKyUIB2VElABUQQsK6AioK6FZqPsrhTltSsoBlkQkI50EmkKImChIzUgIAkhEFLm/eOQABJKQpIz5f5cVy5+U3mGwyR3fnPOeRwul8uFiIiIiIgb8rNdgIiIiIjIlSisioiIiIjbUlgVEREREbelsCoiIiIibkthVURERETclsKqiIiIiLgthVURERERcVv5bBeQE9LS0jh06BDBwcE4HA7b5YiIiIjIX7hcLk6dOkVYWBh+ftd/vtQrwuqhQ4coV66c7TJERERE5Br2799PeHj4dd/fK8JqcHAwYF584cKFLVdzY5KTk/n2229p2bIl/v7+tsuRbNAYej6NoWfT+Hk+jaHny2wM4+PjKVeuXEZuu15eEVbTP/ovXLiwV4TVoKAgChcurDeoh9IYej6NoWfT+Hk+jaHnu9oYZnXKphZYiYiIiIjbUlgVEREREbelsCoiIiIibkthVURERETclsKqiIiIiLitLIXVESNGULduXYKDgyldujQdOnRg27ZtGbfv3bsXh8OR6de0adOu+LyPPvroZfdv3bp19l+ViIiIiHiFLIXVlStX0rdvX9auXcvixYtJTk6mZcuWnD59GoBy5cpx+PDhS76GDx9OoUKFaNOmzVWfu3Xr1pc8bsqUKdl/VSIiIiLiFbK0z+rChQsvuTxx4kRKly7Nhg0baNy4MU6nk5CQkEvuM3PmTB544AEKFSp01ecODAy87LEiIiIi4ttuqClAXFwcAMWLF8/09g0bNrBp0yYmTJhwzedasWIFpUuXplixYtx999288cYblChRItP7JiUlkZSUlHE5Pj4eMBvQJicnZ/VluJX0+j39dfgyjaHn0xh6No2f59MYer7MxjC74+lwuVyu7DwwLS2Ndu3acfLkSWJiYjK9T58+fVixYgW//PLLVZ/rq6++IigoiEqVKrFr1y5efvllChUqxJo1a3A6nZfdf9iwYQwfPvyy66OioggKCsrOyxERERGRXJSYmEi3bt2Ii4vLUsfRbIfVp556igULFhATE0N4ePhlt585c4bQ0FAGDx7MwIEDs/Tcu3fvpkqVKixZsoRmzZpddntmZ1bLlSvHsWPHvKLd6uLFi2nRooVazHkojaHn0xh6No2f59MYer7MxjA+Pp6SJUtmOaxmaxpAv379mDt3LqtWrco0qAJMnz6dxMREHnnkkSw/f+XKlSlZsiQ7d+7MNKwGBgYSGBh42fX+/v5e85/am16Lr9IYej6NoWfT+Hk+jaHnu3gMszuWWQqrLpeLp59+mpkzZ7JixQoqVap0xft+8skntGvXjlKlSmW5qAMHDnD8+HFCQ0Oz/FgRERER8R5Z2rqqb9++TJ48maioKIKDg4mNjSU2NpYzZ85ccr+dO3eyatUqHnvssUyfp1q1asycOROAhIQEnn/+edauXcvevXtZunQp7du3p2rVqrRq1SqbL0tEREREvEGWwup7771HXFwcERERhIaGZnxNnTr1kvt9+umnhIeH07Jly0yfZ9u2bRk7CTidTjZv3ky7du24+eab6d27N3Xq1CE6OjrTj/pFRERExHdkeRrA9Xjrrbd46623rut5ChQowKJFi7JShoiIiIj4iCydWRURERERyUsKqyIiIiLithRWRURERMRtKayKiIiIiNvKVlMA8TypqalER0dz+PBhQkNDadSoUaatbEVERETcicKqD5gxYwbPPvssBw4cyLguPDyccePGERkZabEyERERkavTNAAvN2PGDDp37nxJUAU4ePAgnTt3ZsaMGZYqExEREbk2hVUvlpqayrPPPpuxr22Bi25Lv65///6kpqZaqE5ERETk2hRWvVh0dHTGGdV/ACeB7y663eVysX//fqKjoy1UJyIiInJtCqte7PDhwxnHfYEATGgdeZX7iYiIiLgThVUvFhoamnF8+qLrXwQ+AZyZ3E9ERETEnSiserFGjRoRHh6Ow+HgH+evGw+kAr2Ar4GqZcvSqFEjazWKiIiIXI3CqhdzOp2MGzeOYi4X1c9f9zoQCZwF2gNrChfGeeqUtRpFRERErkZh1ctFRkYy++WXAdgGHANmA91LleJcUBAlf/0VGjcGzVsVERERN6Sw6gPuOv9n4datiYqKYvny5Uw9fJiA1ashJAS2bIF//AN27LBap4iIiMhfKaz6gtWrAQjt1ImuXbsSERFhWq3WrAnffQdVqsDe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x47ZrkpERESySGHVE6VvWVW3LgQE2K3FnbVuDcuWQfHisH49NGwI+/bZrkpERESyQGHVE128uEqurl49iImB8HDYts38m/3yi+2qRERE5DoprHoizVfNmltvNf9m1arBgQPQqBGsWWO7KhEREbkOCque5sQJ+PVXc9yggd1aPEm5cuYMa7165t+weXNYsMB2VSIiInINCqueJv2M4C23QMmSdmvxNCVKwNKlpi1rYiK0a2d2DRARERG3laWwOmLECOrWrUtwcDClS5emQ4cObNu27ZL7RERE4HA4Lvn65z//edXndblcDBkyhNDQUAoUKEDz5s3ZsWNH1l+NL0hfXKUpANlTsCDMnm12C0hJMfuwpu/LKiIiIm4nS2F15cqV9O3bl7Vr17J48WKSk5Np2bIlp0+fvuR+jz/+OIcPH874Gj169FWfd/To0YwfP57333+fdevWUbBgQVq1asXZs2ez/oq8nRZX3biAAPjiC3jmGXP5uefg5ZfVnlVERMQN5cvKnRcuXHjJ5YkTJ1K6dGk2bNhA48aNM64PCgoiJCTkup7T5XIxduxYXn31Vdq3bw/A559/TpkyZZg1axZdunTJSoneLTnZbMEEOrN6o/z8zBnVMmVMi9YRI+DoUXj/fdNMQERERNzCDf1UjouLA6B48eKXXP/ll18yefJkQkJCuO+++xg8eDBBQUGZPseePXuIjY2lefPmGdcVKVKEevXqsWbNmkzDalJSEklJSRmX4+PjAUhOTiY5OflGXpJ16fVn9jocP/xAvjNncBUrRkrlyia8yo15/nkcJUrg7NMHxyefkPbHH6R+8QUUKJDtp7zaGIpn0Bh6No2f59MYer7MxjC74+lwubL32WdaWhrt2rXj5MmTxMTEZFz/4YcfUqFCBcLCwti8eTMvvvgid955JzNmzMj0eVavXs1dd93FoUOHCA0Nzbj+gQcewOFwMHXq1MseM2zYMIYPH37Z9VFRUVcMxd6g8pw53P7JJ8T+/e+se/VV2+V4ldC1a6nz3//iTE7mWPXqrHv5ZVIKFrRdloiIiNdITEykW7duxMXFUbhw4et+XLbPrPbt25etW7deElQBnnjiiYzj22+/ndDQUJo1a8auXbuoUqVKdv+6S7z00ksMGDAg43J8fDzlypWjZcuWWXrx7ig5OZnFixfTokUL/P39L7nN+cUXAJRq1462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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig = plt.figure(figsize=(8, 8))\n", "plot_route(coords, results[\"solutions\"][0], n)\n", "plt.grid()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Conclusion\n", "\n", "In this tutorial, we have shown how to use QCi hardware for one of the most well known NP-hard optimization problems, the traveling salesman problem. We constructed a simple map that assumes travel in a straight line between randomly assigned cities, and have visualized the result. A good next step could be to look at the [quadratic assignment problem](https://quantumcomputinginc.com/learn/tutorials-and-use-cases/quadratic-assignment-on-dirac), which uses the same constraint structure. Of course, another option is to start using our device to solve some of your own optimization problems." ] } ], "metadata": { "kernelspec": { "display_name": "Python (web-notebooks)", "language": "python", "name": "web-notebooks" }, "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.10.12" } }, "nbformat": 4, "nbformat_minor": 4 }