diff --git a/LoQus/Readme.md b/LoQus/Readme.md new file mode 100644 index 0000000..1d78382 --- /dev/null +++ b/LoQus/Readme.md @@ -0,0 +1,79 @@ +# 1- Vehicle Routing Problem (VRP) + +Vehicle Routing Problem (VRP) is a combinatorial optimization problem asking: "What is the optimal set of routes for vehicles to deliver to a given set of customers?" When optimizing the route option between fixed points, many constraints – e.g. vehicle number and capacities – need to be considered. VRP has proved to be NP-hard. As a result, the size of problems that can be optimized using classical methods is constrained by the computational resources. + +![alt text](https://github.com/walid-mk/Hackathon2022/blob/main/LoQus/VRP.png) + +Except using classical combinatorial optimization and mathematical programming to solve VRP, people also proposed applying quantum computing on this problem. Quantum annealers and quantum gate devices are two major paradigms. + +In this hackathon, we are going to apply filtering-Variational Quantum Eigensolver (F-VQE), which is a combination of quantum annealing process and quantum gates, to solve VRP. It should even give how many times faster compared to VQE? acceleration on top of the Variational Quantum Eigensolver (VQE) or Quantum Approximate Optimization Algorithm (QAOA). + +# 2- How we solved the problem + +### **Problem Hamiltonian:** + +From VRP one can construct a binary polynomial optimization with equality constraints only by considering cases in which K=n-1 (K is the number of vehicles and n is the number of nodes or depos). In these cases the sub-tour elimination constraints are not necessary and the problem is only on the variable z. In particular, we can write an augmented Lagrangian as (source [here](https://qiskit.org/documentation/optimization/tutorials/07_examples_vehicle_routing.html)) + +![alt text](https://github.com/walid-mk/Hackathon2022/blob/main/LoQus/VRP_Ham.png) + +where A is a big enough parameter. + +### **Filtering VQE & CVAR & Qiskit Runtime:** + +Our strategy is to provide an algorithm to deliver a solution that is much faster and more accurate compared with the state-of-the-art algorithms (namely VQE and QAOA) for solving combinatorial optimization problems on gate-based quantum computers. + +As a first solution, we proceeded with a new algorithm called [Filtering-VQE](https://arxiv.org/abs/2106.10055), claimed to outperform VQE and QAOA with faster convergence to the optimal solution. Our work was to implement the algorithm at the first stage and utilize this new quantum heuristic algorithm to solve VRP. See the code. + +Second, in order to improve this variational quantum optimization and increases the likelihood of finding the right solution, we are working on combining the filtering VQE approach with a method called [CVAR](https://arxiv.org/pdf/1907.04769.pdf), which make the expectation value computation more accurate. As a consequence, we anticipate significantly faster and more precise results. This is a developing project. + +On the other hand, IBM quantum offers Qiskit runtime to dramatically accelerate development and execution of quantum-enabled workloads by reducing the number of iterative processes in our computation. We intend to run our algorithm on Qiskit Runtime to leverage the simultaniouslty execution of multiple circuits in order to speed up our algorithm and output results much faster. We intend to use Qiskit runtime at the level of computing the gradient calculation, where we use the parameter shift rule to lead to a number of circuits executed equivalent to two times the number of parameters in the circuit for each iteration. Thanks to the QISKIT runtime, we can execute those circuits at the same time. This is a work in progress. + +The below figure shows how we envision our developed algorithm. In order to maximize the likelihood of finding the ideal answer with fewer iterations, we first combine FVQE with CVAR. Second, In order to significantly shorten the runtime of our method and enable a more effective quantum approach for our vehicule routing problem, we make use of Qiskit runtime. + +![alt text](https://github.com/walid-mk/Hackathon2022/blob/main/LoQus/plan.png) + +To briefly introduce Filtering VQE: By designing a quantum hamiltonian according to the fitness function of the given problem, the optimal route can be encoded in the lowest energy state of a qubit system. F-VQE provides an acceleration on the relaxation process of the quantum system. + +The basic idea is after applying a filtering operator F on state $\psi$, the probability of state $\psi$ will be modified by the prefactor $f^2$/<$F^2$> (see equation below). Function f is chosen to be monotonically decreasing with energy Ex. So higher energy states will have smaller weight after this operation and lower energy states will increase the portion. This operation can speed up the relaxation process. + +![alt text](https://github.com/walid-mk/Hackathon2022/blob/main/LoQus/probability.png) + +It is achieved by applying an operator (see below for a list of possible filtering operators) in each iteration that changes the probability (weight) of states according to the energy of that state. And with the extra operator, the quantum system will relax to its minimum energy state with much less iteration. + +![alt text](https://github.com/walid-mk/Hackathon2022/blob/main/LoQus/foperators.png) + +### **FVQE results:** + +![alt text](https://github.com/walid-mk/Hackathon2022/blob/main/LoQus/fvqe.png) + +![alt text](https://github.com/walid-mk/Hackathon2022/blob/main/LoQus/histogram.png) + +As we can see, filtering VQE has better convergence to the exact solution of our problem. It only requires a few iterations to reach a better estimate of the solution. + +![alt text](https://github.com/walid-mk/Hackathon2022/blob/main/LoQus/path.png) + +# 3- Business Part + +Quantum technology can provide a faster solution for the Vehicle Routing Problem. This way, we aim to offer a software for delivery managers that can handle many constraints and provide an optimal solution in a reasonable amount of time. Our software will take in account many factors of VRP such as: arrival and departure time gap, effective loading, vehicle limitation and number of stops on the route. Thus, delivery managers will be provided with a solution that minimizes costs and maximizes the efficiency of last mile deliveries. + +It has been estimated that, for delivery companies that use route optimization softwares, the increase in productivity can be over 15% and the reduction of CO2 emissions can be about 30%.Our software aims to provide a better logistic, financial and ecological performance. + +We address the route optimization software market. As customers, we target the industries that want to plan and optimize the routes of drivers to increase route efficiency and deliver in less time. + +Examples of market segments can be On-demand Food Delivery, Retail & fast moving consumer goods, field services, ride hailing and taxi services. +The route optimization software market is expanding: from $M 4,325.40 in 2020 it is projected to grow to $M 16,252.04 with a CAGR of 14.2%. + +**Sources** + +Allied Market Research. (2022, March). Route Optimization Software Market (No. A04093). https://www.alliedmarketresearch.com/route-optimization-software-market + +Altexsoft. (2019, September 18). How to Solve Vehicle Routing Problems:Route Optimization Software and Their APIs. https://www.altexsoft.com/blog/business/how-to-solve-vehicle-routing-problems-route-optimization-software-and-their-apis/ + +Mordor Intelligence. (2021). Route Optimization Software Market Size. https://www.mordorintelligence.com/industry-reports/route-optimization-software-marketù + +# Contributors + +* Walid El Maouaki +* Francesco Zappulla +* Ruolan Xue +* Dikshant Dulal diff --git a/LoQus/VRP.png b/LoQus/VRP.png new file mode 100644 index 0000000..353efb7 Binary files /dev/null and b/LoQus/VRP.png differ diff --git a/LoQus/VRP_Ham.png b/LoQus/VRP_Ham.png new file mode 100644 index 0000000..43861e1 Binary files /dev/null and b/LoQus/VRP_Ham.png differ diff --git a/LoQus/foperators.png b/LoQus/foperators.png new file mode 100644 index 0000000..fabd5b3 Binary files /dev/null and b/LoQus/foperators.png differ diff --git a/LoQus/fvqe.png b/LoQus/fvqe.png new file mode 100644 index 0000000..318a927 Binary files /dev/null and b/LoQus/fvqe.png differ diff --git a/LoQus/histogram.png b/LoQus/histogram.png new file mode 100644 index 0000000..4e9c376 Binary files /dev/null and b/LoQus/histogram.png differ diff --git a/LoQus/notebooks/Filtering_VQE_VRP.ipynb b/LoQus/notebooks/Filtering_VQE_VRP.ipynb new file mode 100644 index 0000000..b4f581d --- /dev/null +++ b/LoQus/notebooks/Filtering_VQE_VRP.ipynb @@ -0,0 +1,935 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "8cc6d995-3852-4e44-99ad-f355ae584476", + "metadata": {}, + "source": [ + "# Defining the VRP Hamiltonian" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "d077e279-9afd-4168-b7dd-5b56ab90ce34", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: cplex in /opt/conda/lib/python3.8/site-packages (22.1.0.0)\n" + ] + } + ], + "source": [ + "!pip install cplex" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "81be4f12-5353-4d8d-a9f3-75773dc24e81", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + ":219: RuntimeWarning: scipy._lib.messagestream.MessageStream size changed, may indicate binary incompatibility. Expected 56 from C header, got 64 from PyObject\n" + ] + } + ], + "source": [ + "%run -i Hamiltonian_provider.py" + ] + }, + { + "cell_type": "markdown", + "id": "10cfa5be-b446-4acb-a8fc-eb820d407f43", + "metadata": {}, + "source": [ + "In this example, we are going to test the filtering VQE with an instance of the vehicule routing problem with 6 qubits (so that we can run it on the OSLO quantum hardware with 7 qubits)." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "5da2cf9c-bff9-41fb-8e32-514dae688edb", + "metadata": {}, + "outputs": [], + "source": [ + "### Problem definition\n", + "n= 3 # number of nodes + depot (n+1)\n", + "K= 2 # number of vehicles\n", + "b= 0\n", + "H, offset=Hamilton(n,K,b)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "ff7226cf-7a2c-460a-83d1-2aaf380434d6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "78572.82126291405 * IIIIIZ\n", + "+ 78331.99410854303 * IIIIZI\n", + "+ 78572.82126291405 * IIIZII\n", + "- 393.2104562109598 * IIZIII\n", + "+ 78331.99410854303 * IZIIII\n", + "- 393.2104562109598 * ZIIIII\n", + "+ 39321.0456210975 * IIIIZZ\n", + "+ 39321.0456210975 * IIZIZI\n", + "+ 39321.0456210975 * IIZZII\n", + "+ 39321.0456210975 * IZIZII\n", + "+ 39321.0456210975 * ZIIIIZ\n", + "+ 39321.0456210975 * ZZIIII\n" + ] + } + ], + "source": [ + "print(H)" + ] + }, + { + "cell_type": "markdown", + "id": "a7688555-2bed-4080-985f-aac9b8c17542", + "metadata": { + "id": "a7688555-2bed-4080-985f-aac9b8c17542" + }, + "source": [ + "# [Filtering variational quantum algorithms for combinatorial optimization](https://arxiv.org/abs/2106.10055) (Implementation using Qiskit library)\n", + "\n", + "Warning: This code uses a filtering operator that was introduced in the first version of the paper. The other filtering operators are in construction (this notebook will be updated later)...\n", + "\n", + "* The filtering operator: $c1-H$ where $c\\geq E_{max}$ , $E_{max}$ is the maximum eigenvalue of the $Hamiltonian$\n", + "\n", + "* The filtering function: $c-E$ where $c\\geq E_{max}$" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "ed85b5f6-b755-411c-876b-bab2e9370506", + "metadata": { + "id": "ed85b5f6-b755-411c-876b-bab2e9370506" + }, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pandas as pd\n", + "from math import isclose\n", + "from qiskit import QuantumCircuit, execute, Aer\n", + "from scipy.optimize import minimize\n", + "from qiskit.opflow import I, X, Z, Y\n", + "import itertools\n", + "from qiskit.algorithms.optimizers import GradientDescent #,ADAM, CG, GSLS, NELDER_MEAD, NFT, POWELL, SPSA, TNC, COBYLA, L_BFGS_B, SLSQP, AQGD, P_BFGS\n", + "from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister, IBMQ, execute, transpile, Aer, assemble\n", + "from qiskit.tools.monitor import job_monitor" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "faa6a250-392e-4af2-bf42-b900d0b51372", + "metadata": { + "id": "faa6a250-392e-4af2-bf42-b900d0b51372" + }, + "outputs": [], + "source": [ + "def Ansatz(theta,n,l=1):\n", + " m=0\n", + " q=QuantumCircuit(n)\n", + " for i in range(n):\n", + " q.ry(theta[i],i)\n", + " m+=1\n", + " \n", + " for _ in range(l):\n", + " if (n % 2) == 0:\n", + " #Sub Layer1\n", + "\n", + " for i, j in itertools.zip_longest(range(0,n-1,2), range(0,n,1)):\n", + " if i!=None:\n", + " q.cx(i,i+1)\n", + " if j!=None:\n", + " q.ry(theta[m],j)\n", + " m+=1\n", + " #=========================\n", + " #Sub Layer2\n", + "\n", + " for i, j in itertools.zip_longest(range(1,n-2,2), range(1,n-1,1)):\n", + " if i!=None:\n", + " q.cx(i,i+1)\n", + " if j!=None:\n", + " q.ry(theta[m],j)\n", + " m+=1\n", + " else:\n", + " #SubLayer1\n", + "\n", + " for i, j in itertools.zip_longest(range(0,n-1,2), range(0,n-1,1)):\n", + " if i!=None:\n", + " q.cx(i,i+1)\n", + " if j!=None:\n", + " q.ry(theta[m],j)\n", + " m+=1\n", + " #==========================\n", + " #SubLayer2\n", + "\n", + " for i, j in itertools.zip_longest(range(1,n-1,2), range(1,n,1)):\n", + " if i!=None:\n", + " q.cx(i,i+1)\n", + " if j!=None:\n", + " q.ry(theta[m],j)\n", + " m+=1\n", + "\n", + " return q" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "0e1fc45b-1f44-428d-8cab-e222d0178585", + "metadata": { + "id": "0e1fc45b-1f44-428d-8cab-e222d0178585" + }, + "outputs": [], + "source": [ + "def filtering_function6(E, c):\n", + " return (c-E)" + ] + }, + { + "cell_type": "markdown", + "id": "4527dbce-8b7b-4967-b912-22c1dfebfdeb", + "metadata": { + "id": "4527dbce-8b7b-4967-b912-22c1dfebfdeb" + }, + "source": [ + "# Defining the functions to be utilized to solve our problem" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "7a9edf18-cb17-44b2-8872-03a8b62cff55", + "metadata": { + "id": "7a9edf18-cb17-44b2-8872-03a8b62cff55" + }, + "outputs": [], + "source": [ + "# A function to return the eigenvalue if the Pauli Z matrix depending on a binary state e.g. 1101\n", + "def sign(measure,index):\n", + " if not index:\n", + " return 1\n", + " measure=np.array(list(measure))\n", + " p=1\n", + " for b in measure[index]:\n", + " p=p*(-1)**int(b)\n", + " return p\n", + "# A function that returns the count of an executed experiment.\n", + "def count(theta,n,l,shots, hardware=False):\n", + " \n", + " circuit = Ansatz(theta,n,l)\n", + " circuit.measure_all()\n", + " \n", + " if hardware==True:# & already_run==False:\n", + " IBMQ.save_account(\"your API\", overwrite=True) \n", + " provider = IBMQ.load_account()\n", + "\n", + " provider = IBMQ.get_provider(hub='ibm-q', group='open', project='main')\n", + " backend = provider.get_backend('ibm_oslo')\n", + "\n", + " # prepare the circuit for the backend\n", + " mapped_circuit = transpile(circuit, backend=backend)\n", + " qobj = assemble(mapped_circuit, backend=backend, shots=1024)\n", + "\n", + " # execute the circuit\n", + " job = backend.run(qobj)\n", + " job.status()\n", + " jobid=job.job_id()\n", + " job = provider.get_backend('ibm_oslo').retrieve_job(jobid)\n", + " result = job.result()\n", + " counts = result.get_counts()\n", + " # elif hardware==True & already_run==False:\n", + " # job = provider.get_backend('ibm_oslo').retrieve_job(jobid)\n", + " # result = job.result()\n", + " # counts = result.get_counts()\n", + " \n", + " else:\n", + " \n", + " backend = Aer.get_backend('qasm_simulator')\n", + " job = execute(circuit, backend, shots=shots)\n", + " result = job.result()\n", + " counts = result.get_counts()\n", + " return counts\n", + "# A function that returns the expected value of a given filtering operator (or an operator in general)\n", + "def expectation(theta,n,l,H,shots,tau,filtering,power,hardware):\n", + " counts_dict=count(theta,n,l,shots,hardware)\n", + " energies,probabilities=[],[]\n", + " for stri,proba in counts_dict.items():\n", + " sums=0\n", + " for i, coef in enumerate(H.coeffs):\n", + " weight = np.real(coef)\n", + " indices = np.where(H.primitive.table.Z[i])\n", + " sums += weight * sign(stri,indices)\n", + " energies.append(sums)\n", + " probabilities.append(proba)\n", + "###########\n", + "\n", + " F_exp=0\n", + " for i in range(len(energies)):\n", + " if filtering ==True:\n", + " if power==True:\n", + " F_exp+=(probabilities[i]*filtering_function6(energies[i], tau)**2)\n", + " else:\n", + " F_exp+=(probabilities[i]*filtering_function6(energies[i], tau))\n", + " else:\n", + " F_exp+=(probabilities[i]*energies[i])\n", + " if isclose(1.0, sum(probabilities), rel_tol=1e-1, abs_tol=0.0)==False:\n", + " F_exp=F_exp/shots\n", + " \n", + " return F_exp" + ] + }, + { + "cell_type": "markdown", + "id": "16470301-3cd3-458f-a658-36d81aa55445", + "metadata": { + "id": "16470301-3cd3-458f-a658-36d81aa55445" + }, + "source": [ + "# Note:\n", + "\n", + "* `theta`: are the parameters that will be injected in the parametrized circuit\n", + "\n", + "* `n`: are the number of qubits\n", + "\n", + "* `l`: is the number of layers in our ansatz\n", + "\n", + "* `H`: is the Hamiltonian that we want to compute its lower energy\n", + "\n", + "* `shots`: total number of samples\n", + "\n", + "* `tho`: is the hyperparameter existing in each filtering operator. In this notebook $\\tau = c$ for the case of the `filtering_function6`\n", + "\n", + "* `filtering`: determine whether you want to apply the filtering function to the sampled energies\n", + "\n", + "* `power`: determine whether you want to raise the filtering function to the power of 2" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "7384689d-7e66-481a-b33d-07c42dcb6a22", + "metadata": { + "id": "7384689d-7e66-481a-b33d-07c42dcb6a22" + }, + "outputs": [], + "source": [ + "def usual_expectation(n,l,H,shots,hardware):\n", + " def sub_usual_expectation(theta):\n", + " counts_dict=count(theta,n,l,shots,hardware)\n", + " \n", + " energies,probabilities=[],[]\n", + " for stri,proba in counts_dict.items():\n", + " sums=0\n", + " for i, coef in enumerate(H.coeffs):\n", + " weight = np.real(coef)\n", + " indices = np.where(H.primitive.table.Z[i])\n", + " sums += weight * sign(stri,indices)\n", + " energies.append(sums)\n", + " probabilities.append(proba)\n", + " \n", + " \n", + " F_exp=0\n", + " for i in range(len(energies)):\n", + " F_exp+=(probabilities[i]*energies[i])\n", + " if isclose(1.0, sum(probabilities), rel_tol=1e-1, abs_tol=0.0)==False:\n", + " F_exp=F_exp/shots\n", + " \n", + " return F_exp\n", + " return sub_usual_expectation" + ] + }, + { + "cell_type": "markdown", + "id": "cdf2a49b-ad12-4e07-8f97-1d6334cb71c3", + "metadata": { + "id": "cdf2a49b-ad12-4e07-8f97-1d6334cb71c3" + }, + "source": [ + "***" + ] + }, + { + "cell_type": "markdown", + "id": "1199b373-cb7b-42a4-8ace-17de54a59bf2", + "metadata": { + "id": "1199b373-cb7b-42a4-8ace-17de54a59bf2" + }, + "source": [ + "Defining the gradient: $$\n", + "\\left.\\frac{\\partial \\mathcal{C}_{t}(\\boldsymbol{\\theta})}{\\partial \\theta_{j}}\\right|_{\\boldsymbol{\\theta}_{t-1}}=-\\frac{\\left\\langle F_{t}\\right\\rangle_{\\psi_{t-1}^{j+}}-\\left\\langle F_{t}\\right\\rangle_{\\psi_{t-1}^{j-}}}{4 \\sqrt{\\left\\langle F_{t}^{2}\\right\\rangle_{\\psi_{t-1}}}}\n", + "$$" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "8a2c7181-8779-422c-b8b2-5aa39e8eff32", + "metadata": { + "id": "8a2c7181-8779-422c-b8b2-5aa39e8eff32" + }, + "outputs": [], + "source": [ + "def gradient(tho,n,l,F_op,shots, hardware):\n", + " def sub_gradient(thetas):\n", + " list_gradient=[]\n", + " dominator=(4*np.sqrt(expectation(thetas,n,l,F_op,shots,tho,True,True,hardware)))\n", + " for j in range(len(thetas)):\n", + "\n", + " theta_n=np.array(thetas)\n", + " theta_n[j]=theta_n[j]-np.pi/2\n", + " theta_p=np.array(thetas)\n", + " theta_p[j]=theta_p[j]+np.pi/2\n", + "\n", + " grad=((expectation(theta_p,n,l,F_op,shots,tho,True,False,hardware)-expectation(theta_n,n,l,F_op,shots,tho,True,False,hardware)))/dominator\n", + "\n", + " list_gradient.append(grad)\n", + " return np.array(list_gradient)\n", + " return sub_gradient" + ] + }, + { + "cell_type": "markdown", + "id": "96a06b3b-a7be-4bea-b39f-1e8fc9bf3de7", + "metadata": { + "id": "96a06b3b-a7be-4bea-b39f-1e8fc9bf3de7" + }, + "source": [ + "***" + ] + }, + { + "cell_type": "markdown", + "id": "d1b3eacf-dee0-441b-a90f-e60e95f0ea6e", + "metadata": { + "id": "d1b3eacf-dee0-441b-a90f-e60e95f0ea6e" + }, + "source": [ + "Testing with a 6 qubits hamiltonian which corresponds to a Traveling salesman problem with one vehicle and n=3 nodes. no. required=$(n-1)^2$" + ] + }, + { + "cell_type": "markdown", + "id": "2c84b936-7966-4b48-b709-09d76c32c523", + "metadata": { + "id": "2c84b936-7966-4b48-b709-09d76c32c523" + }, + "source": [ + "# Classical Solution" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "aef533bd-42f5-400e-8af4-c98bc6977d38", + "metadata": { + "id": "aef533bd-42f5-400e-8af4-c98bc6977d38", + "outputId": "74de2f58-0325-451c-939e-2f27dfbf2862" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The maximum eigenvalue= 548949.4835570772\n", + "The minimum eigenvalue= -393238.14289753104\n" + ] + } + ], + "source": [ + "# Here we get the value of the lower eigenvalue which will be our reference value, and also find the maximum eigenvalue to determine the constant c.\n", + "#H=eval(convert_hamiltonian('Hamiltonian.txt'))\n", + "#F=1800909*(I^I^I^I^I^I^I^I^I)-H\n", + "a=H.to_matrix()\n", + "w, v =np.linalg.eig(a)\n", + "E_max,E_min=np.real(max(w)),np.real(min(w))\n", + "print(r'The maximum eigenvalue=',E_max)\n", + "print(r'The minimum eigenvalue=',E_min)" + ] + }, + { + "cell_type": "markdown", + "id": "49c736a9-655b-4f7d-a08e-963e5298ab5d", + "metadata": { + "id": "49c736a9-655b-4f7d-a08e-963e5298ab5d" + }, + "source": [ + "***" + ] + }, + { + "cell_type": "markdown", + "id": "97e8dc0b-844e-48dd-b734-b42fab96d045", + "metadata": { + "id": "97e8dc0b-844e-48dd-b734-b42fab96d045" + }, + "source": [ + "# Filtering VQE Solution" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "362464ab-a4ae-4adc-b3d0-b44fb536fcc2", + "metadata": { + "id": "362464ab-a4ae-4adc-b3d0-b44fb536fcc2" + }, + "outputs": [], + "source": [ + "fvqe_cost, fvqe_iter=[],[]\n", + "def callback(nfevs, x_next, cost, stepsize):\n", + " fvqe_cost.append(cost)\n", + " fvqe_iter.append(nfevs)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "cfe12962-8314-4527-9d8c-f7a4fb17b172", + "metadata": { + "id": "cfe12962-8314-4527-9d8c-f7a4fb17b172", + "outputId": "49d523b2-6c03-4efc-aea4-94a05083cc05" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{ 'fun': -392860.4281422653,\n", + " 'jac': None,\n", + " 'nfev': 150,\n", + " 'nit': None,\n", + " 'njev': None,\n", + " 'x': array([ 0.53067355, 1.6282146 , 1.7173211 , 1.57099924, 1.57622531,\n", + " 1.57274696, -0.53300268, 1.38945878, 0.122506 , 0.98412565,\n", + " -0.01315273, 1.57076669, 0.13127512, -1.29911239, 0.58573076,\n", + " 1.56354416])}\n", + "\n", + "CPU times: user 4min 58s, sys: 1.82 s, total: 5min\n", + "Wall time: 5min 4s\n" + ] + } + ], + "source": [ + "%%time\n", + "\n", + "num_qubits,layers,shots,c=H.num_qubits,1,5000,E_max+1\n", + "Filtering_op = c * (I^H.num_qubits) - H\n", + "\n", + "theta= np.array([*((np.pi/2)*np.ones(num_qubits)),*(np.zeros(2*(num_qubits-1)*layers))])\n", + "optimizer = GradientDescent(maxiter=150,learning_rate=1.0,callback = callback)\n", + "obj=usual_expectation(num_qubits, layers, H, shots, hardware=False)\n", + "\n", + "grad_fun=gradient(c, num_qubits, layers, Filtering_op, shots, hardware=False)\n", + "res=optimizer.minimize(fun=obj, x0=theta,jac=grad_fun)\n", + "\n", + "\n", + "print(res)\n", + "print()" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "b5e0a97c-4136-47a2-9825-67f3fb7dbe03", + "metadata": { + "id": "b5e0a97c-4136-47a2-9825-67f3fb7dbe03", + "outputId": "24d1671c-c9bd-4de0-bf8a-0c949cd596a6" + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAmUAAAFzCAYAAAB/6H48AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAA89ElEQVR4nO3deXxcZdnG8d89WzLZm+5NV6CUtRQIm8omoC37qyytiBbBKghuiIIIbwXEDZdXRaGCgIgUxIWqQJUC4sLSFkqhhUIplW50o2uSJpnM/f4x0zLZ2mQymZkk1/fzGZg558yZOyenyZXnec5zzN0RERERkdwK5LoAEREREVEoExEREckLCmUiIiIieUChTERERCQPKJSJiIiI5AGFMhEREZE8EMp1AV01YMAAHz16dK7LEBEREdmj+fPnb3D3gW2t6/GhbPTo0cybNy/XZYiIiIjskZn9t7116r4UERERyQMKZSIiIiJ5QKFMREREJA8olImIiIjkAYUyERERkTzQ46++FBER6cu2bt3KunXraGxszHUpfV44HGbQoEGUlZWl9X6FMhERkR5q69atrF27lqqqKqLRKGaW65L6LHenrq6OVatWAaQVzNR9KSIi0kOtW7eOqqoqioqKFMhyzMwoKiqiqqqKdevWpbUPhTIREZEeqrGxkWg0musyJEU0Gk27K1mhTEREpAdTC1l+6cr3Q6FMREREJA8olHVSY1OcxqZ4rssQERGRXkahrJMu/+0LzHl1ba7LEBER6RWmT5+OmbV6nHzyybt93xVXXEH//v3bHb91yy23EAwGWb169a5lixYt4vzzz2fQoEEUFhYybtw4vvnNb1JXV9fsvU899VSbNZkZl1xySde/6HZoSoxOKikIs21HLNdliIiI9Brl5eU89thjrZbtzpQpU/jZz37G3/72N0477bRW62fOnMnxxx/PsGHDAHjyySc57bTTmDBhAj/96U8ZMmQI8+bN4+abb2b27Nk8/vjjFBUVNdvHfffdx1577dVs2aBBg9L5EjtEoayTSgtDCmUiIiIZFAqFOProozv1nmOOOYZRo0Yxc+bMVqFs6dKlzJ8/nxkzZgBQW1vLBRdcwOGHH84TTzxBOBwG4Pjjj+eUU07h8MMPZ/r06Xzve99rtp/x48dz0EEHdeEr6xx1X3ZSSUGI7fUKZSIiIrlkZkyePJmHH36YHTt2NFs3c+ZMwuEwH/3oRwH43e9+x5o1a/jWt761K5DtNH78eD7+8Y9z++23t9pPtimUdVJJoUKZiIhIpsVisWYPd9/je6ZMmcK2bdv461//2mz5zJkz+fCHP0xlZSUATz/9NP369eO4445rcz9nn302W7du5cUXX2y2vKmpKa260qVQ1kklBeq+FBERyaSNGzcSDoebPebMmbPH9x1yyCHsv//+zJw5c9eyV155hUWLFjFlypRdy1atWsWoUaPa3c/OdStXrmy2fMKECa3quueeezr75XWYxpR1UqlaykREJM+Nvvqve96omyz/TutB93tSXl7O448/3mzZuHHjOvTeKVOm8O1vf5vt27dTUlLCAw88QFFREWeddVan62g58evMmTPZe++9my0bM2ZMp/fbUQplnVRSEGL7jvRunyAiIpIN6QSjXAqFQlRXV6f13ilTpnD99dcza9YsPvaxj/HAAw9wxhlnUFxcvGubqqoqnn/++Xb38d///heAoUOHNlt+4IEHaqB/PtNAfxERkfyxzz77UF1dzcyZM5k/fz5vvPFGs65LSFxluWnTJv71r3+1uY9Zs2ZRVFTEhAkTslBx+xTKOqlEU2KIiIjklSlTpjB79mxuu+02KioqmDRpUrP155xzDkOHDuXaa68lFmv+O/yVV17h3nvv5dxzz23WupYL6r7spNKCsFrKRERE8sj555/PVVddxZ133slFF11EJBJptr6oqIj77ruP0047jRNOOIHPf/7zDB48mPnz53PzzTczdOhQfvjDH7ba78KFC9m+fXuzZeXl5ey///7d8nUolHWSpsQQERHJL1VVVRx77LH84x//aNV1udOJJ57I888/zw033MDnPvc5Nm7ciLvz/ve/nz/96U+7ps9IdcEFF7RadtJJJ7W6KCFTrDvn28iG6upqnzdvXtY+rz7WxIHXz+aNb01qdZWGiIhINr366qvd1mrTF3ziE59g1qxZPPPMMxk9jrv7vpjZfHdv86oGjSnrpIJQkEDAqI/Fc12KiIiIdMGMGTMYN24cp556KuvWrct1Oeq+TEdpcgLZwnAw16WIiIj0SvF4nHi8/QaQYDDY5R6rwsJCnnvuuS7tI5PUUpYGjSsTERHpXjfccEOr2fRTH//4xz9yXWLGqaUsDYkJZBXKREREusu0adM4/fTT213f0Rn/exKFsjSUFITY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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# A function to normalize the cost values\n", + "def normalize(list, exact):\n", + " lis=[abs(exact-list[i])/abs(exact) for i in range(len(list))]\n", + " return lis\n", + "\n", + "plt.rcParams['figure.figsize'] = (10, 6)\n", + "plt.plot(fvqe_iter,normalize(fvqe_cost,E_min), linewidth=1, label='F_VQE')\n", + "plt.plot(range(0, 150), 0.0*np.ones(150), 'k--', linewidth=1.5, label='E_0')\n", + "\n", + "plt.xlabel('Number of iterations')\n", + "plt.ylabel(r'$|E_{exact}-E|/|E_{exact}|$')\n", + "plt.legend(loc='upper right', fontsize=15)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "7f43a897-140e-4cb8-88ec-f72904540955", + "metadata": { + "id": "7f43a897-140e-4cb8-88ec-f72904540955" + }, + "source": [ + "As we can see, the Filtering VQE approach performs pretty well in finding the lowest energy of our Hamiltonian with a few number of iterations. I utilized the Filtering operator $c1-H$, which has the disadvantage of requiring the maximum eigenvalue of the Hamiltonian which with itself require a separate calculation using for instance the Subspace search VQE. However, there are other filtering operators which don't have this constraint and rely on a parameter $\\tau$ to be dynamically updated after each iteration. To name one: the inverse Filtering operator $H^{-\\tau}$ discussed in [this paper](https://www.nature.com/articles/s41534-019-0239-7). As mentioned this notebook will be updated with new filtering operators tested." + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "607a964e-4492-4772-b51b-ecd6c1306f47", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAc0AAAFrCAYAAACzANLuAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAmNUlEQVR4nO3de5hVZ3n38e8tmAkRUCAC4RABIWjAkOBEQkog+krToI2tsSZWTamHNFETD9VW33rCqrXW5jXVplba5qRGW1u11RywKiDJZOKAooAltEAaCAcTiIAhQ8D7/WPtwZ1xDmuTYfYM8/1c175m72c9a+17Z2fx2+v0rMhMJElS955W7wIkSeovDE1JkkoyNCVJKsnQlCSpJENTkqSSDE1JkkoyNKUTXERMioiMiMHHOP9rI2JZT9cl9UeGptSPRMS8iLgnIn4eEXsi4u6IOLcHl/9rAZuZX8zM3+yp95D6s2P65Smp90XEcOCbwNXAPwMnARcArfWsSxpI3NKU+o8zADLztsw8kpkHM3NZZv44Ip4WEe+PiAciYndE3BIRz+xoIRGxNSJeWvX6wxHxhcrLlZW/j0bEgYiYGxGLI2JVVf/zI+IHla3dH0TE+VXTlkfEn1e2gPdHxLKIOLXn/1NI9WFoSv3H/cCRiLg5Ii6OiBFV0xZXHi8GpgBDgc8ew3vMr/x9VmYOzcym6okRMRL4FvA3wCjgOuBbETGqqtvvA38IjKbYGn73MdQh9UmGptRPZOY+YB6QwFLgZxHx7xExBngtcF1mbs7MA8D7gMuP9eSfLrwM2JSZt2bm4cy8Dfgv4Ler+tyYmfdn5kGK3chn93ANUt0YmlI/kpk/zczFmTkBmAmMAz5d+ftAVdcHKM5ZGNPDJbR/n7b3Gl/1emfV88cotnqlE4KhKfVTmflfwE0U4fkQ8JyqyacDh4FdHcz6C+CUqtdjqxfbzdu2f5+299refcVS/2doSv1ERDwvIv44IiZUXk8EXgPcC9wGvDMiJkfEUODjwFcy83AHi/oRxa7bp0dEI/Cqqmk/A35JcVy0I7cDZ0TE70fE4Ii4DDiT4qxe6YTnJSdS/7EfmAO8KyKeBTxKEVbvAQ5Q7DpdCZwM3AVc08lyPkARsnuBFcCXgJEAmflYRHwMuDsing78VvWMmflIRLwcuB74O+C/gZdn5sM99imlPiy8CbUkSeW4e1aSpJIMTUmSSjI0JUkqydCUJKmkAX327KmnnpqTJk2qdxmSpD5k9erVD2fmszuaNqBDc9KkSbS0tNS7DElSHxIR7Ue9Osrds5IklWRoSpJUkqEpSVJJhqYkSSUZmpIklWRoSpJUkqEpSVJJhqYkSSUZmpIklWRoSpJUkqEpSVJJhqYkSSUZmpIklWRoSpJUkqEpSVJJhqYkSSUZmpIklWRoSpJUkqEpSVJJhqYkSSUZmpIklWRoSpJUkqEpSVJJhqYk9RNveMMbGD16NDNnzuxwemZy7bXXMnXqVM466yzWrFlzdNrNN9/MtGnTmDZtGjfffPPR9tWrV/OCF7yAqVOncu2115KZx/1z9GeGpiT1E4sXL+bOO+/sdPodd9zBpk2b2LRpE5///Oe5+uqrAdizZw9LliyhubmZ++67jyVLlrB3714Arr76apYuXXp0vq6WL0NTkvqN+fPnM3LkyE6nf+Mb3+CKK64gIjjvvPN49NFH2bFjB3fddRcLFy5k5MiRjBgxgoULF3LnnXeyY8cO9u3bx3nnnUdEcMUVV/D1r3+99z5QP2RoStIJYvv27UycOPHo6wkTJrB9+/Yu2ydMmPBr7eqcoSlJUkmGpiSdIMaPH8+DDz549PW2bdsYP358l+3btm37tXZ1ztCUpBPEJZdcwi233EJmcu+99/LMZz6T0047jYsuuohly5axd+9e9u7dy7Jly7jooos47bTTGD58OPfeey+ZyS233MIrXvGKen+MPm1wvQuQJJXzmte8huXLl/Pwww8zYcIElixZwhNPPAHAVVddxaJFi7j99tuZOnUqp5xyCjfeeCMAI0eO5AMf+ADnnnsuAB/84AePnlB0ww03sHjxYg4ePMjFF1/MxRdfXJ8P10/EQL4mp7GxMVtaWupdhiSpD4mI1ZnZ2NE0d89KklSSoSlJUkmGpiRJJRmakiSVZGhKklSSoSlJUkmGpiRJJRmakiSV1KuhGRHzI+LfI2J7RGRELC4xzwsiYkVEHKzM98GIiHZ9Lo2IDRHRWvn7u8ftQ0iSBqze3tIcCqwD3g4c7K5zRAwHvg3sAs6tzPce4F1VfeYCXwG+CJxd+fsvETGnh2uXJA1wvTr2bGbeDtwOEBE3lZjltcApwB9k5kFgXUQ8D3hXRFyXxRiA7wC+l5kfq8zzsYh4caX9NT37CSRJA1lfP6Y5F/h+JTDb3AWMAyZV9VnWbr67gPOPe3WSpAGlr9/lZCywrV3brqppWyp/d3XQZ2xHC4yIK4ErAcaNG8fy5csBmDJlCsOGDWPt2rUAjBo1ihkzZrBy5UoABg8ezLx581izZg379u0DoLGxkV27dh29T920adNoaGhg3bp1AIwePZozzjiDVatWAdDQ0MDcuXNpaWnhwIEDAMyZM4dt27YdvVv69OnTGTRoEBs2bCg+5NixTJ48maamJgCGDBnCnDlzaG5u5uDB4rfE3Llz2bJlCzt37gTgzDPP5MiRI2zcuBEo7rE3YcIEmpubARg6dCiNjY00NTXR2toKwLx587j//vvZvXs3ADNnzqS1tZVNmzYBMHHiRMaMGUPbAPfDhw9n9uzZrFq1isOHDwMwf/581q9fzyOPPALArFmz2L9/P5s3bwZg0qRJjBw5kjVr1gAwYsQIZs2axYoVK8hMIoIFCxawdu1a9u7dC8Ds2bPZs2cPW7du9Xvye+qx7+nkT5yMTjwPXflQj6xPXanbXU4i4gDwtsy8qYs+y4BtmfmGqrbTgQeA8zOzKSIOAW/KzFuq+lwBLM3Mhq5q8C4n0sAUS6L7Tup38kM9k2f9+S4nO4Ex7drGVE3rqs9OJEnqQX09NJuACyKiel/KQuAhYGtVn4Xt5lsI3HPcq5MkDSi9fZ3m0Ig4OyLOrrz36ZXXp1em/0VEfKdqli8BjwE3RcTMiHgl8F6g7cxZgOuBl0TEeyPieRHxPuDFwKd76WNJkgaI3t7SbAR+WHkMAZZUnn+kMv004LltnTPz5xRbjeOAFuBvgb8Grqvqcw9wObAY+DFwBXBZZjYf348iSRpoevs6zeVAp0fgM3NxB20/AeZ3s9yvAl99iuVJktSlvn5MU5KkPsPQlCSpJENTkqSSDE1JkkoyNCVJKsnQlCSpJENTkqSSDE1JkkoyNCVJKsnQlCSpJENTkqSSDE1JkkoyNCVJKsnQlCSpJENTkqSSDE1JkkoyNCVJKsnQlCSpJENTkqSSDE1JkkoyNCVJKsnQlCSpJENTkqSSDE1JkkoyNCVJKsnQlCSpJENTkqSSDE1JkkoyNCVJKsnQlCSpJENTkqSSDE1JkkoyNCVJKsnQlCSpJENTkqSSDE1JkkoyNCVJKsnQlCSpJENTkqSSDE1JkkoyNCVJKsnQlCSpJENTkqSSDE1JkkqqKTQj4mkR8bSq12Mj4k0R8Rs9X5okSX1LrVua3wKuAYiIoUAL8FfA8oi4oodrkySpT6k1NBuB71aevxLYB4wG3gy8u8wCIuItEbElIh6PiNURcUEXfW+KiOzg8YuqPhd20ud5NX42SZK6VGtoDgUerTz/TeBrmfkERZA+t7uZI+Iy4Hrg48A5wD3AHRFxeiezvB04rd1jM/DPHfSd0a7fplKfSJKkkmoNzf8FfiMingFcBHy70j4SeKzE/O8CbsrMpZn508y8BtgBXN1R58z8eWbubHtQBPMUYGkH3XdX983MIzV+NkmSujS4xv7XAbcCB4AHgJWV9vnAT7qaMSJOAl4IfKrdpGXA+SXf/83A+sy8p4NpLRHRAGwAPpqZ3+ukjiuBKwHGjRvH8uXLAZgyZQrDhg1j7dq1AIwaNYoZM2awcmXxEQcPHsy8efNYs2YN+/btA6CxsZFdu3bx4IMPAjBt2jQaGhpYt24dAKNHj+aMM85g1apVADQ0NDB37lxaWlo4cOAAAHPmzGHbtm1s374dgOnTpzNo0CA2bNgAwNixY5k8eTJNTU0ADBkyhDlz5tDc3MzBgwcBmDt3Llu2bGHnzp0AnHnmmRw5coSNGzcCMH78eCZMmEBzczMAQ4cOpbGxkaamJlpbWwGYN28e999/P7t37wZg5syZtLa2smlTscE+ceJExowZQ0tLCwDDhw9n9uzZrFq1isOHDwMwf/581q9fzyOPPALArFmz2L9/P5s3bwZg0qRJjBw5kjVr1gAwYsQIZs2axYoVK8hMIoIFCxawdu1a9u7dC8Ds2bPZs2cPW7du9Xvye+qx70knph07dvTI+tSVyMyaioqIRmAi8O3MPFBpexnwaGbe3cV844DtwILMXFnV/kHgtZk5vZv3fSbFVun7MvP6qvbpwIuBHwAnAa8Hrqq8z/e7WmZjY2O2/eMiaeCIJVHvEnQc5Idqy7PORMTqzGzsaFqtW5pkZgvFWbPVbd86xtpq8TqK3cm3tnvvjcDGqqamiJgEvAfoMjQlSapFzYMbVM5+XR8Rj0XElErbn0bEq7uZ9WHgCDCmXfsYYGeJt34z8K+ZuadE32ZgWol+kiSVVuvgBu8A3g98Hqjev/EQ8Lau5s3MQ8BqYGG7SQspzqLt6n1fBMyi4xOAOnI2xa5cSZJ6TK27Z68C3pyZ34qIj1a1r6G45KM71wG3RsR9wN2V5Y0DPgcQEbcAZGb7gRKuBDZl5vL2C6wE+VZgPcUxzdcBvwNcWvIzSZJUSq2h+RxgXQftTwBDups5M78SEaMotlZPqyxrUWY+UOnya9drRsQw4HLgI50s9iSKUYkmAAcpwvNlmXl7d/VIklSLWkNzMzCb4nKTaosoLvXoVmbeANzQybQLO2jbTzGoQmfL+yTwyTLvLUnSU1FraH4K+GxEnEJxTHNuRLwe+BPgDT1dnCRJfUlNoZmZN0bEYIph8E6huPzjIeDazPzKcahPkqQ+41iu01wKLI2IU4GnZebuni9LkqS+p+bQbJOZD/dkIZIk9XXdhmZE/JhiSLq9EfEToNNxijLzrJ4sTpKkvqTMlua/Aq1Vz3tmcD9JkvqZbkMzM5dUPf/wca1GkqQ+rNZh9L4bEc/qoH14RHy3x6qSJKkPqnXA9gspRuBp72TggqdcjSRJfVips2cjYnbVy7MiovpOI4OAiyjulSlJ0gmr7CUnLRQnACWwrIPpB4FreqooSZL6orKhOZli2LzNwIuAn1VNOwTszswjPVybJEl9SqnQrLoLSc03rZYk6URRZnCDVwL/kZlPVJ53KjP/rccqkySpjymzpflVYCywu/K8M0lxUpAkSSekMoMbPK2j55IkDTSGoCRJJZU9plmKxzQlSSeyssc0y/CYpiTphFbTMU1JkgYyA1GSpJK8TlOSpJK8TlOSpJK8TlOSpJIMQUmSSqo5NCNidkTcEhEtlcet7e63KUnSCamm0IyI1wI/AE4Dbq88xgD3RcTrer48SZL6jrL302zzMeADmfnx6saIeB/wUeALPVWYJEl9Ta27Z58N/HMH7f8CjH7q5UiS1HfVGprfAy7soP1CYMVTLUaSpL6s1gHb7wD+IiIagXsrbecBrwQ+3OPVSZLUhxzrgO1XVh7VPgPc8JQrkiSpj3LAdkmSSjIQJUkqqdZLToiIEcDFwOnASdXTMvMjPVSXJEl9Tk2hGRHnAd8CWikuP9lOMdBBK7AVMDQlSSesWnfP/hXwRWA88DjwEootzhbgL3u2NEmS+pZaQ/Ms4LOZmcARoCEzdwF/ipecSJJOcLWG5qGq57uA51SeHwDG9UhFkiT1UbWeCLQGOBe4H1gOfDQixgCvA37cs6VJktS31Lql+WfAQ5Xn7wd+RjGowQh+fbADSZJOKDVtaWZmS9Xzn1FceiJJ0oBQ83WaABHxXOD5lZcbMnNzz5UkSVLfVOt1mqOAfwQuAX75q+b4JvCGzHykh+uTJKnPqPWY5j8AU4ELgJMrj/nAZGBpz5YmSVLfUmtoXgS8OTPvzszDlcfdwB9VpnUrIt4SEVsi4vGIWB0RF3TR98KIyA4ez2vX79KI2BARrZW/v1vj55IkqVu1hubPgF900P4Y0O2u2Yi4DLge+DhwDnAPcEdEnN7NrDMohutre2yqWuZc4CsUIxWdXfn7LxExp7t6JEmqRa2h+RHg0xExvq2h8vyvKTfu7LuAmzJzaWb+NDOvAXYAV3cz3+7M3Fn1OFI17R3A9zLzY5VlfoziGtJ3lP5UkiSV0O2JQBHxEyCrmiYDWyNie+V12zi0oymOeXa2nJOAFwKfajdpGXB+N2W0REQDsAH4aGZ+r2raXIprRavdBbytm2VKklSTMmfPfrWH3utUYBDF8HvVdgEv7WSetq3QH1Dchuz1wHciYkFmfr/SZ2wnyxzb0QIj4koqAzGMGzeO5cuXAzBlyhSGDRvG2rVrARg1ahQzZsxg5cqVAAwePJh58+axZs0a9u3bB0BjYyO7du3iwQcfBGDatGk0NDSwbt06AEaPHs0ZZ5zBqlWrAGhoaGDu3Lm0tLRw4MABAObMmcO2bdvYvr34DTJ9+nQGDRrEhg0big83diyTJ0+mqakJgCFDhjBnzhyam5s5ePAgAHPnzmXLli3s3LkTgDPPPJMjR46wceNGAMaPH8+ECRNobm4GYOjQoTQ2NtLU1ERraysA8+bN4/7772f37t0AzJw5k9bWVjZtKvaET5w4kTFjxtDSUlyqO3z4cGbPns2qVas4fPgwAPPnz2f9+vU88kixp37WrFns37+fzZuLK5ImTZrEyJEjWbNmDQAjRoxg1qxZrFixgswkIliwYAFr165l7969AMyePZs9e/awdetWvye/px77nnRi2rFjR4+sT12JYuz14y8ixlHcSmxBZq6sav8g8NrMnF5yObcDhzPzksrrQ8CbMvOWqj5XAEszs6GrZTU2NmbbPy6SBo5YEvUuQcdBfqhn8iwiVmdmY0fTjnVwg5cAZ1Lstl2fmctLzPYwxZ1RxrRrHwPsrOHtm4HLq17v7IFlSpLUrZpOBIqI8RFxH/BtituBvZdid2lzZUuyU5l5CFgNLGw3aSHFWbRlnU2x27ZNUw8sU5KkbtW6pfk3FFuLUzNzC0BETAG+UJn2qm7mvw64tRK8dwNXUdxS7HOVZd0CkJlXVF6/A9gKrKc4pvk64HeAS6uWeT2wMiLeC3wd+F3gxcC8Gj+bJEldqjU0FwIXtgUmQGZujohrge90N3NmfqUyFN/7Ka63XAcsyswHKl3aX695EvBXwATgIEV4viwzb69a5j0RcTnwUYrLXv4HuCwzm2v8bJIkdelYjml2dKS19NHXzLwBuKGTaRe2e/1J4JMllvlVeu4sX0mSOlTr4AbfAT4TERPbGiqj+XyaEluakiT1Z7WG5rXAM4DNEfFARDxAsTv0GZVpkiSdsGrdPfsI8CLgQqBt0PSfZuZ/9mRRkiT1RaVDMyIGAT8HZmXmtykuO5EkacAovXu2Mkj6AxRntEqSNODUekzzz4FPRMSpx6MYSZL6slqPab6b4i4n2yNiG+3urZmZZ/VUYZIk9TW1huZXKa7JdLRjSdKAUyo0I+IUipF5fgd4OsU1mddk5sPHrzRJkvqWssc0lwCLgW8Bt1Hc//LvjlNNkiT1SWV3z74SeGNmfhkgIr4I3B0Rgypn1UqSdMIru6U5Efh+24vMvA84THGHEkmSBoSyoTkIONSu7TDHeBNrSZL6o7KhF8AXIqK1qu1kYGlEPNbWkJmX9GRxkiT1JWVD8+YO2r7Qk4VIktTXlQrNzPzD412IJEl9Xa3D6EmSNGAZmpIklWRoSpJUkqEpSVJJhqYkSSUZmpIklWRoSpJUkqEpSVJJhqYkSSUZmpIklWRoSpJUkqEpSVJJhqYkSSUZmpIklWRoSpJUkqEpSVJJhqYkSSUZmpIklWRoSpJUkqEpSVJJhqYkSSUZmpIklWRoSpJUkqEpSVJJhqYkSSUZmpIklWRoSpJUkqEpSVJJhqYkSSUZmpIkldTroRkRb4mILRHxeESsjogLuuj7yohYFhE/i4j9EdEcEZe067M4IrKDx8nH/9NIkgaSXg3NiLgMuB74OHAOcA9wR0Sc3sksC4DvAi+r9L8d+FoHQfsYcFr1IzMf7/lPIEkayAb38vu9C7gpM5dWXl8TEb8FXA28r33nzHx7u6YlEfEy4HeA7z+5a+48DvVKknRUr21pRsRJwAuBZe0mLQPOr2FRw4C97dqGRMQDEbEtIr4ZEec8hVIlSepQb25pngoMAna1a98FvLTMAiLircAE4Naq5o3AG4C1FIH6duDuiJiVmZs6WMaVwJUA48aNY/ny5QBMmTKFYcOGsXbtWgBGjRrFjBkzWLlyJQCDBw9m3rx5rFmzhn379gHQ2NjIrl27ePDBBwGYNm0aDQ0NrFu3DoDRo0dzxhlnsGrVKgAaGhqYO3cuLS0tHDhwAIA5c+awbds2tm/fDsD06dMZNGgQGzZsAGDs2LFMnjyZpqYmAIYMGcKcOXNobm7m4MGDAMydO5ctW7awc2exsX3mmWdy5MgRNm7cCMD48eOZMGECzc3NAAwdOpTGxkaamppobW0FYN68edx///3s3r0bgJkzZ9La2sqmTcV/wokTJzJmzBhaWloAGD58OLNnz2bVqlUcPnwYgPnz57N+/XoeeeQRAGbNmsX+/fvZvHkzAJMmTWLkyJGsWbMGgBEjRjBr1ixWrFhBZhIRLFiwgLVr17J3b/G7aPbs2ezZs4etW7f6Pfk99dj3pBPTjh07emR96kpk5nH8CFVvFDEO2A4syMyVVe0fBF6bmdO7mf9SirC8LDP/o4t+g4AfAd/LzGu7WmZjY2O2/eMiaeCIJVHvEnQc5Id6Js8iYnVmNnY0rTdPBHoYOAKMadc+BujyeGREvIoiMK/oKjABMvMI0AJMO/ZSJUn6db0Wmpl5CFgNLGw3aSHFWbQdiohXUwTm4sz8anfvExEBnAXsOPZqJUn6db199ux1wK0RcR9wN3AVMA74HEBE3AKQmVdUXl9OEZjvBlZGxNjKcg5l5p5Knw8B9wKbgOHAtRSheXUvfSZJ0gDRq6GZmV+JiFHA+ymup1wHLMrMBypd2l+veRVFjZ+uPNqsAC6sPH8W8HlgLPBz4IfA/My8r8c/gCRpQOvtLU0y8wbghk6mXdjV607meSfwzp6oTZKkrjj2rCRJJRmakiSVZGhKklSSoSlJUkmGpiRJJRmakiSVZGhKklSSoSlJUkmGpiRJJRmakiSVZGhKklSSoSlJUkmGpiRJJRmakiSVZGhKklSSoSlJUkmGpiRJJRmakiSVZGhKklSSoSlJUkmGpiRJJRmakiSVZGhKklSSoSlJUkmGpiRJJRmakiSVZGhKklSSoSlJUkmGpiRJJRmakiSVZGhKklSSoSlJUkmGpiRJJRmakiSVZGhKklSSoSlJUkmGpiRJJRmakiSVZGhKklSSoSlJUkmGpkq78847mT59OlOnTuUTn/hEvcuRpF5naKqUI0eO8Na3vpU77riDDRs2cNttt7Fhw4Z6lyVJvcrQVCn33XcfU6dOZcqUKZx00klcfvnlfOMb36h3WZLUqwxNlbJ9+3YmTpx49PWECRPYvn17HSuSpN5naEqSVFKvh2ZEvCUitkTE4xGxOiIu6Kb/gkq/xyNic0Rc9VSXqdqNHz+eBx988Ojrbdu2MX78+DpWJEm9r1dDMyIuA64HPg6cA9wD3BERp3fSfzJwe6XfOcBfAJ+JiEuPdZk6Nueeey6bNm1iy5YtHDp0iC9/+ctccskl9S5LknpVb29pvgu4KTOXZuZPM/MaYAdwdSf9rwIeysxrKv2XAjcD734Ky9QxGDx4MJ/97Ge56KKLeP7zn8+rX/1qZsyYUe+yJKlXDe6tN4qIk4AXAp9qN2kZcH4ns82tTK92F/AHEfF0II5hmTpGixYtYtGiRfUuQ5LqptdCEzgVGATsate+C3hpJ/OMBf6zg/6DK8uLWpcZEVcCV1ZeHoiIjWWK11GnAg/XuwhJpQ2YdTY+HD21qOd0NqE3Q7NPyMzPA5+vdx39VUS0ZGZjveuQVI7rbM/qzdB8GDgCjGnXPgbY2ck8Ozvpf7iyvDiGZUqSdEx67USgzDwErAYWtpu0kOKM1440ddK/JTOfOMZlSpJ0THp79+x1wK0RcR9wN8XZseOAzwFExC0AmXlFpf/ngLdFxKeBvwd+A1gMvKbsMtXj3LUt9S+usz0oMrN33zDiLcCfAKcB64B3ZubKyrTlAJl5YVX/BcD/A2YADwF/mZmfK7tMSZJ6Sq+HpiRJ/ZVjz0qSVJKhKUlSSYamJEklGZqSJJVkaErSABER0fY3Ivz3/xj4H01PSdtKKKnvy8yMiKdn4Zdt7a7H5XnJiXpE20qX/g8l9UkRMQl4NTCTYgCYZcDXMnNTPevqb9zS1DGJiIaIeEVlRaTyyzUr0/z/SupDImI4cAvFfYYHUYzN/RbgpxGxIiL+Tz3r608G3F1O1GPeCPwlcEdErAZ+AKzLzN1tu30iYhTwCuALlXGCJdXH1cApwDmZ+WhEnAIMBeYAfwT8XUS8JzO/Uc8i+wN3z+qYRMT3gF8CjwIvAH4B/BhophKgwOXAhzJzUn2qlAQQEV8DHsrMt7ZrD4q7Qv01cC5wQWa2vz+xqrgbTTWrbEEG8KXMvBR4CcWun4nAu4DrKbZC/xz4t3rVKemobwKXRMTk6sbKUZWdFGN3/wI4px7F9SduaapmETEUuAjYl5nfbjftbOAy4OUUg+xPysz/7fUiJR0VEeOBrwAnU9wxagWwJTOfqEyfCvwEODMzt9St0H7A0NQxiYgGiv9/Ho+IQZXnh6umfwj43cw8u141SvqVyg/a9wNnAQ8ALcDDwEnAS4FB1XeYUscMTfWoypmzJwMbgH/KzI/UuSRJVSJiEcU9ic+gOEQ3GvgSsDQzN9eztv7A0FRNKqE4A5gHbKM4+ednmflYZfogihOEXgj82LNmpfqLiMEA7fYGPQMYD/w3lcObdSqvXzE0VZOI+AzwWmA7cDrFVuU9wOcz87Z61ibpySJicvUxysqP3qcDR9oFaBia5Xj2rEqLiNcDFwN/SHGizxkU12E+DNwYES2V4yaS6iwiXgHcFxFfiIg/iIgxmfnLzGzNzMMRMSginhERzzIwy3NLU6VFxH8A/5OZ76i8PvrrNCJmU1zrtSMzf79+VUoCiIhvANOBn1LsFXoCWAPcDnw7M1sj4hKKofQG1a/S/sXQVCmVi6A/AbwgMxdVtQ8CyMwjEfHKSp/FmXlPfSqVVBnx5zvAFyhC8oXA+RQDkTwb2AusAi4Edmbm79Wn0v7H0FRpEfFiihXxZuD6zPxRu+nPoDiVfWFm/rD3K5QEEBEjgXdQjAL0uUpbUJzEdx7F8HkzK39flJktdSq13zE0VZPK1uR7KUYPWUNxrdc9wGHgfcDLMnNy50uQ1FsqtwF7ou1vdTvwF8BlmTmxfhX2P4amalI5dX0O8PsUY1U+DZhAca3Xd4C/zcyv161ASR2qbGkOojhzNiOiCbgvM99e59L6FUNTpUTEOGAYsB/4RWb+PCKeTRGcJ1OcQbsuM/fUsUxJHF1fhwKPU/yw3ZmZj1dNb6DYY/SPmbmtPlX2T4amuhURb6G4FdgMit2wP6I4ieCbmbmqjqVJaqfd+nqI4jBKE/A9YEVmttaxvH7P6zTVpYi4EPgz4D8p7oDwexSnsL8S+GpEfKJttBFJ9dXB+noZsAm4FLgR+GDb+urN4o+NW5rqUkR8CdifmX/Urv3pFL9mPwL8R2a+sR71SfoV19fjzy0EdecQMDIiTq7c0eRk4HDlTLzPRcQTwHsiYkZmrq9vqdKA5/p6nLl5ru7cBrwYuAQgMx+vDMHV9oPry8ApwKl1qk/Sr7i+HmeGpjpVOUV9BXAL8MWIaIqIqyJiVGVFPJXimMmzMnNFXYuVBjjX197hMU2VEhEvp7g28xyKYbh2UZxJ2wD8Q2Z+qo7lSari+nr8GJrqUrtB2U8DzqQY/HkyxfWZ/wRsyswj9atSEri+9gZDU93yXntS/+H6enx5TFO/JiLGRMTrK4M+U/XL9WmV4yZU7sXXUM86Jbm+9jZDUx15P8WdTP47Iv4lIhZFREPlBrZtv2DHA9e4Ikp15/raiwxNdaQR+Evgj4ERwNeALRHxmcrNpgHeDFzlkFxS3bm+9iIHN9CTVAZ63gZsycwbI+JWYCrwCuA1wFsiYgMwBfi/9atUkutr7/NEID1J5UbSLwF2Z2Zzu2mnUNy49t0UY88Oy8yDvV+lJHB9rQdDU13q6Ey8iLgJeG5mXlCfqiR1xPX1+POYpp6k+ow7+NWZeFXThwDjgOt6uzZJT+b62vvc0lRNKndLaMzMpnrXIqlrrq89z9AUcHTlmgw84Bl2Ut/m+lo/7p5Vm7cCP6S4fdBvR8TYiBhU3SEihkfEyyLipPqUKKnC9bVO3NIUABHRBDxOcRnS+cD/Ulzv9W/ATzLz5xFxFbA4M8+rX6WSXF/rxy1NERHPBp4AllbOsHsO8I/Ay4GVwHcj4k+BdwDNnS1H0vHn+lpfbmmq7W4IlwMbMvOudtPOAd5UmT4CmJiZ23u/Skng+lpvhqaAo6emZ2Y+3tEp7BHxMWBRZp5TrxolFVxf68dh9ARAZh5sW/k6uNbrFOBS4MZ61CbpyVxf68ctzQEuIoYD+7u6/15EnAxcBtyWmYd6rThJT+L6Wn+G5gAXEX8P3Fd5PJCZ+zro86zMfLS3a5P0ZK6v9WdoDmAR8Rrgi8A+YA/wbeBO4MfAQ5VdQEOALwN/lpnr6lasNMC5vvYNhuYAFhFLgSPAJynugvAHwHOBjcDtwHeA6cD1mekF0lIdub72DYbmABURg4E/AYZn5nur2mdQ3LD2VcDJwLOAmzPzjfWoU5Lra19iaA5gETECGJOZ/1UZauuJ6hMMIuIy4DZgdmb+qE5lSsL1ta/wkpMBLDP3Ansrzw9Bcashih9TR4DhwOOugFL9ub72DYamniQzf1n1chjwoXrVIqlrrq+9z92z6lTl9kNH2q2Ykvog19feYWhKklSSdzmRJKkkQ1OSpJIMTUmSSjI0JUkqydCUJKmk/w9uUIl06BBTVAAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from qiskit.visualization import plot_histogram\n", + "counts=count(res.x,num_qubits,layers,2000)\n", + "plot_histogram(counts, color='green', title=\"Solution\")" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "id": "a8bff4b2-23a0-4434-aff3-8af6fa34aeca", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 1, 1, 0, 1, 0]\n" + ] + } + ], + "source": [ + "optimal_state=[eval(i) for i in max(counts, key=counts.get)]\n", + "print(optimal_state)" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "id": "425f304b-5c30-4e87-a076-72e0a59e93ab", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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nJwcJk6cyPLly72OIxIT6ruOlIjIdgkGg2RmZlFSsoHk5GQCgQApKSlex5JaysvLw+/307lzZ7ZnQWeReKURKRFpNK+88gpJSUmUlGzgqquuoqysTCWqifH5fLz88stA+CR0kUSnESkRaRQ77bwzixYuBGDVqlW0a9fO40RSV8cffzzt27fnpZde4p577qFLly5eRxLxjEakRKRBzZ49GzNj0cKFHH744TjnVKLiQOUyCF27dvU4iYi3VKREpMEceeSR9O/fHwi/AO4777zjcSKJFp/PxyuvvAKET0IXSVSa2hORqFu9enXVqFOPHj1YtGiRx4mkIRx33HG079CBl19+maVLl2p0ShKSRqREJKquvfbaqhI1ceJElag492tkGYRu3bp5G0TEIxqREpGoqKioID09nbKyMpo1a0ZRURFJSfoRE+98Ph+vvfYaxx57LMcff3zVdJ9IotCIlIjU27hx40hOTqasrIwbb7yRDRs2qEQlkOHDh7NDx468+uqrLF261Os4Io1KP+lEpF66dOlStSr5mjVraNWqlceJxAvLfvkFv99Pt27dtFCnJBSNSIlInUyfPh0zY9myZRx33HE451SiEpjP5+ONN94A4Nhjj/U2jEgjUpESke02dOhQ9t13XwDmzJmj82IEgKOPPppOnTvz+uuv8/PPP3sdR6RRaGpPRGotLy+Pjh07AtC7d2/mzp3rcSKJNUuXLMHv97Pjjjtqik8SgkakRKRW/va3v1WVqEmTJqlESbV8Ph9vvvkmEB6hEol3GpESka0qLS0lIyODYDBIZlYWhQUF+Hz6G0xqduSRR9K5SxfefPNNFi9ezI477uh1JJEGo5+GIlKjMWPG0KxZM4LBIHfeeSdF69apREmtLImcI9WjRw+Pk4g0LI1IicgfhEIhdthhB1atWgXAunXryMrK8jiVNCU+n4+3336bI444giOOOIK3337b60giDUJ/WorIZj7++GP8fj+rVq3i9NNPxzmnEiV18te//pWu3brxzjvv8NNPP3kdR6RBaERKRKrsv//+fPnllwAsXLiQnj17epxImrqfFy/G5/PRs2dPXcUncUkjUiLC0qVLMTO+/PJLBgwYgHNOJUqiwsyYPHkyEB6hEok3KlIiCe7888+nW7duAEydOpUZM2Z4G0jizrBhw+jWvTuTJ09m4cKFXscRiSpN7YkkqA0bNpCRkRF5aZfWrF6dryvypMH8vHgxZsbOO++sKT6JK/qpKZKARo8eTXp6Os45HnroIdas+U0lShrce++9B4RHqETihUakRBJIKBSidZs2VYtqrl+/nubNm3sdSxLEX/7yF3bccUfee+89FixYQK9evbyOJFJv+hNUJEFMmTIFv99PYUEBF1xwAcFgUCVKGl3lMgi77LKLx0lEokNFSiQB9O/fn8MOOwwIX6H3xBNPeJxIEtnUqVMBqv5PijRlKlIicWzBggWYGbNnz2bQoEE45+jSpYvXsSTBHXroofTo2ZMpU6Ywf/58r+OI1IuKlEicOu2006qmTz755BM+/fRTjxOJ/G5RZBmEXXfd1eMkIvWjIiUSZ4qKijAzXnjhBdp36EAwGOTAAw/0OpbIH3zwwQdAeIRKpKlSkRKJI3fccQctWrQA4KmnnmJFXp6WNZCYNXToUHbaaSc++OAD5s2b53UckTrR8gcicSAUCpGVlUVxcTFJSUkUFxeTkpLidSyRbfrxxx8xM3r37q2FOqVJisqfqmZ2uZnNNbM5ZjbBzNKisV8R2bZJkybh9/spLi7msssuo7y8XCVKmpTKKb6hQ4d6nERk+9V7RMrMOgJ/A3o750rM7CXgZGBsffctIlu36667Vl31lJeXR4cOHTxOJLL9hg4dys4778y0adOYO3cuu+22m9eRRGotWidPJAHNzCwJaA7kRWm/IlKNOXPmYGbMnz+fQw45BOecSpQ0aQsWLACgT58+HicR2T71LlLOuV+Be4FfgBXAOufc1PruV0SqN3z4cPr27QvA119/zfvvv+9xIpHo+PDDDwH405/+5HESkdqz+p7cZ2YtgVeBk4BC4GXgFefc+C3uNxIYCZCTkzNg4sSJ9XpeqV4gECAjI8PrGFKD+hyfYDDI7NmzAUhJSakqUxJd+h7y1ty5cyktLWW33XYjLa360211jGJfvB2jIUOGzHTODaxuWzSK1AnAYc65cyMfnwns65y7uKbHDBw40M2YMaNezyvVy83NZfDgwV7HkBrU9fjccMMN3HbbbQCMHz+e0047LcrJpJK+h7xnZgA1XsWnYxT74u0YmVmNRSoayx/8AuxrZs2BEmAooJYkEgUVFRVkZGaysbSU1NRUAoEASUlatUTi20cffcSQIUMYPHgwubm5XscR2aponCM1HXgF+Bb4IbLPMfXdr0iimzBhAsnJyWwsLeW6666jtLRUJUoSwuDBg9m1d28+/vhjfvjhB6/jiGxVVH4qO+duBG6Mxr5EBHbccUd+/vlnAFavXk2bNm08TiTSuP43dy5mxu67766FOiWm6bUjRGLIjBkzMDN+/vlnjj76aJxzKlGSsD7++GMADjroII+TiNRMRUokRhx22GHstddeAHz33Xe88cYb3gYS8dhBBx3Ebrvtxqeffsr333/vdRyRaumECxGPrVy5smoxzZ179WJBZKVyEfl98dl+/fppik9ikkakRDx05ZVXVpWoV199VSVKpBqffvopAIMGDfI4icgfaURKxANlZWWkp6dTUVFBeno6RUVF+Hz6u0akOoMGDaJv3758/vnnVYvSisQK/eQWaWTPPPMMqampVFRUcOuttxIIBFSiRLah8hyp/v37e5xEZHP66S3SiL7//nvOO+88AAoKCvjXv/7lcSKRpuOzzz4Dfn+BY5FYoCIl0gg+//xzzIzy8nJOPvlknHNkZ2d7HUukSTnggAPYvV8/AoEA3377rddxRAAVKZEGd/DBB1edJNunTx8mTJjgcSKRpuu7yDlSAwYM8DaISISKlEgD+eWXXzAzPvnkE3aPXLqdmprqdSyRJm+XXXYBYN999/U4iYiKlEiDuOiii+jatSsAkydPrvorWkTqLz09nT322IPp06czY8YMr+NIgtPyByJRtGHDBjIzMwmFQmRnZ7NmzRpdkSfSAGbNmoWZsddee2mhTvGUfsKLRMkjjzxCeno6oVCI++67j4KCApUokQb01VdfAbD33nt7nEQSmUakROopFArRrl0Oa9b8hplRVFRERkaG17FE4t4+++zDngMG8M033/DNN99UvValSGPSn8si9fDhhx/i9/tZs+Y3zj77bEKhkEqUSCOaGTlHSqNS4hUVKZE62muvvTjkkEMAWLx4Mc8++6zHiUQS09dffw3AwIEDPU4iiUhFSmQ7/fTTT5gZM2bMYJ999sE5R/fu3b2OJZKw9tprLwYOHMjMmTOrSpVIY1GREtkOI0aMoGfPngBMmzat6mRXEfHWN998A4TPmxJpTDrZXKQWAoEAmZmZALRt146VK1boijyRGFN5wvmeAwbw7cyZXseRBKHfBCLbcM8991SVqMcee4z8VatUokRi0MCBA9l7772Z9e23Gi2WRqMRKZEahEIhWrZsSVFREX6/n0AgQFpamtexRGQrpk+fjpmx3377aaFOaRT6s1qkGm+//TZ+v5+ioiJGjRpFRUWFSpRIEzEzMq3Xv39/j5NIItCIlMgW+vTpw9y5cwFYtmwZnTp18jiRiGyPPffck3323ZfpX33FF198wf777+91JIljGpESiZg3bx5mxty5cxk8eDDOOZUokSbqqy+/BOCAAw7wOInEOxUpEeDEE0+kd+/eAHzxxRd89NFHHicSkfqqnOLr16+fx0kknmlqTxJaYWEhLVu2BKBTp04sW7bM40QiEi177rkn+++/P1988QWff/65RqekQWhEShLWzTffXFWixo4dqxIlEoc+//xzAAYNGuRxEolXGpGShFNRUUFWVhYlJSUkJycTCARISUnxOpaINJBZs2bRv39/+u6+Oz98/73XcSTOaERKEsrLL79McnIyJSUlXHXVVZSVlalEicS5PfbYg0GDBjHnhx/47LPPvI4jcUYjUpIwdtp5ZxYtXAjAqlWraNeunceJRKSxfPrpp5gZBx54oBbqlKjSiJTEvdmzZ2NmLFq4kMMPPxznnEqUSAL67rvvANitTx+Pk0g8UZGSuHbEEUdUrW48c+ZM3nnnHY8TiYhXdt99dw466CD+N3cun3zyiddxJE5oak/iUn5+Pjk5OQD06NGDRYsWeZxIRGLBxx9/jJlx8MEHa4pPokIjUhJ3rrnmmqoS9eKLL6pEichmfvjhB4CqRXhF6kMjUhI3KioqaJ6eTnlZGWnNmrG+qIikJP0XF5HN9enTh4MPPpiPP/6Y3NxcBg8e7HUkacKiMiJlZtlm9oqZzTezeWa2XzT2K1Jb48aNIzk5mfKyMm688UZKNmxQiRKRGuXm5gIwZMgQb4NIkxet3zQPAu855443sxSgeZT2K7JNXbp0qVqVfM2aNbRq1crjRCLSFPzwww/07duXXXfdlXnz5nkdR5qoeo9ImVkL4CDgGQDnXJlzrrC++xXZlunTp2NmLFu2jOOOOw7nnEqUiNRanz59GDJkCPPnz2fatGlex5EmKhojUt2B1cBzZtYPmAn83TlXHIV9i1Rr6NChVT/45syZw2677eZxIhFpiqZNm4aZMXToUF3FJ3Vi9f2PY2YDga+AA5xz083sQaDIOXfDFvcbCYwEyMnJGTBx4sR6Pa9ULxAIkJGR4XWMBlNeXs73kdfKSktLa3IFKt6PTzzQMYp90T5GpaWlzJ07t0n+TIlV8fZ9NGTIkJnOuYHVbnTO1esNaA8s2eTjA4F3tvaYAQMGOGkYH330kdcRGsyll17qAAe4SZMmeR2nTuL5+MQLHaPY1xDHaOjQoQ5wH3zwQdT3nYji7fsImOFq6DT1ntpzzq00s2Vm1ss5twAYCvyvvvsVqVRaWkpGRgbBYJCsrCwKCgrw+bQEmohEzwcffICZccghh2iKT7ZLtH4bXQr818y+B/YA7ojSfiXBPfnkkzRr1oxgMMhdd93FunXrVKJEpEH873/hMYCdd97Z4yTSlERl+QPn3Gyg+rlDkToIhUJ06NCB/Px8ANatW0dWVpbHqUQknu26664ceuihvP/++7z//vsceuihXkeSJkB/2kvMyc3Nxe/3k5+fzxlnnIFzTiVKRBrF1KlTAfjzn//scRJpKlSkJKbst9/+VSsNL1y4kHHjxnmcSEQSzfz58wHoudNOHieRpkBFSmLC0qVLMTO++upLBgwYgHOOnj17eh1LRBJQr169+Mtf/sJPixYxZcoUr+NIjFOREs+dd955dOvWDQgPq8+YMcPbQCKS8N577z0ADjvsMI+TSKzTq7qKZzZs2EBGRkb4pV1at2Z1fr6uyBORmDF//nx22WUXevTowU8//eR1HIlR+q0lnhg9ejTp6ek453jooYdY89tvKlEiElN69erFsGHDWLx4Me+++67XcSRGaURKGlUoFKJ169YUFhZi5iMQWE/z5s29jiUiUq3JkydjZhx++OFaqFOqpSEAaTTvvfcefr+fwsJCLrjgAkKhoEqUiMS8H3/8EYDu3bt7nERikYqUNIr+/fszbNgwIHyF3hNPPOFxIhGR2tlpp53461//ypIlS5g8ebLXcSTGqEhJg1qwYAFmxuzZsxk0aBDOObp06eJ1LBGR7fL2228D8Ne//lVTfLIZFSlpMKeeeiq77LILAJ9++imffvqpx4lEROpu0aJFAFXLtYiAipQ0gKKiIsyMCRMm0L5DB4LBIIMGDfI6lohIvfTo0YMjjzySX375hbfeesvrOBIjVKQkqu644w5atGgBwFNPPcWKvDwtayAicePNN98E4KijjiIUCnmcRmKBlj+QqAiFQmRlZVFcXExSUhLFxcWkpKR4HUtEJOoWL17MjjvuSLdu3fjll1+8jiMe01CB1Nvrr7+O3++nuLiYyy+/nPLycpUoEYlb3bt356ijjmLZsmVVI1SSuDQiJfWy6667Vr1Sel5eHh06dPA4kYhIw5s0aRJmxtFHH00wGNQpDAlMR17qZM6cOZgZ8+fP59BDD8U5pxIlIgll8eLFAHTp2tXjJOIlFSnZbsOHD6dv374AfP3110ydOtXjRCIija979+4MHz6cX5cvZ9KkSV7HEY9oak9qbc2aNbRp0waArl27smTJEm8DiYh47LXXXsPMOOaYYzTFl6B0xKVWbrjhhqoSNX78eJUoEZGIyp+HnTt39jaIeEIjUrJVFRUVZGRksHHjRlJTUwkEAiQl6b+NiEilrl27ctxxx/Hqq6/y+uuvM3z4cK8jSSPSiJTUaMKECSQnJ7Nx40auvfZaSktLVaJERKrxyiuvAHDsscdqoc4Eo9+KUq3u3btXDVevXr26alpPRESqt3TpUrp27UqnTp3Iy8vzOo40Eo1IyWZmzJiBmbFkyRKOPvponHMqUSIitdClSxeOP/54VqxYwauvvup1HGkkGpGSKocddhhTpkwB4LvvvmP33Xf3OJGISNPy8ssvY2Ycf/zxuoovQegICytXrsTMmDJlCjv36oVzTiVKRKSOli5dCkDHjh09TiKNQUUqwV1xxRVVK5K/8sorLIi83IuIiNRNly5dOOmkk1i5ciUvv/yy13GkgWlqL0GVlZWRnp5ORUUF6enpFBUVaQhaRCRKJk6cyIsvvsiJJ56oKb44pyObgJ555hlSU1OpqKjgtttuIxAI6JtcRCTKli1bBsAOO+zgcRJpSBqRSjA7dOzIishluevWrSMrK8vjRCIi8alTp06cfPLJVaNTJ510kteRpAFoGCJBfPbZZ5gZK/LyOPnkk3HOqUSJiDSwCRMmAHDyySdroc44pSKVAA466CAOPPBAAObPn1/1jS0iIg2vcoqv8sIeiS8qUnHsl19+wcz49NNP2b1fP5xz9OrVy+tYIiIJpVOnTpx66qnk5+czceJEr+NIlKlIxamLLrqIrl27AjB58mS+mz3b20AiIgnsv//9LwCnnHKKpvjijE42jzOhUAi/308oFCI7O5s1a9boijwRkRjw66+/0rFjR9q3b09+fr7XcSRKovYb1sz8ZjbLzN6O1j5l+zzyyCPMmjWLUCjEfffdR0FBgUqUiEiM2GGHHTj99NNZvXo1L7zwgtdxJEqi+Vv278C8KO5PaikUCtGmTRsuvfRSANavX88VV1zhcSoREdnSf/7zHwBOO+00TfHFiagUKTPrBPwVeDoa+5Pa++CDD/D7/axZs4azzz6bAQMGkJGR4XUsERGpQV5kLb927dp5nESiwZxz9d+J2SvAv4FM4B/OuSOquc9IYCRATk7OAF25UH/z5s1jw4YNAPTt25eUlBQCgYCKVAzT8Yl9OkaxLx6O0ZIlS1izZg3du3enVatWXseJung4RpsaMmTITOfcwOq21ftkczM7Ash3zs00s8E13c85NwYYAzBw4EA3eHCNd5Vt+Omnn+jZsycA++y7L199+WXVttzcXPS1jV06PrFPxyj2xcsxMjOAuHwtvng5RrURjSN3AHCUmS0BJgJ/MrPxUdivVGPEiBFVJeqjjz7arESJiEjTsWLFCgDatm3rcRKpj3oXKefctc65Ts65bsDJwDTn3On1TiabCQQCmBnjxo2jbbt2BIPBhGn7IiLxqH379px11lmsXbuW559/3us4UkfxNZYYp+6++24yMzMBeOyxx8hftSruhoFFRBLRc889B8BZZ52lq/iaqKguyOmcywVyo7nPRBYKhchu2ZL1RUX4/X4CgQBpaWlexxIRkShatWoVOTk5tG7ThoK1a72OI9tJwxox6u2338bv97O+qIhRo0ZRUVGhEiUiEofatWvHueeeS2FBgab4miAVqRjUp08fjjzySCD8quEPP/ywx4lERKQhPf10eBlGTfE1PSpSMWTu3LmYGXPnzmXw4ME45+jUqZPXsUREpBGsWrUKIC7XlYpnKlIx4oQTTqBPnz4AfPHFF3z00UceJxIRkcbUrl07zj//fNatW8czzzzjdRypJRUpjxUWFmJmvPLKK3Tq1AnnHPvtt5/XsURExANjxowB4LzzztMUXxOhIuWhm2++mZYtWwIwduxYli1b5nEiERHx2urVqwGqfj9IbIvq8gdSOxUVFWRlZVFSUkJycjKBQICUlBSvY4mISAxo06YNF1xwAU8++SRPP/005513nteRZCs0ItXIXnrpJZKTkykpKeGqq66irKxMJUpERDbzxBNPAHD++edrii/GaUSqEe20004sWrQICF+d0a5dO48TiYhIrFq9ejVt27Ylu2VLitat8zqO1EAjUo1g1qxZmBmLFi3i8MMPxzmnEiUiIlvVpk0bLrzwQtYXFVWdhC6xR0WqgR1xxBHs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rbnlllvw+/1cf/31muKLknoXKTMz4BlgnnPu/vpH2j79OmczceS+ZDdLJj2l+oKUnuInu1kyE0fuS7/O2Y0bUEREJIZULtSZqYU6oyIaI1IHAGcAfzKz2ZG3w6Ow31rr1zmb6dcP5fbhfemVk4EZJPsNM+iVk8ntw/sy/fqhKlEiIpLwmjdvzo033khFeTm33Xab13GavHqfI+Wc+wzw/BK41CQ/x/TvyDH9OxIMOYrLKkhPSdLVeSIiIlu46aabuO2227jhhhv4xz/+QVpamteRmqwmu7L51vh9RlZaskqUiIhIDaqm+DIzPU7StMVlkRIREZGta968OTfffDMVFRXccsstXsdpslSkREREEtT//d//kZSUxI033siGDRu8jtMkqUiJiIgksPXr1wOQldXC4yRNk4qUiIhIAktLS+OWW24hGKzgpptu8jpOk6MiJSIikuBuuOEGkpKSuPnmmzXFt51UpERERGSTKT4t1Lk9VKRERESEtLQ0brvtNoLBIDfeeKPXcZoMFSkREREB4Prrryc5OZlbbrlFU3y1pCIlIiIiVSoX6tQUX+2oSImIiEiVtLQ0/v3vfxMMBrnhhhu8jhPzVKRERERkM//85z9JTknhtttuo7i42Os4MU1FSkRERP4goKv4akVFSkRERP4gJSWFu+66i1AoxPXXX+91nJilIiUiIiLVuvrqq0lJSeGOO+4gEAh4HScmqUiJiIhIjSoX6mzRQq/FVx0VKREREalRSkoKd999N6FQiGuvvdbrODFHRUpERES26qqrriI1NZU777xTU3xbUJESERGRbdJCndVTkRIREZFtSklJ4b777sM5xzXXXON1nJihIiUiIiK1csUVV5Calsbdd99dNUKV6FSkREREpNaK1q0DIDs729sgMUJFSkRERGotJSWFBx54AOccV111lddxPKciJSIiItvlsssuIy2tGffee2/CT/GpSImIiMh2KyrSFB+oSImIiEgdJCcnM3r0aJxzXHnllV7H8YyKlIiIiNTJ3//+d5o1a879999PYWGh13E8oSIlIiIidVY5xdeyZUuPk3hDRUpERETqLCkpiYcffhiAyy+/3OM0jU9FSkREROpl1KhRNG/enNGjRyfcFJ+KlIiIiNTbunWJOcWnIiUiIiL1lpSUxKOPPgrAsmXLPE7TeFSkREREJCouvvhi0tPTyc/P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dDNmzNhmcNl+ubm5DB482OsYUgMdn9inYxT7dIxiX7wdIzOrsUht8xwp59wh29j5WcARwNDalCgRERGReFHfq/YOA64GDnbObYhOJBEREZGmob7rSD0CZALvm9lsM3siCplEREREmoSonWy+XU9qthpY2uhPnBjaAL95HUJqpOMT+3SMYp+OUeyLt2PU1TnXtroNnhQpaThmNqOmE+LEezo+sU/HKPbpGMW+RDpGeokYERERkTpSkRIRERGpIxWp+DPG6wCyVTo+sU/HKPbpGMW+hDlGOkdKREREpI40IiUiIiJSRypSccbMbjKzXyPres02s8O9ziRhZnaYmS0ws0Vm9k+v88gfmdkSM/sh8r2j17GKAWb2rJnlm9mcTW5rZWbvm9nCyL8tvcyY6Go4Rgnzu0hFKj494JzbI/I22eswAmbmBx4FhgG9gVPMrLe3qaQGQyLfOwlx6XYTMBY4bIvb/gl86JzbCfgw8rF4Zyx/PEaQIL+LVKREGsfewCLn3GLnXBkwETja40wiMc859wmwdoubjwaej7z/PHBMY2aSzdVwjBKGilR8GmVm30eGWzXkHRs6Ass2+Xh55DaJLQ6YamYzzWyk12GkRjnOuRWR91cCOV6GkRolxO8iFakmyMw+MLM51bwdDTwO9AD2AFYA93mZVaSJGeSc25PwFOwlZnaQ14Fk61z40nNdfh57EuZ3UZLXAWT7OecOqc39zOwp4O0GjiO18yvQeZOPO0VukxjinPs18m++mb1OeEr2E29TSTVWmVkH59wKM+sA5HsdSDbnnFtV+X68/y7SiFScifxQqTQcmFPTfaVRfQPsZGbdzSwFOBl40+NMsgkzSzezzMr3gT+j759Y9SYwIvL+CGCSh1mkGon0u0gjUvHnbjPbg/BQ9xLgAk/TCADOuQozGwVMAfzAs865uR7Hks3lAK+bGYR/Nr7gnHvP20hiZhOAwUAbM1sO3AjcCbxkZucCS4ETvUsoNRyjwYnyu0grm4uIiIjUkab2REREROpIRUpERESkjlSkREREROpIRUpERESkjlSkREREROpIRUpERESkjlSkREREROpIRUpERESkjv4fclMX+uxUFUUAAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Visualize the solution\n", + "def visualize_solution(xc, yc, x, C, n, K, title_str):\n", + " plt.figure()\n", + " plt.scatter(xc, yc, s=200)\n", + " for i in range(len(xc)):\n", + " plt.annotate(i, (xc[i] + 0.15, yc[i]), size=16, color=\"r\")\n", + " plt.plot(xc[0], yc[0], \"r*\", ms=20)\n", + "\n", + " plt.grid()\n", + "\n", + " for ii in range(0, n**2):\n", + "\n", + " if x[ii] > 0:\n", + " ix = ii // n\n", + " iy = ii % n\n", + " plt.arrow(\n", + " xc[ix],\n", + " yc[ix],\n", + " xc[iy] - xc[ix],\n", + " yc[iy] - yc[ix],\n", + " length_includes_head=True,\n", + " head_width=0.25,\n", + " )\n", + "\n", + " plt.title(title_str + \" cost = \" + str(int(C * 100) / 100.0))\n", + " plt.show()\n", + "#########################################################\n", + "# Initialize the problem by randomly generating the instance\n", + "initializer = Initializer(3,2)\n", + "xc, yc, instance = initializer.generate_instance()\n", + "# Put the solution in a way that is compatible with the classical variables\n", + "x_quantum = np.zeros(n**2)\n", + "kk = 0\n", + "for ii in range(n**2):\n", + " if ii // n != ii % n:\n", + " x_quantum[ii] = optimal_state[kk]\n", + " kk += 1\n", + "\n", + "\n", + "# visualize the solution\n", + "visualize_solution(xc, yc, x_quantum, E_min+offset, 3, 2, \"Quantum\")" + ] + }, + { + "cell_type": "markdown", + "id": "401ca501-96bf-4d6c-b7d7-11d21c8f485b", + "metadata": {}, + "source": [ + "# On real computer `ibm_Oslo`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0c61718a-7c55-45e4-9ae9-ee7c9b74a891", + "metadata": {}, + "outputs": [], + "source": [ + "fvqe_cost, fvqe_iter=[],[]\n", + "def callback(nfevs, x_next, cost, stepsize):\n", + " fvqe_cost.append(cost)\n", + " fvqe_iter.append(nfevs)\n", + "\n", + "num_qubits,layers,shots,c=H.num_qubits,1,5000,E_max+1\n", + "Filtering_op = c * (I^H.num_qubits) - H\n", + "\n", + "theta= np.array([*((np.pi/2)*np.ones(num_qubits)),*(np.zeros(2*(num_qubits-1)*layers))])\n", + "optimizer = GradientDescent(maxiter=150,learning_rate=1.0,callback = callback)\n", + "obj=usual_expectation(num_qubits, layers, H, shots,hardware=True)\n", + "\n", + "grad_fun=gradient(c, num_qubits, layers, Filtering_op, shots,hardware=True)\n", + "res=optimizer.minimize(fun=obj, x0=theta,jac=grad_fun)\n", + "\n", + "print(res)\n", + "print()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "57d098bb-86a0-425b-8f2b-fba9facd519c", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "4ce7d5cb-f597-4ca9-b964-214a2c42ea46", + "metadata": { + "id": "40b37013-2d9d-4e9d-a325-30dd249ba65a", + "tags": [] + }, + "source": [ + "# VQE solver\n", + "https://qiskit.org/documentation/stubs/qiskit.algorithms.VQE.html\n", + "\n", + "https://qiskit.org/documentation/tutorials/algorithms/04_vqe_advanced.html" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "aa80fa67-994d-4198-81b5-1ccb3b98ea5d", + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit.algorithms import VQE, QAOA\n", + "from qiskit.circuit.library import TwoLocal" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "11b03706-b20c-443f-a5b8-00e06b280ae3", + "metadata": {}, + "outputs": [], + "source": [ + "def gradient_vqe(tho,n,l,F_op,shots, hardware):\n", + " def sub_gradient_vqe(thetas):\n", + " list_gradient=[]\n", + " dominator=2\n", + " for j in range(len(thetas)):\n", + "\n", + " theta_n=np.array(thetas)\n", + " theta_n[j]=theta_n[j]-np.pi/2\n", + " theta_p=np.array(thetas)\n", + " theta_p[j]=theta_p[j]+np.pi/2\n", + "\n", + " grad=((expectation(theta_p,n,l,H,shots,tho,False,False,hardware)-expectation(theta_n,n,l,H,shots,tho,False,False,hardware)))/dominator\n", + "\n", + " list_gradient.append(grad)\n", + " return np.array(list_gradient)\n", + " return sub_gradient_vqe" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "ad8bc947-0d92-4c92-a315-164fdcde84a5", + "metadata": {}, + "outputs": [], + "source": [ + "vqe_cost, vqe_iter=[],[]\n", + "def callback_vqe(nfevs, x_next, cost, stepsize):\n", + " vqe_cost.append(cost)\n", + " vqe_iter.append(nfevs)" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "aff05c69-22cb-4c9e-9003-c5b967ba123c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + } + ], + "source": [ + "qi = QuantumInstance(Aer.get_backend('qasm_simulator'), seed_transpiler=50, seed_simulator=50)\n", + "ansatz = TwoLocal(rotation_blocks='ry', entanglement_blocks='cz')\n", + "vqe=VQE(ansatz=ansatz, optimizer=optimizer, expectation=obj, callback=callback_vqe,quantum_instance=qi, gradient=gradient_vqe)#Ansatz(theta,num_qubits,layers),initial_point=theta\n", + "print(vqe)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "01014c6c-3bf7-43f5-a07e-f6ff4c263e20", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Traceback \u001b[1;36m(most recent call last)\u001b[0m:\n", + " Input \u001b[0;32mIn [38]\u001b[0m in \u001b[0;35m\u001b[0m\n", + " result = vqe.compute_minimum_eigenvalue(operator=H)\n", + " File \u001b[0;32m/opt/conda/lib/python3.8/site-packages/qiskit/algorithms/minimum_eigen_solvers/vqe.py:519\u001b[0m in \u001b[0;35mcompute_minimum_eigenvalue\u001b[0m\n", + " energy_evaluation, expectation = self.get_energy_evaluation(\n", + " File \u001b[0;32m/opt/conda/lib/python3.8/site-packages/qiskit/algorithms/minimum_eigen_solvers/vqe.py:594\u001b[0m in \u001b[0;35mget_energy_evaluation\u001b[0m\n", + " expect_op, expectation = self.construct_expectation(\n", + "\u001b[1;36m File \u001b[1;32m/opt/conda/lib/python3.8/site-packages/qiskit/algorithms/minimum_eigen_solvers/vqe.py:424\u001b[1;36m in \u001b[1;35mconstruct_expectation\u001b[1;36m\u001b[0m\n", + "\u001b[1;33m observable_meas = expectation.convert(StateFn(operator, is_measurement=True))\u001b[0m\n", + "\u001b[1;31mAttributeError\u001b[0m\u001b[1;31m:\u001b[0m 'function' object has no attribute 'convert'\n", + "\n", + "Use %tb to get the full traceback.\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "\n", + "\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "result = vqe.compute_minimum_eigenvalue(operator=H)\n", + "print(result)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "11629ce5-ed48-429f-933f-cbc16fd4aad9", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "colab": { + "collapsed_sections": [], + "name": "Copie de F_VQE.ipynb", + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.8.13" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "state": {}, + "version_major": 2, + "version_minor": 0 + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/LoQus/notebooks/Hamiltonian_provider.py b/LoQus/notebooks/Hamiltonian_provider.py new file mode 100644 index 0000000..8caa0da --- /dev/null +++ b/LoQus/notebooks/Hamiltonian_provider.py @@ -0,0 +1,269 @@ +from time import process_time +import numpy as np +# Visualization tool +from qiskit.visualization import * +import matplotlib.pyplot as plt +import matplotlib.axes as axes + +import itertools +import networkx as nx +import time +import math + +from qiskit.algorithms.optimizers import GradientDescent +from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister, Aer, transpile, execute +from qiskit.utils import QuantumInstance, algorithm_globals +from qiskit.circuit import ParameterVector +from qiskit.opflow import Z, I, X, Y, ListOp, PauliExpectation, CVaRExpectation, StateFn, CircuitSampler, CircuitStateFn, ListOp + +from qiskit.algorithms import VQE, QAOA + +import plotly.graph_objects as go + +from qiskit import BasicAer +from qiskit_optimization import QuadraticProgram +from qiskit_optimization.algorithms import MinimumEigenOptimizer + +import qiskit.tools.jupyter +# %qiskit_version_table + +# Ignore Deprecation Warnings +import warnings +warnings.filterwarnings("ignore") + + +# Classes for solving the VRP problem + +class Initializer(): + + def __init__(self, n, b): + self.n = n + self.b = b + + def generate_instance(self): + + n = self.n + b = self.b + + # np.random.seed(33) + np.random.seed(100*n + b) + + xc = (np.random.rand(n) - 0.5) * 50 + yc = (np.random.rand(n) - 0.5) * 50 + + instance = np.zeros([n, n]) + for ii in range(0, n): + for jj in range(ii + 1, n): + instance[ii, jj] = (xc[ii] - xc[jj]) ** 2 + (yc[ii] - yc[jj]) ** 2 + instance[jj, ii] = instance[ii, jj] + + return xc, yc, instance + + +try: + import cplex + from cplex.exceptions import CplexError +except: + print("Warning: Cplex not found.") + +class ClassicalOptimizer: + + def __init__(self, instance,n,K): + + self.instance = instance + self.n = n # number of nodes + self.K = K # number of vehicles + + + def compute_allowed_combinations(self): + f = math.factorial + return f(self.n) / f(self.K) / f(self.n-self.K) + + + def cplex_solution(self): + + # refactoring + instance = self.instance + n = self.n + K = self.K + + my_obj = list(instance.reshape(1, n**2)[0])+[0. for x in range(0,n-1)] + my_ub = [1 for x in range(0,n**2+n-1)] + my_lb = [0 for x in range(0,n**2)] + [0.1 for x in range(0,n-1)] + my_ctype = "".join(['I' for x in range(0,n**2)]) + "".join(['C' for x in range(0,n-1)]) + + my_rhs = 2*([K] + [1 for x in range(0,n-1)]) + [1-0.1 for x in range(0,(n-1)**2-(n-1))] + [0 for x in range(0,n)] + my_sense = "".join(['E' for x in range(0,2*n)]) + "".join(['L' for x in range(0,(n-1)**2-(n-1))])+"".join(['E' for x in range(0,n)]) + + try: + my_prob = cplex.Cplex() + self.populatebyrow(my_prob,my_obj,my_ub,my_lb,my_ctype,my_sense,my_rhs) + + my_prob.solve() + + except CplexError as exc: + print(exc) + return + + x = my_prob.solution.get_values() + x = np.array(x) + cost = my_prob.solution.get_objective_value() + + return x,cost + + + def populatebyrow(self,prob,my_obj,my_ub,my_lb,my_ctype,my_sense,my_rhs): + + n = self.n + + prob.objective.set_sense(prob.objective.sense.minimize) + prob.variables.add(obj = my_obj, lb = my_lb, ub = my_ub, types = my_ctype) + + prob.set_log_stream(None) + prob.set_error_stream(None) + prob.set_warning_stream(None) + prob.set_results_stream(None) + + rows = [] + for ii in range(0,n): + col = [x for x in range(0+n*ii,n+n*ii)] + coef = [1 for x in range(0,n)] + rows.append([col, coef]) + + for ii in range(0,n): + col = [x for x in range(0+ii,n**2,n)] + coef = [1 for x in range(0,n)] + + rows.append([col, coef]) + + # Sub-tour elimination constraints: + for ii in range(0, n): + for jj in range(0,n): + if (ii != jj)and(ii*jj>0): + + col = [ii+(jj*n), n**2+ii-1, n**2+jj-1] + coef = [1, 1, -1] + + rows.append([col, coef]) + + for ii in range(0,n): + col = [(ii)*(n+1)] + coef = [1] + rows.append([col, coef]) + + prob.linear_constraints.add(lin_expr=rows, senses=my_sense, rhs=my_rhs) + + + +class QuantumOptimizer: + + def __init__(self, instance, n, K): + + self.instance = instance + self.n = n + self.K = K + + def binary_representation(self,x_sol=0): + + instance = self.instance + n = self.n + K = self.K + + A = np.max(instance) * 100 # A parameter of cost function + + # Determine the weights w + instance_vec = instance.reshape(n ** 2) + w_list = [instance_vec[x] for x in range(n ** 2) if instance_vec[x] > 0] + w = np.zeros(n * (n - 1)) + for ii in range(len(w_list)): + w[ii] = w_list[ii] + + # Some variables I will use + Id_n = np.eye(n) + Im_n_1 = np.ones([n - 1, n - 1]) + Iv_n_1 = np.ones(n) + Iv_n_1[0] = 0 + Iv_n = np.ones(n-1) + neg_Iv_n_1 = np.ones(n) - Iv_n_1 + + v = np.zeros([n, n*(n-1)]) + for ii in range(n): + count = ii-1 + for jj in range(n*(n-1)): + + if jj//(n-1) == ii: + count = ii + + if jj//(n-1) != ii and jj%(n-1) == count: + v[ii][jj] = 1. + + vn = np.sum(v[1:], axis=0) + + # Q defines the interactions between variables + Q = A*(np.kron(Id_n, Im_n_1) + np.dot(v.T, v)) + + # g defines the contribution from the individual variables + g = w - 2 * A * (np.kron(Iv_n_1,Iv_n) + vn.T) - \ + 2 * A * K * (np.kron(neg_Iv_n_1, Iv_n) + v[0].T) + + # c is the constant offset + c = 2 * A * (n-1) + 2 * A * (K ** 2) + + try: + max(x_sol) + # Evaluates the cost distance from a binary representation of a path + fun = lambda x: np.dot(np.around(x), np.dot(Q, np.around(x))) + np.dot(g, np.around(x)) + c + cost = fun(x_sol) + except: + cost = 0 + + return Q, g, c, cost + + def construct_problem(self, Q, g, c) -> QuadraticProgram: + qp = QuadraticProgram() + for i in range(n * (n - 1)): + qp.binary_var(str(i)) + qp.objective.quadratic = Q + qp.objective.linear = g + qp.objective.constant = c + return qp + +def Hamilton(n,K,b): + + initializer = Initializer(n,b) + xc, yc, instance = initializer.generate_instance() + + classical_optimizer = ClassicalOptimizer(instance,n,K) + + x = None + z = None + try: + x, classical_cost = classical_optimizer.cplex_solution() + # Put the solution in the z variable + z = [x[ii] for ii in range(n**2) if ii//n != ii%n] + # Print the solution + except: + pass + + algorithm_globals.massive=True + # Instantiate the quantum optimizer class with parameters: + quantum_optimizer = QuantumOptimizer(instance, n, K) + + try: + if z is not None: + Q, g, c, binary_cost = quantum_optimizer.binary_representation(x_sol = z) + else: + Q, g, c, binary_cost = quantum_optimizer.binary_representation() + except NameError as e: + pass + + qp = quantum_optimizer.construct_problem(Q, g, c) + + quantum_instance = QuantumInstance(BasicAer.get_backend('qasm_simulator'), + seed_simulator=algorithm_globals.random_seed, + seed_transpiler=algorithm_globals.random_seed) + + vqe = VQE(quantum_instance=quantum_instance) + optimizer = MinimumEigenOptimizer(min_eigen_solver=vqe) + H, offset = optimizer._convert(qp, optimizer._converters).to_ising() + return H, offset \ No newline at end of file diff --git a/LoQus/path.png b/LoQus/path.png new file mode 100644 index 0000000..19a4904 Binary files /dev/null and b/LoQus/path.png differ diff --git a/LoQus/plan.png b/LoQus/plan.png new file mode 100644 index 0000000..e1928ed Binary files /dev/null and b/LoQus/plan.png differ diff --git a/LoQus/probability.png b/LoQus/probability.png new file mode 100644 index 0000000..615c849 Binary files /dev/null and b/LoQus/probability.png differ