Skip to content

Results are limited to the current section: Application solving tools

Product news

Solving a QUBO problem flexibly

We'll start with the classical approach, since the quantum one has some specificities. Rather than going through Solver, we call the solving algorithm directly — here, tabu search — on a batch of starting bitstrings. See the documentation for other classical solvers.

from __future__ import annotations
from qubosolver import (
Instance,
analysis,
bitstrings,
matrix,
solving,
torch_rng,
)
Q = matrix.tensor(
[
[-0.2, 0.0, 1.0],
[0.0, 0.0, 1.5],
[1.0, 1.5, 0.0],
]
)
instance = Instance(Q)
# Run tabu search in parallel from 5 starting bitstrings
starts = bitstrings.rand(5, instance.size, rng=torch_rng(15))
solution = solving.tabu_search.solve(instance, starts=starts, time_limit=10.0)
print(analysis.to_dataframe([solution]))
import qoolqit
from qubosolver import (
Instance,
LocalEmulator,
Solution,
analysis,
drive_shaping,
embedding,
matrix,
solving,
)
Q = matrix.tensor(
[
[-0.2, 0.0, 1.0],
[0.0, 0.0, 1.5],
[1.0, 1.5, 0.0],
]
)
instance = Instance(Q)
device = qoolqit.AnalogDevice()
backend = LocalEmulator()
register = embedding.blade.embed_for_device(instance, device)
drive = drive_shaping.proportional_diagonal.build_drive(instance, register, device=device)
program = solving.analog_quantum_sampling.compile(register, drive, device)
job = backend.run(program)
solution = Solution.from_results(job.results(), instance)
print(analysis.to_dataframe([solution]))
import qoolqit
from pasqal_cloud import PasqalCloudConnection
from qoolqit.execution import QPU
from qubosolver import (
Instance,
RemoteEmulator,
Solution,
analysis,
drive_shaping,
embedding,
matrix,
solving,
)
# Replace with your username, project id and password on the Pasqal Cloud.
USERNAME = "#TO_PROVIDE"
PROJECT_ID = "#TO_PROVIDE"
PASSWORD = None
Q = matrix.tensor(
[
[-0.2, 0.0, 1.0],
[0.0, 0.0, 1.5],
[1.0, 1.5, 0.0],
]
)
instance = Instance(Q)
if PASSWORD is not None:
# Setup connection
connection = PasqalCloudConnection(
username=USERNAME,
password=PASSWORD,
project_id=PROJECT_ID,
)
else:
# Use a mock local connection for tutorial
from qubosolver.utils._local_connection import LocalConnection
connection = LocalConnection()
emulate = True
if emulate:
device = qoolqit.AnalogDevice()
backend = RemoteEmulator(connection=connection)
else:
print(f"Available devices: {connection.fetch_available_devices()}")
device = qoolqit.Device.from_connection(connection, "FRESNEL_CAN1")
backend = QPU(connection=connection, num_shots=1000)
register = embedding.blade.embed_for_device(instance, device)
drive = drive_shaping.proportional_diagonal.build_drive(instance, register, device=device)
program = solving.analog_quantum_sampling.compile(register, drive, device)
job = backend.run(program)
solution = Solution.from_results(job.results(), instance)
print(analysis.to_dataframe([solution]))

Remote runs, whether on a QPU or a remote emulator, are submitted asynchronously: backend.run(program) returns as soon as the job is queued, without waiting for results. This lets you save the job's identifiers and the instance, disconnect, and retrieve the results later — from the same session or a different one — rather than blocking until the run completes.

import json
import pathlib
from qoolqit.execution.job import JobStatus, get_batch_id, retrieve_remote_job
metadata = {
"job_id": job.job_id(),
"batch_id": get_batch_id(job),
}
output_directory = pathlib.Path.cwd() / "tmp" / "qubosolver-in-full"
output_directory.mkdir(parents=True, exist_ok=True)
metadata_file = output_directory / "metadata.json"
data_file = output_directory / "data.bin"
with metadata_file.open("w") as f:
json.dump(metadata, f)
with data_file.open("wb") as f:
instance.save(f)
with metadata_file.open("r") as f:
metadata = json.load(f)
with data_file.open("rb") as f:
reloaded_instance = Instance.load(f)
reloaded_job = retrieve_remote_job(connection, metadata["job_id"], batch_id=metadata["batch_id"])
status = reloaded_job.get_status()
print(f"Job status: {status}")
if status == JobStatus.DONE:
solution = Solution.from_results(reloaded_job.results(), reloaded_instance)
print(analysis.to_dataframe([solution]))