{
"cells": [
{
"cell_type": "code",
"execution_count": 35,
"id": "a005e247",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['Ket v0.10.0',\n",
" 'libket v0.7.1 [rustc 1.97.0 (2d8144b78 2026-07-07) x86_64-unknown-linux-gnu]',\n",
" 'kbw v0.5.1 [rustc 1.97.0 (2d8144b78 2026-07-07) x86_64-unknown-linux-gnu]']"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from typing import Callable\n",
"from functools import partial\n",
"from functools import reduce\n",
"from operator import add\n",
"\n",
"from scipy.optimize import minimize, OptimizeResult\n",
"from IPython.display import display\n",
"\n",
"from ket import *\n",
"from ket import ket_version\n",
"\n",
"ket_version()"
]
},
{
"cell_type": "markdown",
"id": "7ce6969b",
"metadata": {},
"source": [
"# Quantum Approximate Optimization Algorithm (QAOA)\n",
"\n",
"The **Quantum Approximate Optimization Algorithm (QAOA)** is a hybrid quantum-classical\n",
"variational algorithm designed to find approximate solutions to combinatorial optimization problems.\n",
"Tailored for near-term (NISQ) devices, QAOA functions as a discretized version of adiabatic quantum computing.\n",
"\n",
"At its core, the algorithm prepares a uniform initial quantum state $|+\\rangle^{\\otimes n}$, which then undergoes\n",
"$p$ alternating layers of unitary evolution driven by two complementary Hamiltonians. Finally, the circuit is\n",
"measured and the evolution parameters are fine-tuned by a classical optimizer.\n",
"\n",
"To understand how QAOA operates, let's explore its three main building blocks:"
]
},
{
"cell_type": "markdown",
"id": "d281d2de",
"metadata": {},
"source": [
"## 1. Problem Hamiltonian ($H_C$)\n",
"\n",
"This block encodes the classical objective (or cost) function of our optimization problem into a quantum format.\n",
"\n",
"- **Role:** The decision variables of the problem are mapped to Pauli-Z operators in the computational basis. The optimal solution corresponds to the lowest energy eigenstate (the ground state) of this Hamiltonian.\n",
"\n",
"- **Circuit Evolution:** The quantum state evolves under the problem Hamiltonian according to the operator: $\\hat U_C(\\gamma_k) = e^{-i\\gamma_k H_C}$"
]
},
{
"cell_type": "markdown",
"id": "83b2cc21",
"metadata": {},
"source": [
"## 2. Mixer Hamiltonian ($H_M$)\n",
"\n",
"To effectively explore the solution space and prevent the system from getting stuck, we introduce the mixer Hamiltonian.\n",
"\n",
"- **Role:** The fundamental requirement for $H_M$ is that it **must not commute** with the problem Hamiltonian $H_C$. The standard implementation uses a sum of Pauli-X operators acting on all qubits.\n",
"\n",
"- **Circuit Evolution:** The mixer creates transitions between different computational basis configurations, driven by the operator: $\\hat U_M(\\beta_k) = e^{-i\\beta_k H_M}$"
]
},
{
"cell_type": "markdown",
"id": "16c57984",
"metadata": {},
"source": [
"## 3. Classical Optimizer\n",
"\n",
"The iterative search for optimal parameters is handed over to a classical processor.\n",
"\n",
"- **Role:** By measuring the final state of the quantum circuit, we obtain the expected value of the cost function: $F(\\gamma, \\beta) = \\langle\\psi(\\gamma, \\beta)|H_C|\\psi(\\gamma, \\beta)\\rangle$. The classical optimizer evaluates this outcome and computes a new set of angles, $\\gamma$ and $\\beta$, aiming to minimize this expected value in the next iteration.\n",
"\n",
"- **Significance:** Once the optimizer converges on the ideal parameters $(\\gamma, \\beta)$, the quantum circuit will output the state encoding the approximate solution with high probability. Selecting a robust classical optimization routine is crucial to avoiding local minima and mitigating challenges like _barren plateaus_."
]
},
{
"cell_type": "markdown",
"id": "4a682a55",
"metadata": {},
"source": [
"## Implementation with Ket\n",
"\n",
"Let's implement the base QAOA structure using `ket`. We define functions to:\n",
"\n",
"1. Apply a single QAOA layer (`qaoa_layer`).\n",
"2. Build the full $p$-layer ansatz (`ansatz`).\n",
"3. Execute the complete hybrid optimization loop (`qaoa`).\n",
"\n",
"Ket's {func}`~ket.gates.evolve` function accepts a {class}`~ket.expv.Hamiltonian` object and automatically\n",
"decomposes the time-evolution operator $e^{-i\\theta H}$ into native quantum gates, making the implementation\n",
"concise and readable."
]
},
{
"cell_type": "code",
"execution_count": 36,
"id": "530bd12f",
"metadata": {},
"outputs": [],
"source": [
"def qaoa_layer(\n",
" problem_h: Callable[[Quant], Hamiltonian],\n",
" mixer_h: Callable[[Quant], Hamiltonian],\n",
" qubits: Quant,\n",
" gamma: float,\n",
" beta: float,\n",
"):\n",
" \"\"\"\n",
" Applies a single layer (p=1) of the QAOA Ansatz to the provided qubits.\n",
"\n",
" Args:\n",
" problem_h: Function that takes the allocated qubits and returns the problem Hamiltonian (cost function).\n",
" mixer_h: Function that takes the allocated qubits and returns the mixer Hamiltonian.\n",
" qubits: Reference to the qubits allocated in the current process.\n",
" gamma: Variational parameter associated with the evolution of the problem Hamiltonian.\n",
" beta: Variational parameter associated with the evolution of the mixer Hamiltonian.\n",
" \"\"\"\n",
" evolve(problem_h(qubits) * gamma)\n",
" evolve(mixer_h(qubits) * beta)\n",
"\n",
"\n",
"def ansatz(\n",
" problem_h: Callable[[Quant], Hamiltonian],\n",
" mixer_h: Callable[[Quant], Hamiltonian],\n",
" initial_state: Callable[[any], None],\n",
" qubits: Quant,\n",
" gamma: list[float],\n",
" beta: list[float],\n",
"):\n",
" \"\"\"\n",
" Constructs the complete QAOA quantum circuit, applying the initial state\n",
" and the 'p' layers of alternating evolution.\n",
"\n",
" Args:\n",
" problem_h: Problem Hamiltonian generator function.\n",
" mixer_h: Mixer Hamiltonian generator function.\n",
" initial_state: Function that prepares the appropriate initial state on the qubits\n",
" (e.g., uniform superposition with H gates, or Dicke state for XY Mixer).\n",
" qubits: Reference to the circuit qubits.\n",
" gamma: List with the 'p' variational gamma parameters.\n",
" beta: List with the 'p' variational beta parameters.\n",
" \"\"\"\n",
" initial_state(qubits)\n",
" for g, b in zip(gamma, beta):\n",
" qaoa_layer(problem_h, mixer_h, qubits, g, b)\n",
"\n",
"\n",
"def qaoa(\n",
" problem_h: Callable[[Quant], Hamiltonian],\n",
" mixer_h: Callable[[Quant], Hamiltonian],\n",
" initial_state: Callable[[any], None],\n",
" num_qubits: int,\n",
" p: int,\n",
" dt: float = 0.5,\n",
" method: str = \"COBYLA\",\n",
") -> tuple[OptimizeResult, Samples]:\n",
" \"\"\"\n",
" Executes the QAOA hybrid (classical-quantum) optimization loop.\n",
"\n",
" Initializes parameters inspired by a quantum annealing process\n",
" (increasing gamma, decreasing beta) and uses a classical optimizer to\n",
" find the configuration that minimizes the expected value of the problem Hamiltonian.\n",
"\n",
" Args:\n",
" problem_h: Problem Hamiltonian generator function.\n",
" mixer_h: Mixer Hamiltonian generator function.\n",
" initial_state: Initial state preparation function.\n",
" num_qubits: Total number of qubits required for the problem.\n",
" p: Number of layers (depth) of the QAOA Ansatz.\n",
" dt: Scale factor for the parameter initialization heuristic (default: 0.5).\n",
" method: SciPy classical optimization algorithm to use (default: \"COBYLA\").\n",
"\n",
" Returns:\n",
" A tuple containing:\n",
" - The OptimizeResult object returned by SciPy with optimization details.\n",
" - The final sampling of the optimized state (measurements and counts).\n",
" \"\"\"\n",
"\n",
" def objective(parameters, final=False):\n",
" gamma = parameters[:p]\n",
" beta = parameters[p:]\n",
"\n",
" # Instantiates a new Ket Process\n",
" process = Process(num_qubits=num_qubits)\n",
" qubits = process.alloc(num_qubits)\n",
" ansatz(problem_h, mixer_h, initial_state, qubits, gamma, beta)\n",
"\n",
" if final:\n",
" # Samples the final state to retrieve likely solutions\n",
" return sample(qubits, 100)\n",
"\n",
" # Returns the energy (expected value) to the classical optimizer\n",
" result = exp_value(problem_h(qubits)).get()\n",
" print(f\"{result=}\", end=\"\\r\")\n",
" return result\n",
"\n",
" # Initialization heuristic based on annealing\n",
" first_gamma = [i / p * dt for i in range(1, p + 1)] # Increasing\n",
" first_beta = [(1 - i / p) * dt for i in range(0, p)] # Decreasing\n",
"\n",
" # Classical optimization loop\n",
" res = minimize(\n",
" objective,\n",
" first_gamma + first_beta, # Gamma comes first, Beta second\n",
" method=method,\n",
" )\n",
"\n",
" # Execute the circuit one last time with optimal parameters to get the probability distribution\n",
" final_sample = objective(res.x, final=True)\n",
"\n",
" return res, final_sample"
]
},
{
"cell_type": "markdown",
"id": "7542e93e",
"metadata": {},
"source": [
"## Example 1: Max-Cut\n",
"\n",
"The **Max-Cut** problem is one of the most widely used benchmarks for quantum optimization algorithms.\n",
"It is an NP-Hard graph problem: finding an exact solution becomes classically intractable as the number\n",
"of vertices grows.\n",
"\n",
"Given an undirected graph $G = (V, E)$, the objective is to partition the vertices into two disjoint\n",
"sets $A$ and $B$ such that the number of edges crossing the partition is maximized.\n",
"\n",
"To model this on a quantum computer, we map each graph vertex to a qubit:\n",
"\n",
"- State $|0\\rangle \\rightarrow$ Vertex belongs to set $A$.\n",
"- State $|1\\rangle \\rightarrow$ Vertex belongs to set $B$."
]
},
{
"cell_type": "markdown",
"id": "7a904b24",
"metadata": {},
"source": [
"### Max-Cut Hamiltonian Formulation\n",
"\n",
"For QAOA, we need to mathematically formulate a cost function that evaluates the quality of our cut using Pauli operators. The Pauli-Z operator is perfect for this:\n",
"\n",
"- $\\left<0|Z|0\\right> = +1$\n",
"- $\\left<1|Z|1\\right> = -1$\n",
"\n",
"For any two vertices connected by an edge $(u, v)$, their interaction is measured by the product $Z_u Z_v$:\n",
"\n",
"- If both vertices are in the **same set** ($\\left|00\\right>$ or $\\left|11\\right>$), the product $Z_u Z_v$ is $+1$.\n",
"- If they are in **different sets** ($\\left|01\\right>$ or $\\left|10\\right>$), the product $Z_u Z_v$ is $-1$.\n",
"\n",
"We can express the contribution of a single edge to our cut as $\\frac{1}{2}(1 - Z_u Z_v)$. This evaluates to $1$ if the edge is cut, and $0$ if it is not.\n",
"\n",
"The total Hamiltonian is the sum of these expressions across all edges in the graph. Since classical optimizers typically aim to **minimize** a function, we multiply the Hamiltonian by $-1$. This ensures that the state representing the maximum number of cuts corresponds to the lowest possible energy (the ground state):\n",
"\n",
"$$H_C = -\\frac{1}{2} \\sum_{(u,\\ v) \\in E} (1 - Z_u Z_v)$$"
]
},
{
"cell_type": "markdown",
"id": "plot_intro",
"metadata": {},
"source": [
"### Graph Visualization\n",
"\n",
"Before solving, let's visualize our problem graph using Plotly for an interactive view.\n",
"We define a helper function that draws the graph and highlights cut edges based on a given\n",
"partition of vertices."
]
},
{
"cell_type": "code",
"execution_count": 37,
"id": "maxcut_plotly_func",
"metadata": {},
"outputs": [],
"source": [
"def plot_maxcut_graph(\n",
" graph_edges: list[tuple[int, int]],\n",
" num_nodes: int,\n",
" qubits_state: list[int] | int,\n",
" title: str = \"Max-Cut Graph\",\n",
"):\n",
" \"\"\"\n",
" Plots the Max-Cut problem graph using Plotly, coloring nodes according to their\n",
" partition assignment and highlighting the cut edges.\n",
"\n",
" Args:\n",
" graph_edges: List of tuples representing the graph edges.\n",
" num_nodes: Total number of nodes/qubits.\n",
" qubits_state: List where the index is the node and the value is the state (0 or 1).\n",
" title: Plot title.\n",
" \"\"\"\n",
" import networkx as nx\n",
" import plotly.graph_objects as go\n",
"\n",
" if isinstance(qubits_state, int):\n",
" qubits_state = list(map(int, f\"{qubits_state:0{num_nodes}b}\"))\n",
"\n",
" G = nx.Graph()\n",
" G.add_nodes_from(range(num_nodes))\n",
" G.add_edges_from(graph_edges)\n",
" pos = nx.spring_layout(G, seed=42)\n",
"\n",
" # --- Edge traces ---\n",
" cut_edge_x, cut_edge_y = [], []\n",
" non_cut_edge_x, non_cut_edge_y = [], []\n",
" for u, v in graph_edges:\n",
" x0, y0 = pos[u]\n",
" x1, y1 = pos[v]\n",
" if qubits_state[u] != qubits_state[v]:\n",
" cut_edge_x += [x0, x1, None]\n",
" cut_edge_y += [y0, y1, None]\n",
" else:\n",
" non_cut_edge_x += [x0, x1, None]\n",
" non_cut_edge_y += [y0, y1, None]\n",
"\n",
" edge_traces = [\n",
" go.Scatter(\n",
" x=cut_edge_x,\n",
" y=cut_edge_y,\n",
" mode=\"lines\",\n",
" line=dict(width=4, color=\"#e74c3c\"),\n",
" name=\"Cut edge\",\n",
" hoverinfo=\"none\",\n",
" ),\n",
" go.Scatter(\n",
" x=non_cut_edge_x,\n",
" y=non_cut_edge_y,\n",
" mode=\"lines\",\n",
" line=dict(width=2, color=\"#aaaaaa\", dash=\"dash\"),\n",
" name=\"Non-cut edge\",\n",
" hoverinfo=\"none\",\n",
" ),\n",
" ]\n",
"\n",
" # --- Node traces ---\n",
" node_x = [pos[n][0] for n in G.nodes()]\n",
" node_y = [pos[n][1] for n in G.nodes()]\n",
" node_colors = [\"#e67e22\" if qubits_state[n] == 1 else \"#3498db\" for n in G.nodes()]\n",
" node_text = [\n",
" f\"Node {n}
Set {'B' if qubits_state[n] == 1 else 'A'} (|{qubits_state[n]}⟩)\"\n",
" for n in G.nodes()\n",
" ]\n",
" node_labels = [str(n) for n in G.nodes()]\n",
"\n",
" node_trace = go.Scatter(\n",
" x=node_x,\n",
" y=node_y,\n",
" mode=\"markers+text\",\n",
" hoverinfo=\"text\",\n",
" hovertext=node_text,\n",
" text=node_labels,\n",
" textposition=\"middle center\",\n",
" textfont=dict(size=14, color=\"white\"),\n",
" marker=dict(\n",
" size=40,\n",
" color=node_colors,\n",
" line=dict(width=2, color=\"#333\"),\n",
" ),\n",
" name=\"Nodes\",\n",
" showlegend=False,\n",
" )\n",
"\n",
" num_cuts = sum(1 for u, v in graph_edges if qubits_state[u] != qubits_state[v])\n",
"\n",
" fig = go.Figure(\n",
" data=edge_traces + [node_trace],\n",
" layout=go.Layout(\n",
" title=dict(\n",
" text=f\"{title} — {num_cuts}/{len(graph_edges)} edges cut\", x=0.5\n",
" ),\n",
" showlegend=True,\n",
" hovermode=\"closest\",\n",
" margin=dict(b=20, l=5, r=5, t=50),\n",
" xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),\n",
" yaxis=dict(showgrid=False, zeroline=False, showticklabels=False),\n",
" legend=dict(x=0, y=1),\n",
" ),\n",
" )\n",
" fig.show()"
]
},
{
"cell_type": "markdown",
"id": "prob_instance",
"metadata": {},
"source": [
"### Problem Instance\n",
"\n",
"Let's define our test graph: 5 nodes and 6 edges. The initial partition shown below\n",
"is just a sample — the QAOA optimizer will find the best one."
]
},
{
"cell_type": "code",
"execution_count": 38,
"id": "ffb1cf5b",
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.plotly.v1+json": {
"config": {
"plotlyServerURL": "https://plot.ly"
},
"data": [
{
"hoverinfo": "none",
"line": {
"color": "#e74c3c",
"width": 4
},
"mode": "lines",
"name": "Cut edge",
"type": "scatter",
"x": [
1,
0.24537112788370613,
null,
0.21658684233928793,
0.24537112788370613,
null,
-0.7503722096196979,
-0.7115857606032955,
null
],
"y": [
0.03492797469890115,
-0.3945287104413233,
null,
0.4084010375951407,
-0.3945287104413233,
null,
0.4088120458522651,
-0.45761234770498316,
null
]
},
{
"hoverinfo": "none",
"line": {
"color": "#aaaaaa",
"dash": "dash",
"width": 2
},
"mode": "lines",
"name": "Non-cut edge",
"type": "scatter",
"x": [
1,
0.21658684233928793,
null,
0.21658684233928793,
-0.7503722096196979,
null,
0.24537112788370613,
-0.7115857606032955,
null
],
"y": [
0.03492797469890115,
0.4084010375951407,
null,
0.4084010375951407,
0.4088120458522651,
null,
-0.3945287104413233,
-0.45761234770498316,
null
]
},
{
"hoverinfo": "text",
"hovertext": [
"Node 0
Set B (|1⟩)",
"Node 1
Set B (|1⟩)",
"Node 2
Set A (|0⟩)",
"Node 3
Set B (|1⟩)",
"Node 4
Set A (|0⟩)"
],
"marker": {
"color": [
"#e67e22",
"#e67e22",
"#3498db",
"#e67e22",
"#3498db"
],
"line": {
"color": "#333",
"width": 2
},
"size": 40
},
"mode": "markers+text",
"name": "Nodes",
"showlegend": false,
"text": [
"0",
"1",
"2",
"3",
"4"
],
"textfont": {
"color": "white",
"size": 14
},
"textposition": "middle center",
"type": "scatter",
"x": [
1,
0.21658684233928793,
0.24537112788370613,
-0.7503722096196979,
-0.7115857606032955
],
"y": [
0.03492797469890115,
0.4084010375951407,
-0.3945287104413233,
0.4088120458522651,
-0.45761234770498316
]
}
],
"layout": {
"hovermode": "closest",
"legend": {
"x": 0,
"y": 1
},
"margin": {
"b": 20,
"l": 5,
"r": 5,
"t": 50
},
"showlegend": true,
"template": {
"data": {
"bar": [
{
"error_x": {
"color": "#2a3f5f"
},
"error_y": {
"color": "#2a3f5f"
},
"marker": {
"line": {
"color": "#E5ECF6",
"width": 0.5
},
"pattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
}
},
"type": "bar"
}
],
"barpolar": [
{
"marker": {
"line": {
"color": "#E5ECF6",
"width": 0.5
},
"pattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
}
},
"type": "barpolar"
}
],
"carpet": [
{
"aaxis": {
"endlinecolor": "#2a3f5f",
"gridcolor": "white",
"linecolor": "white",
"minorgridcolor": "white",
"startlinecolor": "#2a3f5f"
},
"baxis": {
"endlinecolor": "#2a3f5f",
"gridcolor": "white",
"linecolor": "white",
"minorgridcolor": "white",
"startlinecolor": "#2a3f5f"
},
"type": "carpet"
}
],
"choropleth": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "choropleth"
}
],
"contour": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "contour"
}
],
"contourcarpet": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "contourcarpet"
}
],
"heatmap": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "heatmap"
}
],
"histogram": [
{
"marker": {
"pattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
}
},
"type": "histogram"
}
],
"histogram2d": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "histogram2d"
}
],
"histogram2dcontour": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "histogram2dcontour"
}
],
"mesh3d": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "mesh3d"
}
],
"parcoords": [
{
"line": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "parcoords"
}
],
"pie": [
{
"automargin": true,
"type": "pie"
}
],
"scatter": [
{
"fillpattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
},
"type": "scatter"
}
],
"scatter3d": [
{
"line": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatter3d"
}
],
"scattercarpet": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattercarpet"
}
],
"scattergeo": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattergeo"
}
],
"scattergl": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattergl"
}
],
"scattermap": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattermap"
}
],
"scattermapbox": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattermapbox"
}
],
"scatterpolar": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterpolar"
}
],
"scatterpolargl": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterpolargl"
}
],
"scatterternary": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterternary"
}
],
"surface": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "surface"
}
],
"table": [
{
"cells": {
"fill": {
"color": "#EBF0F8"
},
"line": {
"color": "white"
}
},
"header": {
"fill": {
"color": "#C8D4E3"
},
"line": {
"color": "white"
}
},
"type": "table"
}
]
},
"layout": {
"annotationdefaults": {
"arrowcolor": "#2a3f5f",
"arrowhead": 0,
"arrowwidth": 1
},
"autotypenumbers": "strict",
"coloraxis": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"colorscale": {
"diverging": [
[
0,
"#8e0152"
],
[
0.1,
"#c51b7d"
],
[
0.2,
"#de77ae"
],
[
0.3,
"#f1b6da"
],
[
0.4,
"#fde0ef"
],
[
0.5,
"#f7f7f7"
],
[
0.6,
"#e6f5d0"
],
[
0.7,
"#b8e186"
],
[
0.8,
"#7fbc41"
],
[
0.9,
"#4d9221"
],
[
1,
"#276419"
]
],
"sequential": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"sequentialminus": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
]
},
"colorway": [
"#636efa",
"#EF553B",
"#00cc96",
"#ab63fa",
"#FFA15A",
"#19d3f3",
"#FF6692",
"#B6E880",
"#FF97FF",
"#FECB52"
],
"font": {
"color": "#2a3f5f"
},
"geo": {
"bgcolor": "white",
"lakecolor": "white",
"landcolor": "#E5ECF6",
"showlakes": true,
"showland": true,
"subunitcolor": "white"
},
"hoverlabel": {
"align": "left"
},
"hovermode": "closest",
"mapbox": {
"style": "light"
},
"paper_bgcolor": "white",
"plot_bgcolor": "#E5ECF6",
"polar": {
"angularaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
},
"bgcolor": "#E5ECF6",
"radialaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
}
},
"scene": {
"xaxis": {
"backgroundcolor": "#E5ECF6",
"gridcolor": "white",
"gridwidth": 2,
"linecolor": "white",
"showbackground": true,
"ticks": "",
"zerolinecolor": "white"
},
"yaxis": {
"backgroundcolor": "#E5ECF6",
"gridcolor": "white",
"gridwidth": 2,
"linecolor": "white",
"showbackground": true,
"ticks": "",
"zerolinecolor": "white"
},
"zaxis": {
"backgroundcolor": "#E5ECF6",
"gridcolor": "white",
"gridwidth": 2,
"linecolor": "white",
"showbackground": true,
"ticks": "",
"zerolinecolor": "white"
}
},
"shapedefaults": {
"line": {
"color": "#2a3f5f"
}
},
"ternary": {
"aaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
},
"baxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
},
"bgcolor": "#E5ECF6",
"caxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
}
},
"title": {
"x": 0.05
},
"xaxis": {
"automargin": true,
"gridcolor": "white",
"linecolor": "white",
"ticks": "",
"title": {
"standoff": 15
},
"zerolinecolor": "white",
"zerolinewidth": 2
},
"yaxis": {
"automargin": true,
"gridcolor": "white",
"linecolor": "white",
"ticks": "",
"title": {
"standoff": 15
},
"zerolinecolor": "white",
"zerolinewidth": 2
}
}
},
"title": {
"text": "Sample Partition (not optimal) — 3/6 edges cut",
"x": 0.5
},
"xaxis": {
"showgrid": false,
"showticklabels": false,
"zeroline": false
},
"yaxis": {
"showgrid": false,
"showticklabels": false,
"zeroline": false
}
}
},
"text/html": [
"