Solving the Maximal Independent Set Problem on defective King Graph
Download Script · Download Job
This notebook was executed using the upstream saved emulator and hardware results. No Aquila jobs were submitted during this website build.
Introduction
In this tutorial, we show how to use some of Bloqade’s built-in tools to generate a defects in a graph and then use Bloqade to solve the Maximal Independent Set (MIS) problem on a Unit Disk Graph (UDG), which is easily expressible on Neutral Atom Hardware via the Rydberg blockade mechanism. We will not cover hybrid quantum- classical algorithms in this tutorial, but instead, we will use a simple parameter scan to find the optimal detuning value for an adiabatic ramp. We will cover hybrid quantum-classical algorithms in a future tutorial.
Define the Program.
To define random defects on any Bloqade geometry, simply call the add_defect_density
or add_defect_count methods on the geometry object. The add_defect_density method
takes a float between 0 and 1 and uses that as the probability of a site being a
defect. The add_defect_count method takes the number of defects to add to the
geometry placed in random locations. Both ways take an optional rng argument,
a numpy random number generator. If no rng argument is provided, then the default
numpy random number generator is used. Using the random number generator allows you
to set the seed for reproducibility. After that, defining the pulse sequence is the
same as in the previous tutorials.
import os
import numpy as npimport matplotlib.pyplot as pltfrom bloqade.analog import load, savefrom bloqade.analog.atom_arrangement import Square
if not os.path.isdir("data"): os.mkdir("data")
# setting the seedrng = np.random.default_rng(1234)
durations = [0.3, 1.6, 0.3]
mis_udg_program = ( Square(15, lattice_spacing=5.0) .apply_defect_density(0.3, rng=rng) .rydberg.rabi.amplitude.uniform.piecewise_linear(durations, [0.0, 15.0, 15.0, 0.0]) .detuning.uniform.piecewise_linear( durations, [-30, -30, "final_detuning", "final_detuning"] ))
mis_udg_job = mis_udg_program.batch_assign(final_detuning=np.linspace(0, 80, 41))Run On Hardware
We can’t run on our emulators because the program size is too large. Instead we will run on hardware.
filename = os.path.join(os.path.abspath(""), "data", "MIS-UDG-job.json")
if not os.path.isfile(filename): hw_batch = mis_udg_job.braket.aquila().run_async(shots=100) save(hw_batch, filename)Plot Results
Here, the total number of Rydberg excitations is plotted as a function of the final detuning. The total number of Rydberg excitations is a proxy for the largest independent set size because the number of violations to the Rydberg blockade is and will not scale with the size of the independent set. We start by loading the results
batch = load(filename)# batch.fetch()# save(filename, batch)The report object already has a method to calculate the Rydberg densities. We can use this to calculate the average total Rydberg density for each final detuning. then, we can plot the results.
report = batch.report()
average_rydberg_excitation = report.rydberg_densities(filter_perfect_filling=False).sum( axis=1)final_detunings = report.list_param("final_detuning")
plt.plot(final_detunings, average_rydberg_excitation, color="#6437FF")plt.xlabel("final detuning (rad/µs)")plt.ylabel("total rydberg excitations")plt.show()