QAOA Example
This examples runs a simple Max-Cut algorithm.
Example
using Qaintessent
using Qaintellect
using LinearAlgebra
using Flux
using IterTools: ncycle
# visualization
using Plots
using LaTeXStrings
# number of vertices
n = 5
# graph edges corresponding to the above graph
edges = [(0, 1), (1, 2), (1, 3), (2, 4), (3, 4)];
# generates QAOA layers
function qaoa_layers(p::Int, n::Int, edges::Vector{Tuple{Int,Int}})
cgs = CircuitGate[]
for _ in 1:p
# C operator
for e in edges
# circuit gate uses 1-based indexing
push!(cgs, circuit_gate(e[1] + 1, e[2] + 1, EntanglementZZGate(0.01*randn())))
end
# B operator
for j in 1:n
push!(cgs, circuit_gate(j, RxGate(0.01*randn())))
end
end
return cgs
end
# create measurement operator representing C
Cmatrix = zeros(2^n, 2^n)
for edge in edges
k1 = circuit_gate(edge[1] + 1, ZGate())
k2 = circuit_gate(edge[2] + 1, ZGate())
global Cmatrix += 0.5*(I - sparse_matrix([k1, k2], n))
end
Cop = MeasurementOperator(Cmatrix, Tuple(1:n));
# example
circ = Circuit{n}(qaoa_layers(2, n, edges), [Cop])
# gather parameters from circuit
paras = Flux.params(circ)
# there is not actually any input data for training
data = ncycle([()], 500)
# define optimizer
opt = Descent(0.5)
# create equal superposition state
s_uni = fill(1/√(2^n) + 0.0im, 2^n);
# define evaluation function
evalcb() = @show(apply(circ, s_uni))
# perform minimization with the negated target function to achieve maximization
Flux.train!(() -> -apply(circ, s_uni)[1], paras, data, opt, cb=Flux.throttle(evalcb, 0.5));
# corresponding optimized quantum wavefunction
ψ1 = apply(circ.moments, s_uni)
tags = [join(reverse(digits(i, pad=n, base=2))) for i in 0:2^n-1];
bar(tags, abs2.(ψ1), xticks=:all, xrotation=45, ylabel=L"|\psi|^2", legend=false);