Commit f7b7d79c by Abhishek

### -.

parent 7797d2c0
 ... ... @@ -63,7 +63,7 @@ "The aim of MaxCut is to maximize the number of edges (yellow lines) in a graph that are \"cut\" by\n", "a given partition of the vertices (blue circles) into two sets (see figure below).\n", "\n", "" "" ] }, { ... ... @@ -75,7 +75,10 @@ "\\begin{align}C(z) = \\sum_{\\alpha=1}^{m}C_\\alpha(z),\\end{align}\n", "\n", "where $C$ counts the number of edges cut. $C_\\alpha(z)=1$ if $z$ places one vertex from the $\\alpha^\\text{th}$ edge in set $A$ and the other in set $B$, and $C_\\alpha(z)=0$ otherwise. Finding a cut which yields the maximum possible value of $C$ is an NP-complete problem, so our best hope for a polynomial-time algorithm lies in an approximate optimization. In the case of MaxCut, this means finding a partition $z$ which yields a value for $C(z)$ that is close to the maximum possible value.\n", "\n" "\n", "We can represent the assignment of vertices to set $A$ or $B$ using a bitstring, $z=z_1...z_n$ where $z_i=0$ if the $i^\\text{th}$ vertex is in $A$ and $z_i = 1$ if it is in $B$. For instance, in the situation depicted in the figure above the bitstring representation is $z=0101\\text{,}$ indicating that the $0^{\\text{th}}$ and $2^{\\text{nd}}$ vertices are in $A$ while the $1^{\\text{st}}$ and $3^{\\text{rd}}$ are in $B$. This assignment yields a value for the objective function (the number of yellow lines cut) $C=4$, which turns out to be the maximum cut. In the following sections, we will represent partitions using computational basis states and use PennyLane to rediscover this maximum cut.\n", "\n", "

Note

In the graph above, $z=1010$ could equally well serve as the maximum cut.

" ] }, { ... ... @@ -103,11 +106,6 @@ "\n", "\n", "\n", "**Remember**: \n", "* $R_x(\\gamma) = \\exp^{-i \\frac{\\gamma}{2}\\sigma_x}$\n", "* $R_y(\\gamma) = \\exp^{-i \\frac{\\gamma}{2}\\sigma_y}$\n", "* $R_z(\\gamma) = \\exp^{-i \\frac{\\gamma}{2}\\sigma_z}$\n", "\n", "\n", "Let $\\langle \\boldsymbol{\\gamma}, \\boldsymbol{\\beta} | C | \\boldsymbol{\\gamma},\\boldsymbol{\\beta} \\rangle$ be the expectation of the objective operator. In the next section, we will use PennyLane to perform classical optimization over the circuit parameters $(\\boldsymbol{\\gamma}, \\boldsymbol{\\beta})$. This will specify a state $|\\boldsymbol{\\gamma},\\boldsymbol{\\beta}\\rangle$ which is likely to yield an approximately optimal partition $|z\\rangle$ upon performing a measurement in the\n", "computational basis. In the case of the graph shown above, we want to measure either 0101 or 1010 from our state since these correspond to\n", ... ... @@ -157,7 +155,7 @@ }, { "cell_type": "code", "execution_count": 3, "execution_count": 11, "metadata": { "collapsed": false, "jupyter": { ... ... @@ -169,7 +167,6 @@ "n_wires = 4\n", "graph = [(0, 1), (0, 3), (1, 2), (2, 3)]\n", "\n", "\n", "# unitary operator U_B with parameter beta\n", "def U_B(beta):\n", " for wire in range(n_wires):\n", ... ... @@ -199,7 +196,7 @@ }, { "cell_type": "code", "execution_count": 4, "execution_count": 12, "metadata": { "collapsed": false, "jupyter": { ... ... @@ -225,7 +222,7 @@ }, { "cell_type": "code", "execution_count": 5, "execution_count": 13, "metadata": { "collapsed": false, "jupyter": { ... ... @@ -253,7 +250,7 @@ }, { "cell_type": "code", "execution_count": 6, "execution_count": 14, "metadata": { "collapsed": false, "jupyter": { ... ... @@ -293,132 +290,82 @@ "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Step 1**: Enter number of layers, $p$ value." ] }, { "cell_type": "code", "execution_count": 7, "execution_count": 20, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "n_layers = 2 # Enter the layers you want" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Step 2**: Define Objective function value for gradient descent, for *minimization*." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "# minimize the negative of the objective function\n", "def objective(params):\n", " gammas = params[0]\n", " betas = params[1]\n", " neg_obj = 0\n", " for edge in graph:\n", " # objective for the MaxCut problem\n", " neg_obj -= 0.5 * (1 - circuit(gammas, betas, edge=edge, n_layers=n_layers))\n", " return neg_obj\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Step 3**: Define the optimiaztion method for Gradient Descent." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "learning_rate = 0.1\n", "opt = qml.AdagradOptimizer(stepsize=learning_rate)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Step 4**: Optimize" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Objective after step 5: 2.0171789\n", "Objective after step 10: 2.9138305\n" "\n", "p=1\n", "Objective after step 5: 2.7870528\n", "Objective after step 10: 2.9983800\n", "Optimized (gamma, beta) vectors:\n", "[[-0.78539768]\n", " [-1.1923295 ]]\n", "Most frequently sampled bit string is: 1010\n" ] } ], "source": [ "n_layers = 1 # Enter the layes you want\n", "\n", "\n", "print(\"\\np={:d}\".format(n_layers))\n", "\n", "# initialize the parameters near zero\n", "init_params = 0.01 * np.random.rand(2, n_layers)\n", "\n", "# minimize the negative of the objective function\n", "def objective(params):\n", " gammas = params[0]\n", " betas = params[1]\n", " neg_obj = 0\n", " for edge in graph:\n", " # objective for the MaxCut problem\n", " neg_obj -= 0.5 * (1 - circuit(gammas, betas, edge=edge, n_layers=n_layers))\n", " return neg_obj\n", "\n", "# initialize optimizer: Adagrad works well empirically\n", "opt = qml.AdagradOptimizer(stepsize=0.5)\n", "\n", "# optimize parameters in objective\n", "params = 0.01 * np.random.rand(2, n_layers)\n", "num_iterations = 10\n", "for i in range(num_iterations):\n", "params = init_params\n", "steps = 10\n", "for i in range(steps):\n", " params = opt.step(objective, params)\n", " if (i + 1) % 5 == 0:\n", " print(\"Objective after step {:5d}: {: .7f}\".format(i + 1, -objective(params)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Step 5**: Extract the most occuring measurement value." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Optimized (gamma, beta) vectors:\n", "[[ 0.28222387 0.29938334]\n", " [-0.19863975 -0.25972002]]\n", "Most frequently sampled bit string is: 0101\n" ] } ], "source": [ " print(\"Objective after step {:5d}: {: .7f}\".format(i + 1, -objective(params)))\n", "\n", "# sample measured bitstrings 100 times\n", "bit_strings = []\n", "n_samples = 100\n", "for i in range(0, n_samples):\n", " bit_strings.append(int(circuit(params[0], params[1], edge=None, n_layers=n_layers)))\n", "\n", "# print optimal parameters and most frequently sampled bitstring\n", "counts = np.bincount(np.array(bit_strings))\n", "most_freq_bit_string = np.argmax(counts)\n", "print(\"Optimized (gamma, beta) vectors:\\n{}\".format(params))\n", "print(\"Most frequently sampled bit string is: \",bin(most_freq_bit_string)[2:].zfill(n_wires))\n" "print(\"Most frequently sampled bit string is: \",bin(most_freq_bit_string)[2:].zfill(n_wires))\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the case where we set n_layers=2, we recover the optimal\n", "objective function $C=4$\n", "\n" ] }, { ... ... @@ -427,13 +374,15 @@ "source": [ "Plotting the results\n", "--------------------\n", "We can plot the distribution of measurements obtained from the optimized circuits. \n", "We can plot the distribution of measurements obtained from the optimized circuits. As\n", "expected for this graph, the partitions 0101 and 1010 are measured with the highest frequencies,\n", "and in the case where we set n_layers=2 we obtain one of the optimal partitions with 100% certainty.\n", "\n" ] }, { "cell_type": "code", "execution_count": 13, "execution_count": 18, "metadata": { "collapsed": false, "jupyter": { ... ... @@ -443,7 +392,7 @@ "outputs": [ { "data": { "image/png": "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\n", "image/png": "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\n", "text/plain": [ "
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!