-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprojectq_qaoa_maxcut.py
70 lines (50 loc) · 1.68 KB
/
projectq_qaoa_maxcut.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
from collections import Counter
from functools import reduce
from networkx import Graph
from projectq import MainEngine
from projectq.ops import All, H, Measure, QubitOperator, Rx, Rzz, X
from scipy.optimize import minimize
def mixer(g: Graph, beta: float):
for n in g:
Rx(2*beta) | n
def problem(g: Graph, gamma: float):
for i, j in g.edges():
Rzz(2*gamma) | (i, j)
def prepare_state(g: Graph, theta: list[float]):
mid = len(theta) // 2
betas = theta[:mid]
gammas = theta[mid:]
qubits = list(g.nodes())
# make sure all qubits are zero
All(Measure) | qubits
for n in g:
if int(n):
X | n
All(H) | qubits
for i in range(mid):
problem(g, gammas[i])
mixer(g, betas[i])
eng.flush()
def sample_circuit(g: Graph, theta: list[float]):
qubits = list(g.nodes())
prepare_state(g, theta)
All(Measure) | qubits
eng.flush()
return ''.join(list(map(lambda x: str(int(x)), qubits)))
def get_expectation(g: Graph):
def execute_circ(params: list[float]):
prepare_state(g, params)
return eng.backend.get_expectation_value(problem_hamiltonian, list(g.nodes()))
return execute_circ
eng = MainEngine()
g = Graph()
nodes = eng.allocate_qureg(4)
edges = [(nodes[i], nodes[(i+1) % 4]) for i in range(4)]
g.add_nodes_from(nodes)
g.add_edges_from(edges)
problem_hamiltonian = reduce(lambda s, curr: s + curr, map(lambda e: QubitOperator(((e[0].id, "Z"), (e[1].id, "Z"))), edges))
expectation = get_expectation(g)
res = minimize(expectation, [1.0, 1.0, 1.0, 1.0], method='COBYLA')
count = Counter([sample_circuit(g, res.x) for _ in range(512)])
print(count["1010"])
print(count["0101"])