Skip to content

FlexQAOA

The FlexQAOA is a variant of QAOA developed by Aqarios, specifically focused on problems coming from the real world. The core issue with plain QAOA is that it requires a Quadratic Unconstrained Binary Optimization (QUBO) input format. However, real-world problems typically contain constraints, that can not be violated for a feasible solution. While constraints can be reformulated into penalty terms to form a QUBO. These penalty terms distort the energy spectrum of the optimization heavily, leading to impaired optimization performance. Additionally, in inequality-constrained cases, slack variables have to be introduced, effectively enlarging the search space.

To alleviate the issues arising with reformulation to QUBO, FlexQAOA integrates common constraints directly into the circuit architecture. Namely, it utilizes XY-mixers for the natural enforcement of one-hot constraints and Indicator Functions (IF) for effective penalization of inequality constraints.

Upon input of a constraint optimization problem, FlexQAOA automatically selects the constraints it can naturally encode and reformulates the remaining constraints using default QUBO methods. The user can freely configure which methods shall be applied in this automatic extraction pipeline.

So far, FlexQAOA only supports an internal simulator for execution. This simulator, however, features advanced techniques, like cost caching, reduction of state vector size and efficient evaluation of indicator functions.

Note

FlexQAOA will be extended in the future to support more types of constraints and different hardware backends. Stay tuned for updates!


Compatible Backends

The FlexQAOA algorithm supports the following backends:

By default, FlexQAOA uses the Aqarios backend.


Initialization

The following section outlines the default configurations of FlexQAOA. You can also specify other compatible backends for the algorithm. When backend=None is specified, the default backend will be initialized automatically. In this case, if the backend requires a token, it will be taken from the environment variables.

Default Configuration
from luna_quantum.solve.parameters.algorithms.base_params import (
    LinearQAOAParams,
    ScipyOptimizerParams
)
from luna_quantum.solve.parameters.algorithms.quantum_gate.flex_qaoa import (
    AdvancedConfig,
    XYMixer,
    FlexQAOA,
    IndicatorFunctionParams,
    OneHotParams,
    PipelineParams,
    QuadraticPenaltyParams
)

algorithm = FlexQAOA(
    backend=None,
    shots=1024,
    reps=1,
    pipeline=PipelineParams(
        indicator_function=IndicatorFunctionParams(
            penalty=None,
            penalty_scaling=2
        ),
        one_hot=OneHotParams(),
        quadratic_penalty=QuadraticPenaltyParams(
            penalty=None
        )
    ),
    optimizer=ScipyOptimizerParams(
        method='cobyla',
        tol=None,
        bounds=None,
        jac=None,
        hess=None,
        maxiter=100,
        options={}
    ),
    qaoa_config=AdvancedConfig(
        mixer=XYMixer(
            types=['even', 'odd', 'last']
        ),
        parallel_indicators=True,
        discard_slack=False,
        infeas_penalty=None
    ),
    initial_params=LinearQAOAParams(
        delta_beta=0.5,
        delta_gamma=0.5
    )
)

Parameter Details

For a complete overview of available parameters and their usage, see the FlexQAOA API Reference.


Usage

from luna_quantum import LunaSolve

LunaSolve.authenticate("<YOUR_LUNA_API_KEY>")

# Define your model and algorithm
model = ...
algorithm = ...

solve_job = algorithm.run(model, name="my-solve-job")

API Reference

Bases: LunaAlgorithm[Aqarios], BaseModel

The FlexQAOA Algorithm for constrained quantum optimization.

The FlexQAOA is an extension to the default QAOA with the capabilities to encode inequality constriants with indicator functions as well as one-hot constraints through XY-mixers. This algorithm will dynamically extract all constraints from the given constraint input optimization model, and construct an accoring QAOA circuit. Currently only simulation of the circuit is supported. But due to the constrained nature, the subspace of the Hilbertspace required for simulation is smaller, depending on the problem instance. This allows for simulation of problems with more qubits than ordinary state vector simulation allows. For now, the simulation size is limited to Hilbertspaces with less <= 2**18 dimensions.

The FlexQAOA allows for a dynamic circuit construction depending on input paramters. Central to this is the pipeline parameter which allows for different configurations.

For instance, if one likes to explore ordinary QUBO simulation with all constraints represented as quadratic penalties, the one_hot and indicator_function options need to be manually disabled

pipeline = {"one_hot": None, "indicator_function": None}

If no indicator function is employed, but the input problem contains inequality constraints, slack variables are added to the optimization problem. FlexQAOA allows for a configuration that discards slack variables as their assignment is not necessarily of interest. This option can be enbled by setting

qaoa_config = {"discard_slack": True}

Following the standard protocol for QAOA, a classical optimizer is required that tunes the variational parameters of the circuit. Besides the classical ScipyOptimizer other optimizers are also featured, allowing for optimizing only a linear schedule, starting with optimizing for a linear schedule followed by individual parameter fine tuning, and interpolating between different QAOA circuit depts.

Attributes:

Name Type Description
shots int

Number of sampled shots.

reps int

Number of QAOA layer repetitions

pipeline PipelineParams | Dict

The pipeline defines the selected features for QAOA circuit generation. By default, all supported features are enabled (one-hot constraints, inequality constraints and quadratic penalties).

optimizer ScipyOptimizerParams | LinearOptimizerParams | CombinedOptimizerParams | InterpolateOptimizerParams | None | Dict

The classical optimizer for parameter tuning. Default: ScipyOptimizer. Setting to None disables the optimization, leading to an evaluation of the initial parameters.

qaoa_config AdvancedConfig | Dict

Additional options for the QAOA circuit and evalutation

initial_params LinearQAOAParams | BasicQAOAParams | RandomQAOAParams | Dict

Custom QAOA variational circuit parameters. By default linear increasing/decreasing parameters for the selected reps are generated.

backend class-attribute instance-attribute

backend: BACKEND_TYPE | None = Field(default=None, exclude=True, repr=False)

initial_params class-attribute instance-attribute

initial_params: LinearQAOAParams | BasicQAOAParams | RandomQAOAParams = Field(
    default_factory=lambda: LinearQAOAParams(delta_beta=0.5, delta_gamma=0.5),
    description="Custom QAOA circuit parameters. By default linear increasing/decreasing parameters for the selected `reps` are generated.",
)

model_config class-attribute instance-attribute

model_config = ConfigDict(
    arbitrary_types_allowed=True, extra="allow", validate_assignment=True
)

optimizer class-attribute instance-attribute

optimizer: (
    ScipyOptimizerParams
    | LinearOptimizerParams
    | CombinedOptimizerParams
    | InterpolateOptimizerParams
    | None
) = Field(
    default_factory=lambda: ScipyOptimizerParams(),
    description="The classical optimizer. Default: ScipyOptimizer",
)

pipeline class-attribute instance-attribute

pipeline: PipelineParams = Field(
    default_factory=lambda: PipelineParams(),
    description="The pipeline defines the selected features for QAOA circuit generation. By default, all supported features are enabled (one-hot constraints, inequality constraints and quadratic penalties).",
)

qaoa_config class-attribute instance-attribute

qaoa_config: AdvancedConfig = Field(
    default_factory=lambda: AdvancedConfig(),
    description="Additional options for the QAOA circuit and evalutation",
)

reps class-attribute instance-attribute

reps: int = Field(
    default=1, ge=1, description="Number of QAOA layer repetitions"
)

shots class-attribute instance-attribute

shots: int = Field(default=1024, ge=1, description='Number of sampled shots.')

get_compatible_backends classmethod

get_compatible_backends() -> tuple[type[Aqarios]]

Check at runtime if the used backend is compatible with the solver.

Returns:

Type Description
tuple[type[IBackend], ...]

True if the backend is compatible with the solver, False otherwise.

get_default_backend classmethod

get_default_backend() -> Aqarios

Return the default backend implementation.

This property must be implemented by subclasses to provide the default backend instance to use when no specific backend is specified.

Returns:

Type Description
IBackend

An instance of a class implementing the IBackend interface that serves as the default backend.

run

run(
    model: Model | str,
    name: str | None = None,
    backend: BACKEND_TYPE | None = None,
    client: LunaSolve | str | None = None,
    *args: Any,
    **kwargs: Any,
) -> SolveJob

Run the configured solver.

Parameters:

Name Type Description Default
model Model or str

The model to be optimized or solved. It could be an Model instance or a string identifier representing the model id.

required
name str | None

If provided, the name of the job. Defaults to None.

None
backend BACKEND_TYPE | None

Backend to use for the solver. If not provided, the default backend is used.

None
client LunaSolve or str

The client interface used to interact with the backend services. If not provided, a default client will be used.

None
*args Any

Additional arguments that will be passed to the solver or client.

()
**kwargs Any

Additional keyword parameters for configuration or customization.

{}

Returns:

Type Description
SolveJob

The job object containing the information about the solve process.