|
| 1 | +{ |
| 2 | + "cells": [ |
| 3 | + { |
| 4 | + "cell_type": "markdown", |
| 5 | + "metadata": {}, |
| 6 | + "source": [ |
| 7 | + "<img src=\"../../../images/qiskit-heading.gif\" alt=\"Note: In order for images to show up in this jupyter notebook you need to select File => Trusted Notebook\" width=\"500 px\" align=\"left\">" |
| 8 | + ] |
| 9 | + }, |
| 10 | + { |
| 11 | + "cell_type": "markdown", |
| 12 | + "metadata": {}, |
| 13 | + "source": [ |
| 14 | + "# _*Qiskit Aqua: Generating Ising Hamiltonians from optimization models with DOcplex*_\n", |
| 15 | + "\n", |
| 16 | + "The latest version of this notebook is available on https://github.com/Qiskit/qiskit-tutorial.\n", |
| 17 | + "\n", |
| 18 | + "***\n", |
| 19 | + "### Contributors\n", |
| 20 | + "Atsushi Matsuo<sup>[1]</sup>, Takashi Imamichi<sup>[1]</sup>, Marco Pistoia<sup>[1]</sup>, Stephen Wood<sup>[1]</sup>\n", |
| 21 | + "### Affiliation\n", |
| 22 | + "- <sup>[1]</sup>IBMQ" |
| 23 | + ] |
| 24 | + }, |
| 25 | + { |
| 26 | + "cell_type": "markdown", |
| 27 | + "metadata": {}, |
| 28 | + "source": [ |
| 29 | + "## Introduction\n", |
| 30 | + "There has been a growing interest in using quantum computers to find solutions of combinatorial problems. A heuristic approach for finding solutions of combinatorial problems on quantum computers is the quantum variational approach, such as the Variational Quantum \n", |
| 31 | + "Eigensolver (VQE) algorithm (see https://arxiv.org/abs/1802.00171 and the Quantum Approximate Optimization Algorithm (QAOA) (see https://arxiv.org/abs/1411.4028). In order to use a quantum variational approach on quantum computers, first, we need to map a combinatorial problem to an Ising Hamiltonian. However Ising Hamiltonians are complicated and unintuitive. Mapping a combinatorial problem to Ising Hamiltonians can be a difficult and time-consuming task, requiring specialized knowledge.\n", |
| 32 | + "\n", |
| 33 | + "In this tutorial, we introduce a translator to automatically generate Ising Hamiltonians from classical optimization models. We will explain about classical optimization models later. The translator dramatically simplifies the task of designing and implementing quantum-computing-based solutions, for optimization problems, by automatically generating Ising Hamiltonians for different optimization problems. With the translator, all a user has to do is to write optimization models using DOcplex (see https://cdn.rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html). DOcplex is a python library for optimization problems.\n", |
| 34 | + "Then the translator will automatically generate Ising Hamiltonians from the models. Optimization models are short and intuitive. It is much easier to write optimization models compared to writing Ising Hamiltonians manually. \n", |
| 35 | + "\n", |
| 36 | + "The quantum variational approach works with the translator in Qiskit Aqua as follows:\n", |
| 37 | + "1. Write an optimization model of the formulation with DOcplex.\n", |
| 38 | + "2. Call the translator to transform the model into an Ising Hamiltonian.\n", |
| 39 | + "3. Solve the problem with variational algorithms such as VQE and QAOA.\n", |
| 40 | + "\n", |
| 41 | + "\n", |
| 42 | + "### Details of Optimization Models\n", |
| 43 | + "The translator supports the generation of an Ising Hamiltonian from the following optimization model elements:\n", |
| 44 | + "- Binary decision variables. \n", |
| 45 | + "- Linear and quadratic terms in objective functions.\n", |
| 46 | + "- Only equality constraints. \n", |
| 47 | + "\n", |
| 48 | + "Input models are validated before transformation. If the model contains elements that are not from the supported set, an error will be raised.\n", |
| 49 | + "\n", |
| 50 | + "Even though there are restrictions, this type of optimization model can handle optimization problems such as max-cut, traveling salesman etc.\n", |
| 51 | + "These are typical optimization problems. Examples of the translator being used for Max-Cut and TSP problems can be found in the following tutorial:\n", |
| 52 | + "- [Qiskit Aqua: Experimenting with Max-Cut problem and Traveling Salesman problem with variational quantum eigensolver](max_cut_and_tsp.ipynb)" |
| 53 | + ] |
| 54 | + }, |
| 55 | + { |
| 56 | + "cell_type": "markdown", |
| 57 | + "metadata": {}, |
| 58 | + "source": [ |
| 59 | + "### A Usage Example: Maximize the number of variables by taking into account constraints\n", |
| 60 | + "The following is a toy example of a maximization problem with constraints.\n", |
| 61 | + "\n", |
| 62 | + "\\begin{aligned}\n", |
| 63 | + " & \\text{maximize}\n", |
| 64 | + " & \\sum_{i} x_{i}\\\\\n", |
| 65 | + " & \\text{subject to}\n", |
| 66 | + " & \\sum_{i} i * x_{i}=3\\\\\n", |
| 67 | + " & & i \\in \\{1,2,3,4\\} \\\\\n", |
| 68 | + " & & x_i \\in \\{0,1\\}\\\\\n", |
| 69 | + "\\end{aligned}" |
| 70 | + ] |
| 71 | + }, |
| 72 | + { |
| 73 | + "cell_type": "code", |
| 74 | + "execution_count": 2, |
| 75 | + "metadata": {}, |
| 76 | + "outputs": [], |
| 77 | + "source": [ |
| 78 | + "from docplex.mp.model import Model\n", |
| 79 | + "\n", |
| 80 | + "from qiskit import BasicAer\n", |
| 81 | + "from qiskit.aqua import Operator, run_algorithm\n", |
| 82 | + "from qiskit.aqua.algorithms import VQE, ExactEigensolver\n", |
| 83 | + "from qiskit.aqua.components.optimizers import SPSA\n", |
| 84 | + "from qiskit.aqua.components.variational_forms import RY\n", |
| 85 | + "from qiskit.aqua import QuantumInstance\n", |
| 86 | + "from qiskit.aqua.translators.ising import docplex\n", |
| 87 | + "\n", |
| 88 | + "# setup aqua logging\n", |
| 89 | + "import logging\n", |
| 90 | + "from qiskit.aqua import set_qiskit_aqua_logging\n", |
| 91 | + "# set_qiskit_aqua_logging(logging.DEBUG) # choose INFO, DEBUG to see the log" |
| 92 | + ] |
| 93 | + }, |
| 94 | + { |
| 95 | + "cell_type": "markdown", |
| 96 | + "metadata": {}, |
| 97 | + "source": [ |
| 98 | + "### Creating an optimization model of the above problem using DOcplex\n", |
| 99 | + "An optimization model of the problem with DOcplex is written as follows. \n", |
| 100 | + "* First an instance of `Model` is created and variables for the model are defined. \n", |
| 101 | + "* Next an objective function is written and passed to the model. The objective function is a function that we would like to minimize (or maximize).\n", |
| 102 | + "* Finally constraints are added. " |
| 103 | + ] |
| 104 | + }, |
| 105 | + { |
| 106 | + "cell_type": "code", |
| 107 | + "execution_count": 3, |
| 108 | + "metadata": { |
| 109 | + "scrolled": true |
| 110 | + }, |
| 111 | + "outputs": [ |
| 112 | + { |
| 113 | + "name": "stdout", |
| 114 | + "output_type": "stream", |
| 115 | + "text": [ |
| 116 | + "\\ This file has been generated by DOcplex\n", |
| 117 | + "\\ ENCODING=ISO-8859-1\n", |
| 118 | + "\\Problem name: max_vars\n", |
| 119 | + "\n", |
| 120 | + "Maximize\n", |
| 121 | + " obj: x_1 + x_2 + x_3 + x_4\n", |
| 122 | + "Subject To\n", |
| 123 | + " c1: x_1 + 2 x_2 + 3 x_3 + 4 x_4 = 3\n", |
| 124 | + "\n", |
| 125 | + "Bounds\n", |
| 126 | + "0 <= x_1 <= 1\n", |
| 127 | + "0 <= x_2 <= 1\n", |
| 128 | + "0 <= x_3 <= 1\n", |
| 129 | + "0 <= x_4 <= 1\n", |
| 130 | + "\n", |
| 131 | + "Binaries\n", |
| 132 | + " x_1 x_2 x_3 x_4\n", |
| 133 | + "End\n", |
| 134 | + "\n" |
| 135 | + ] |
| 136 | + } |
| 137 | + ], |
| 138 | + "source": [ |
| 139 | + "# Create an instance of a model and variables\n", |
| 140 | + "mdl = Model(name='max_vars')\n", |
| 141 | + "x = {i: mdl.binary_var(name='x_{0}'.format(i)) for i in range(1,5)}\n", |
| 142 | + "\n", |
| 143 | + "# Objective function\n", |
| 144 | + "max_vars_func = mdl.sum(x[i] for i in range(1,5))\n", |
| 145 | + "mdl.maximize(max_vars_func)\n", |
| 146 | + "\n", |
| 147 | + "# Constraints\n", |
| 148 | + "mdl.add_constraint(mdl.sum(i*x[i] for i in range(1,5)) == 3)\n", |
| 149 | + "\n", |
| 150 | + "print(mdl.export_to_string())" |
| 151 | + ] |
| 152 | + }, |
| 153 | + { |
| 154 | + "cell_type": "markdown", |
| 155 | + "metadata": {}, |
| 156 | + "source": [ |
| 157 | + "### Generate an Ising Hamiltonian from the model using ```docplex.get_qubitops(mdl)```\n" |
| 158 | + ] |
| 159 | + }, |
| 160 | + { |
| 161 | + "cell_type": "code", |
| 162 | + "execution_count": 3, |
| 163 | + "metadata": {}, |
| 164 | + "outputs": [], |
| 165 | + "source": [ |
| 166 | + "qubitOp, offset = docplex.get_qubitops(mdl)" |
| 167 | + ] |
| 168 | + }, |
| 169 | + { |
| 170 | + "cell_type": "markdown", |
| 171 | + "metadata": {}, |
| 172 | + "source": [ |
| 173 | + "### Checking that the full Hamiltonian gives the right cost" |
| 174 | + ] |
| 175 | + }, |
| 176 | + { |
| 177 | + "cell_type": "code", |
| 178 | + "execution_count": 4, |
| 179 | + "metadata": {}, |
| 180 | + "outputs": [ |
| 181 | + { |
| 182 | + "name": "stdout", |
| 183 | + "output_type": "stream", |
| 184 | + "text": [ |
| 185 | + "energy: -57.5\n", |
| 186 | + "objective: -2.0\n", |
| 187 | + "solution: [1. 1. 0. 0.]\n" |
| 188 | + ] |
| 189 | + } |
| 190 | + ], |
| 191 | + "source": [ |
| 192 | + "ee = ExactEigensolver(qubitOp, k=1)\n", |
| 193 | + "result = ee.run()\n", |
| 194 | + "\n", |
| 195 | + "print('energy:', result['energy'])\n", |
| 196 | + "print('objective:', result['energy'] + offset)\n", |
| 197 | + "\n", |
| 198 | + "x = docplex.sample_most_likely(result['eigvecs'][0])\n", |
| 199 | + "print('solution:', x)" |
| 200 | + ] |
| 201 | + }, |
| 202 | + { |
| 203 | + "cell_type": "markdown", |
| 204 | + "metadata": {}, |
| 205 | + "source": [ |
| 206 | + "### Running it on quantum computer\n", |
| 207 | + "We run the optimization routine using a feedback loop with a quantum computer that uses trial functions built with Y single-qubit rotations, $U_\\mathrm{single}(\\theta) = \\prod_{i=1}^n Y(\\theta_{i})$, and entangler steps $U_\\mathrm{entangler}$." |
| 208 | + ] |
| 209 | + }, |
| 210 | + { |
| 211 | + "cell_type": "code", |
| 212 | + "execution_count": 9, |
| 213 | + "metadata": {}, |
| 214 | + "outputs": [ |
| 215 | + { |
| 216 | + "name": "stdout", |
| 217 | + "output_type": "stream", |
| 218 | + "text": [ |
| 219 | + "energy: -57.16261789728296\n", |
| 220 | + "time: 10.59960389137268\n", |
| 221 | + "solution objective: -1.6626178972829635\n", |
| 222 | + "solution: [1. 1. 0. 0.]\n" |
| 223 | + ] |
| 224 | + } |
| 225 | + ], |
| 226 | + "source": [ |
| 227 | + "seed = 10598\n", |
| 228 | + "\n", |
| 229 | + "spsa = SPSA(max_trials=300)\n", |
| 230 | + "ry = RY(qubitOp.num_qubits, depth=5, entanglement='linear')\n", |
| 231 | + "vqe = VQE(qubitOp, ry, spsa, 'matrix')\n", |
| 232 | + "\n", |
| 233 | + "backend = BasicAer.get_backend('statevector_simulator')\n", |
| 234 | + "quantum_instance = QuantumInstance(backend, seed=seed, seed_transpiler=seed)\n", |
| 235 | + "\n", |
| 236 | + "result = vqe.run(quantum_instance)\n", |
| 237 | + "\n", |
| 238 | + "\"\"\"declarative approach\n", |
| 239 | + "algorithm_cfg = {\n", |
| 240 | + " 'name': 'VQE',\n", |
| 241 | + " 'operator_mode': 'matrix'\n", |
| 242 | + "}\n", |
| 243 | + "\n", |
| 244 | + "optimizer_cfg = {\n", |
| 245 | + " 'name': 'SPSA',\n", |
| 246 | + " 'max_trials': 300\n", |
| 247 | + "}\n", |
| 248 | + "\n", |
| 249 | + "var_form_cfg = {\n", |
| 250 | + " 'name': 'RY',\n", |
| 251 | + " 'depth': 5,\n", |
| 252 | + " 'entanglement': 'linear'\n", |
| 253 | + "}\n", |
| 254 | + "\n", |
| 255 | + "params = {\n", |
| 256 | + " 'problem': {'name': 'ising', 'random_seed': seed},\n", |
| 257 | + " 'algorithm': algorithm_cfg,\n", |
| 258 | + " 'optimizer': optimizer_cfg,\n", |
| 259 | + " 'variational_form': var_form_cfg,\n", |
| 260 | + " 'backend': {provider': 'qiskit.BasicAer', 'name': 'statevector_simulator'}\n", |
| 261 | + "}\n", |
| 262 | + "\n", |
| 263 | + "result = run_algorithm(params, algo_input)\n", |
| 264 | + "\"\"\"\n", |
| 265 | + "\n", |
| 266 | + "x = docplex.sample_most_likely(result['eigvecs'][0])\n", |
| 267 | + "print('energy:', result['energy'])\n", |
| 268 | + "print('time:', result['eval_time'])\n", |
| 269 | + "print('solution objective:', result['energy'] + offset)\n", |
| 270 | + "print('solution:', x)" |
| 271 | + ] |
| 272 | + } |
| 273 | + ], |
| 274 | + "metadata": { |
| 275 | + "kernelspec": { |
| 276 | + "display_name": "Python 3", |
| 277 | + "language": "python", |
| 278 | + "name": "python3" |
| 279 | + }, |
| 280 | + "language_info": { |
| 281 | + "codemirror_mode": { |
| 282 | + "name": "ipython", |
| 283 | + "version": 3 |
| 284 | + }, |
| 285 | + "file_extension": ".py", |
| 286 | + "mimetype": "text/x-python", |
| 287 | + "name": "python", |
| 288 | + "nbconvert_exporter": "python", |
| 289 | + "pygments_lexer": "ipython3", |
| 290 | + "version": "3.7.2" |
| 291 | + } |
| 292 | + }, |
| 293 | + "nbformat": 4, |
| 294 | + "nbformat_minor": 2 |
| 295 | +} |
0 commit comments