Skip to content

Commit 8f9dfb4

Browse files
authored
Moreexamples (#54)
* add two examples * Add fix_one_node highest-degree comment and new example notebooks to README
1 parent 2b76889 commit 8f9dfb4

6 files changed

Lines changed: 730 additions & 5 deletions

File tree

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ A flexible, modular Python library for the [Quantum Approximate Optimization Alg
1919
- [Further Parameters](#further-parameters)
2020
- [Extracting Results](#extract-results)
2121
- [Multi-Angle QAOA](#multi-angle-qaoa)
22+
- [Fixing One Node to Reduce Circuit depth/width](#fixing-one-node-to-reduce-circuit-size)
2223
- [Building Circuits like Lego](#building-circuits-like-lego)
2324
- [Minimizing Circuit Depth](#minimizing-depth-of-phase-separating-operator)
2425
- [Repository Structure](#repository-structure)
@@ -148,6 +149,10 @@ This library already contains several standard implementations.
148149

149150
It is **very easy to extend this list** by implementing the abstract methods of the base classes above. Feel free to fork the repo and open a pull request!
150151

152+
See [examples/MaxCut/OverlapInitialState.ipynb](examples/MaxCut/OverlapInitialState.ipynb) for a study of how the overlap between the initial state and the X-mixer ground state affects QAOA performance at various circuit depths.
153+
154+
See [examples/MaxCut/KCutExamples.ipynb](examples/MaxCut/KCutExamples.ipynb) for worked examples of Max k-cut using both one-hot and binary encodings.
155+
151156
For example, to set up QAOA for MaxCut using the X-mixer and $|+\rangle^{\otimes n}$ as the initial state:
152157

153158
```python
@@ -266,6 +271,22 @@ Implement `get_num_parameters()` in a custom component to enable multi-angle sup
266271

267272
---
268273

274+
## Fixing One Node to Reduce Circuit Size
275+
276+
The MaxCut (and Max k-cut) problem exhibits a **flip symmetry**: swapping all partition labels yields an equally valid solution. This symmetry allows one node to be fixed to a specific partition, removing it from the circuit entirely.
277+
278+
The node selected for fixing is always the **highest-degree node**. Fixing this node eliminates CZ gates equal to its degree — the maximum possible reduction for a single fixed node.
279+
280+
Enable this via the `fix_one_node` flag on any graph problem:
281+
282+
```python
283+
problem = problems.MaxCut(G, fix_one_node=True)
284+
```
285+
286+
See [examples/MaxCut/FixOneQubit.ipynb](examples/MaxCut/FixOneQubit.ipynb) for a worked example showing the circuit-size reduction and that the approximation quality is preserved.
287+
288+
---
289+
269290
## Minimizing Depth of Phase Separating Operator
270291

271292
Assuming all-to-all connectivity of qubits, one can minimize the circuit depth of the phase separating operator by solving the minimum edge colouring problem. This is implemented in [GraphHandler](qaoa/util/graphutils.py) and is invoked automatically. An [example](examples/MaxCut/MinimalDepth.ipynb) output is shown below:

examples/MaxCut/FixOneQubit.ipynb

Lines changed: 331 additions & 0 deletions
Large diffs are not rendered by default.

examples/MaxCut/OverlapInitialState.ipynb

Lines changed: 363 additions & 0 deletions
Large diffs are not rendered by default.

qaoa/problems/graph_problem.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ class GraphProblem(Problem):
1515
Attributes:
1616
G: The graph to be used in the problem.
1717
N_qubits_per_node (int): Number of qubits per node.
18-
fix_one_node (bool): If True, fixes the last node to "color1".
18+
fix_one_node (bool): If True, fixes the highest-degree node to "color1",
19+
reducing circuit size. The highest-degree node is chosen to maximize the
20+
number of entangling gates eliminated.
1921
2022
Methods:
2123
create_edge_circuit(theta): Abstract method to create circuit for an edge
@@ -30,17 +32,19 @@ def __init__(
3032
self,
3133
G,
3234
N_qubits_per_node=1,
33-
fix_one_node: bool = False, # this fixes the last node to color 1, i.e., one qubit gets removed
35+
fix_one_node: bool = False, # fixes the highest-degree node to color 1, removing it from the circuit and eliminating entangling gates proportional to its degree
3436
) -> None:
3537
"""
3638
Args:
3739
G: The graph to be used in the problem.
3840
N_qubits_per_node (int): Number of qubits per node.
39-
fix_one_node (bool): If True, fixes the last node to "color1".
41+
fix_one_node (bool): If True, fixes the highest-degree node to "color1", reducing
42+
the circuit size. The highest-degree node is chosen to maximize the number of
43+
entangling gates eliminated (proportional to the degree of the fixed node).
4044
"""
4145
super().__init__()
4246

43-
# fixes the last node to "color1"
47+
# fixes the highest-degree node (node n-1 after relabeling) to "color1"
4448
self.fix_one_node = fix_one_node
4549

4650
# ensure graph has labels 0, 1, ..., num_V-1

qaoa/utils/graphutils.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ def __init__(self, G):
3636

3737
# ensure graph has labels 0, 1, ..., num_V-1
3838
G_int = self.__ensure_integer_labels__(G)
39-
# relabel to make node n-1 the one with maximum degree
39+
# relabel to make node n-1 the one with maximum degree; when fix_one_node=True
40+
# this node is fixed (removed from the circuit), maximizing the number of entangling
41+
# gates eliminated (proportional to the degree of the fixed node)
4042
self.G = self.__get_graph_maxdegree_last_node__(G_int)
4143
# to avoid a deep circuit, we partition the edges into sets which can be executed in parallel
4244
if not nx.is_isomorphic(G, self.G):

qaoa/utils/plotroutines.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@ def plot_ApproximationRatio(
130130

131131
fig, ax = _get_fig_ax(fig)
132132
ax.hlines(1, 1, maxdepth, linestyles="solid", colors="black")
133+
# Normalized approximation ratio for a minimization objective.
134+
# Here mincost is the optimal (most negative) value and maxcost the worst.
135+
# This maps exp = maxcost → 0 (worst) and exp = mincost → 1 (optimal).
136+
# Hence we use (maxcost - exp) / (maxcost - mincost).
133137
ax.plot(
134138
np.arange(1, maxdepth + 1),
135139
(maxcost - exp) / (maxcost - mincost),

0 commit comments

Comments
 (0)