Skip to content

Commit af62020

Browse files
nquetschlichpre-commit-ci[bot]burgholzer
authored
❇️ Implementations for QCE Submissions (#36)
This PR merges the implementations for 1) the proposed Pre-Compilation approach and 2) the satellite solver use case. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Lukas Burgholzer <lukas.burgholzer@jku.at>
1 parent 587f920 commit af62020

25 files changed

+1960
-15
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,4 @@ repos:
9292
- python_tsp
9393
- networkx
9494
- mqt.ddsim
95+
- pytest

README.md

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ In the current implementation, two case studies are conducted:
2929
1. A SAT Problem: Constraint Satisfaction Problem
3030
2. A Graph-based Optimization Problem: Travelling Salesman Problem
3131

32-
# A SAT Problem: Constraint Satisfaction Problem
32+
## A SAT Problem: Constraint Satisfaction Problem
3333

34-
This exemplary implementation can be found in the [CSP_example.ipynb](src/mqt/problemsolver/csp_example.ipynb) Jupyter notebook.
34+
This exemplary implementation can be found in the [CSP_example.ipynb](notebooks/csp_example.ipynb) Jupyter notebook.
3535
Here, the solution to a Kakuro riddle with a 2x2 grid can be solved for arbitrary sums `s0` to `s3`:
3636

3737
<p align="center">
@@ -40,9 +40,9 @@ Here, the solution to a Kakuro riddle with a 2x2 grid can be solved for arbitrar
4040

4141
MQT ProblemSolver will return valid values to `a`, `b`, `c`, and `d` if a solution exists.
4242

43-
# A Graph-based Optimization Problem: Travelling Salesman Problem
43+
## A Graph-based Optimization Problem: Travelling Salesman Problem
4444

45-
This exemplary implementation can be found in the [TSP_example.ipynb](src/mqt/problemsolver/tsp_example.ipynb) Jupyter notebook.
45+
This exemplary implementation can be found in the [TSP_example.ipynb](notebooks/tsp_example.ipynb) Jupyter notebook.
4646
Here, the solution to a Travelling Salesman Problem with 4 cities can be solved for arbitrary distances `dist_1_2` to `dist_3_4`between the cities.
4747

4848
<p align="center">
@@ -51,6 +51,33 @@ Here, the solution to a Travelling Salesman Problem with 4 cities can be solved
5151

5252
MQT ProblemSolver will return the shortest path visiting all cities as a list.
5353

54+
## Satellite Mission Planning Problem
55+
56+
Additional to the two case studies, we provide a more complex example for the satellite mission planning problem.
57+
The goal is to maximize the accumulated values of all images taken by the satellite while it is often not possible
58+
to take all images since the satellite must rotate and adjust its optics.
59+
60+
In the following example, there are five to-be-captured locations which their assigned value.
61+
62+
<p align="center">
63+
<img src="img/satellite_mission_planning_problem.png" height=200px>
64+
</p>
65+
66+
# Pre-Compilation
67+
68+
Every quantum computing application must be encoded into a quantum circuit and then compiled for a specific device.
69+
This lengthy compilation process is a key bottleneck and intensifies for recurring problems---each of which requires
70+
a new compilation run thus far.
71+
72+
Pre-compilation is a promising approach to overcome this bottleneck.
73+
Beginning with a problem class and suitable quantum algorithm, a **predictive encoding** scheme is applied to encode a
74+
representative problem instance into a general-purpose quantum circuit for that problem class.
75+
Once the real problem instance is known, the previously constructed circuit only needs to be
76+
**adjusted**—with (nearly) no compilation necessary.
77+
78+
Following this approach, we provide a pre-compilation module that can be used to precompile QAOA circuits
79+
for the MaxCut problem.
80+
5481
# Usage
5582

5683
MQT ProblemSolver is available via [PyPI](https://pypi.org/project/mqt.problemsolver/):
@@ -66,12 +93,18 @@ MQT ProblemSolver is available via [PyPI](https://pypi.org/project/mqt.problemso
6693
├── src
6794
│ └── mqt
6895
│ └── problemsolver
69-
│ └── csp.py
96+
│ │ └── csp.py
97+
│ │ └── tsp.py
98+
│ └── satelitesolver
99+
│ │ └── ...
100+
│ └── precompilation
101+
│ └── ...
102+
└── notebooks
103+
│ └── problemsolver
70104
│ └── csp_example.ipynb
71-
│ └── tsp.py
72105
│ └── tsp_example.ipynb
73-
└── tests
74-
└── ...
106+
└── satellitesolver
107+
└── satellitesolver_example.ipynb
75108
```
76109

77110
# References
146 KB
Loading
File renamed without changes.
Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "f8d3cb81",
6+
"metadata": {},
7+
"source": [
8+
"# Pre-Compilation"
9+
]
10+
},
11+
{
12+
"cell_type": "code",
13+
"execution_count": null,
14+
"id": "1ce842bb",
15+
"metadata": {},
16+
"outputs": [],
17+
"source": [
18+
"import pandas as pd\n",
19+
"import numpy as np\n",
20+
"%matplotlib inline\n",
21+
"import matplotlib.pyplot as plt\n",
22+
"\n",
23+
"size = 14\n",
24+
"legendsize = 12"
25+
]
26+
},
27+
{
28+
"cell_type": "code",
29+
"execution_count": null,
30+
"id": "d155a2d1",
31+
"metadata": {},
32+
"outputs": [],
33+
"source": [
34+
"import math\n",
35+
"def orderOfMagnitude(number):\n",
36+
" return -math.ceil(math.log(number, 10))"
37+
]
38+
},
39+
{
40+
"cell_type": "markdown",
41+
"id": "3ad24eb1",
42+
"metadata": {},
43+
"source": [
44+
"# MaxCut"
45+
]
46+
},
47+
{
48+
"cell_type": "code",
49+
"execution_count": null,
50+
"id": "6e39d00d",
51+
"metadata": {},
52+
"outputs": [],
53+
"source": [
54+
"df_maxcut = pd.read_csv('res_qaoa.csv', sep=',')\n",
55+
"df_maxcut['num_qubits'] = df_maxcut['num_qubits'].astype(int)\n",
56+
"df_maxcut"
57+
]
58+
},
59+
{
60+
"cell_type": "code",
61+
"execution_count": null,
62+
"id": "c59a720d",
63+
"metadata": {},
64+
"outputs": [],
65+
"source": [
66+
"def label_encoding (row):\n",
67+
" if row['considered_following_qubits'] == 1 :\n",
68+
" return 'Only Direct Neighbor'\n",
69+
" elif row['considered_following_qubits'] == 1000 :\n",
70+
" return \"All Neighbors\"\n",
71+
"df_maxcut[\"Encoding Prediction\"] = df_maxcut.apply(lambda row: label_encoding(row), axis=1)"
72+
]
73+
},
74+
{
75+
"cell_type": "markdown",
76+
"id": "cc0ff4da",
77+
"metadata": {},
78+
"source": [
79+
"## Graph"
80+
]
81+
},
82+
{
83+
"cell_type": "code",
84+
"execution_count": null,
85+
"id": "d438c6c9",
86+
"metadata": {},
87+
"outputs": [],
88+
"source": [
89+
"for considered_following_qubits in [\"Only Direct Neighbor\", \"All Neighbors\"]:\n",
90+
" for sample_probability in [0.3,0.7]:\n",
91+
" df_subset = df_maxcut[(df_maxcut.sample_probability==sample_probability) & (df_maxcut[\"Encoding Prediction\"]==considered_following_qubits)]\n",
92+
" \n",
93+
" ax1 = df_subset.plot(x='num_qubits', y='cx_count_proposed', color='orange', style=\"o-\", label=\"Proposed Scheme\") \n",
94+
" ax1.tick_params(which='both', labelsize=size)\n",
95+
" df_subset.plot(x='num_qubits', y='cx_count_baseline_O0', color='red', style=\"x-.\", ax=ax1, label=\"Qiskit's O0\")\n",
96+
" df_subset.plot(x='num_qubits', y='cx_count_baseline_O1', color='purple', ax=ax1, style=\".--\", label=\"Qiskit's O1\") \n",
97+
" df_subset.plot(x='num_qubits', y='cx_count_baseline_O2', color='blue', ax=ax1, style=\"+-.\", label=\"Qiskit's O2\") \n",
98+
" df_subset.plot(x='num_qubits', y='cx_count_baseline_O3', color='green', ax=ax1, style=\"^-.\", label=\"Qiskit's O3\") \n",
99+
" \n",
100+
" plt.xlabel(\"Qubits\", size=size)\n",
101+
" plt.ylabel(\"Number of two-qubit gates\", size=size)\n",
102+
" plt.yscale(\"log\")\n",
103+
" plt.legend(fontsize=legendsize)\n",
104+
" plt.savefig('cx_'+str(considered_following_qubits) + '_'+ str(sample_probability)+'.pdf', bbox_inches=\"tight\")\n",
105+
" plt.show()\n",
106+
" \n",
107+
" ax2 = df_subset.plot(x='num_qubits', y='time_proposed', color='orange', style=\"o-\", label=\"Proposed Scheme\") \n",
108+
" ax2.tick_params(which='both', labelsize=size)\n",
109+
" df_subset.plot(x='num_qubits', y='time_baseline_O0', color='red', ax=ax2, style=\"x-.\", label=\"Qiskit's O0\")\n",
110+
" df_subset.plot(x='num_qubits', y='time_baseline_O1', color='purple', ax=ax2, style=\".--\", label=\"Qiskit's O1\") \n",
111+
" df_subset.plot(x='num_qubits', y='time_baseline_O2', color='blue', ax=ax2, style=\"+-.\", label=\"Qiskit's O2\") \n",
112+
" df_subset.plot(x='num_qubits', y='time_baseline_O3', color='green', ax=ax2, style=\"^-.\", label=\"Qiskit's O3\") \n",
113+
" \n",
114+
" plt.xlabel(\"Qubits\", size=size)\n",
115+
" plt.ylabel(\"Time\", size=size)\n",
116+
" plt.yscale(\"log\")\n",
117+
" plt.legend(fontsize=legendsize)\n",
118+
" plt.savefig('time_'+str(considered_following_qubits) + '_'+ str(sample_probability)+'.pdf', bbox_inches=\"tight\")\n",
119+
" plt.show()"
120+
]
121+
},
122+
{
123+
"cell_type": "markdown",
124+
"id": "b9520d0e",
125+
"metadata": {},
126+
"source": [
127+
"## Averages"
128+
]
129+
},
130+
{
131+
"cell_type": "code",
132+
"execution_count": null,
133+
"id": "7f8d8944",
134+
"metadata": {},
135+
"outputs": [],
136+
"source": [
137+
"df_maxcut[\"time_ratio_O3\"] = df_maxcut[\"time_proposed\"]/df_maxcut[\"time_baseline_O3\"]\n",
138+
"df_maxcut[\"order_magnitudes_diff\"] = df_maxcut[\"time_ratio_O3\"].apply(orderOfMagnitude)\n",
139+
"df_maxcut[\"order_magnitudes_diff\"].describe()"
140+
]
141+
},
142+
{
143+
"cell_type": "code",
144+
"execution_count": null,
145+
"id": "da967ba1",
146+
"metadata": {},
147+
"outputs": [],
148+
"source": [
149+
"df_maxcut[\"cx_ratio_O3\"] = df_maxcut['cx_count_proposed']/df_maxcut['cx_count_baseline_O3']\n",
150+
"df_maxcut.cx_ratio_O3.describe()"
151+
]
152+
},
153+
{
154+
"cell_type": "markdown",
155+
"id": "392d94bc",
156+
"metadata": {},
157+
"source": [
158+
"# Satellite"
159+
]
160+
},
161+
{
162+
"cell_type": "code",
163+
"execution_count": null,
164+
"id": "cb53e7d5",
165+
"metadata": {},
166+
"outputs": [],
167+
"source": [
168+
"df_satellite = pd.read_csv('res_satellite.csv', sep=',')\n",
169+
"df_satellite['num_qubits'] = df_satellite['num_qubits'].astype(int)\n",
170+
"df_satellite"
171+
]
172+
},
173+
{
174+
"cell_type": "markdown",
175+
"id": "9f743f84",
176+
"metadata": {},
177+
"source": [
178+
"## Graphs"
179+
]
180+
},
181+
{
182+
"cell_type": "code",
183+
"execution_count": null,
184+
"id": "8a50d9df",
185+
"metadata": {},
186+
"outputs": [],
187+
"source": [
188+
"df_subset = df_satellite[(df_satellite.sample_probability==0.4) & (df_satellite.considered_following_qubits==1)]\n",
189+
"\n",
190+
"ax1 = df_subset.plot(x='num_qubits', y='cx_count_proposed', color='orange', style=\"o-\", label=\"Proposed Scheme\") \n",
191+
"ax1.tick_params(which='both', labelsize=size)\n",
192+
"df_subset.plot(x='num_qubits', y='cx_count_baseline_O0', color='red', style=\"x-.\", ax=ax1, label=\"Qiskit's O0\")\n",
193+
"df_subset.plot(x='num_qubits', y='cx_count_baseline_O1', color='purple', ax=ax1, style=\".--\", label=\"Qiskit's O1\") \n",
194+
"df_subset.plot(x='num_qubits', y='cx_count_baseline_O2', color='blue', ax=ax1, style=\"+-.\", label=\"Qiskit's O2\") \n",
195+
"df_subset.plot(x='num_qubits', y='cx_count_baseline_O3', color='green', ax=ax1, style=\"^-.\", label=\"Qiskit's O3\") \n",
196+
" \n",
197+
"\n",
198+
"plt.ylim(10e0*1.5, 10e2)\n",
199+
"plt.xlabel(\"Qubits\", size=size)\n",
200+
"plt.ylabel(\"Number of two-qubit gates\", size=size)\n",
201+
"plt.yscale(\"log\")\n",
202+
"plt.legend(fontsize=legendsize)\n",
203+
"plt.savefig('sat_cx.pdf', bbox_inches=\"tight\")\n",
204+
"plt.show()\n",
205+
"\n",
206+
"ax2 = df_subset.plot(x='num_qubits', y='time_proposed', color='orange', style=\"o-\", label=\"Proposed Scheme\") \n",
207+
"ax2.tick_params(which='both', labelsize=size)\n",
208+
"df_subset.plot(x='num_qubits', y='time_baseline_O0', color='red', ax=ax2, style=\"x-.\", label=\"Qiskit's O0\")\n",
209+
"df_subset.plot(x='num_qubits', y='time_baseline_O1', color='purple', ax=ax2, style=\".--\", label=\"Qiskit's O1\") \n",
210+
"df_subset.plot(x='num_qubits', y='time_baseline_O2', color='blue', ax=ax2, style=\"+-.\", label=\"Qiskit's O2\") \n",
211+
"df_subset.plot(x='num_qubits', y='time_baseline_O3', color='green', ax=ax2, style=\"^-.\", label=\"Qiskit's O3\") \n",
212+
" \n",
213+
"\n",
214+
"plt.xlabel(\"Qubits\", size=size)\n",
215+
"plt.ylabel(\"Time\", size=size)\n",
216+
"\n",
217+
"plt.yscale(\"log\")\n",
218+
"plt.legend(fontsize=legendsize, loc=\"center right\")\n",
219+
"plt.savefig('sat_time.pdf', bbox_inches=\"tight\")\n",
220+
"plt.show()"
221+
]
222+
},
223+
{
224+
"cell_type": "code",
225+
"execution_count": null,
226+
"id": "b269ff67",
227+
"metadata": {},
228+
"outputs": [],
229+
"source": [
230+
"df_satellite[\"time_ratio_O3\"] = df_satellite[\"time_proposed\"]/df_satellite[\"time_baseline_O3\"]\n",
231+
"df_satellite[\"order_magnitudes_diff\"] = df_satellite[\"time_ratio_O3\"].apply(orderOfMagnitude)\n",
232+
"df_satellite[\"order_magnitudes_diff\"].describe()"
233+
]
234+
},
235+
{
236+
"cell_type": "code",
237+
"execution_count": null,
238+
"id": "cc181700",
239+
"metadata": {},
240+
"outputs": [],
241+
"source": [
242+
"df_satellite[\"cx_ratio_O3\"] = df_satellite[\"cx_count_proposed\"]/df_satellite[\"cx_count_baseline_O3\"]\n",
243+
"df_satellite.cx_ratio_O3.describe()"
244+
]
245+
},
246+
{
247+
"cell_type": "code",
248+
"execution_count": null,
249+
"id": "57aa8906",
250+
"metadata": {},
251+
"outputs": [],
252+
"source": []
253+
}
254+
],
255+
"metadata": {
256+
"kernelspec": {
257+
"display_name": "Python 3 (ipykernel)",
258+
"language": "python",
259+
"name": "python3"
260+
},
261+
"language_info": {
262+
"codemirror_mode": {
263+
"name": "ipython",
264+
"version": 3
265+
},
266+
"file_extension": ".py",
267+
"mimetype": "text/x-python",
268+
"name": "python",
269+
"nbconvert_exporter": "python",
270+
"pygments_lexer": "ipython3"
271+
}
272+
},
273+
"nbformat": 4,
274+
"nbformat_minor": 5
275+
}

0 commit comments

Comments
 (0)