Skip to content

QAGA

The QAGA+ algorithm uses the paradigm of Genetic Algorithms: We keep track of a population of possible solutions to an optimization/decision problem in the QUBO formulation, and iteratively create new solutions from these using mutations and recombinations. A selection ensures we only keep track of the most promising solutions in the population for the next iteration, where these again are used to create new solutions. This process is run until a predefined stopping criterion is reached, which might be a desired solution quality (i.e., an energy level) or a boundary on the time / iterations the algorithm is allowed to run. At the end, the best found solution vector and its corresponding solution value is returned. For QAGA+, Quantum Annealing is used during the mutation phase.

Note

This solver is only available for commercial and academic licenses.


Compatible Backends

The QAGA algorithm supports the following backends:

By default, QAGA uses the DWaveQpu backend.


Initialization

The following section outlines the default configurations of QAGA. 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 import QAGA

algorithm = QAGA(
    backend=None,
    p_size=20,
    p_inc_num=5,
    p_max=160,
    pct_random_states=0.25,
    mut_rate=0.5,
    rec_rate=1,
    rec_method='random_crossover',
    select_method='simple',
    target=None,
    atol=1e-08,
    rtol=1e-05,
    timeout=60.0,
    max_iter=100
)

Parameter Details

For a complete overview of available parameters and their usage, see the QAGA 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[DWaveQpu]

Parameters for the Quantum Assisted Genetic Algorithm (QAGA).

QAGA combines quantum computing with genetic algorithms to enhance the search for optimal solutions. It uses quantum annealing for mutation and recombination operations, potentially allowing the algorithm to escape local optima more effectively than classical genetic algorithms.

The algorithm maintains a population of candidate solutions that evolve through selection, quantum-enhanced recombination, and mutation operations across generations.

Attributes:

Name Type Description
p_size int

Initial population size (number of candidate solutions). Larger populations provide more diversity but require more computation. Default is 20, suitable for small to medium problems.

p_inc_num int

Number of new individuals added to the population after each generation. Controls population growth rate. Default is 5, allowing moderate expansion.

p_max int | None

Maximum population size. Once reached, no more growth occurs. Prevents unbounded population expansion. Default is 160, balancing diversity with computational cost.

pct_random_states float

Percentage of random states added to the population after each iteration. Helps maintain diversity and avoid premature convergence. Default is 0.25 (25%).

mut_rate float

Mutation rate - probability to mutate an individual after each iteration. Higher values favor exploration, lower values favor exploitation. Default is 0.5, balanced between the two. Must be between 0.0 and 1.0.

rec_rate int

Recombination rate - number of mates each individual is recombined with per generation. Higher values increase genetic mixing. Default is 1.

rec_method Literal['cluster_moves', 'one_point_crossover', 'random_crossover']

Method used for recombining individuals: - "cluster_moves": Swaps clusters of related variables between solutions - "one_point_crossover": Splits solutions at a random point and exchanges parts - "random_crossover": Randomly exchanges bits between parents Default is "random_crossover", which provides good exploration.

select_method Literal['simple', 'shared_energy']

Selection strategy for the next generation: - "simple": Pure energy-based selection - "shared_energy": Promotes diversity by penalizing similar solutions Default is "simple", focusing on solution quality.

target float | None

Target energy level to stop the algorithm. If None, runs until other criteria are met. Default is None.

atol float

Absolute tolerance when comparing energies to target. Default is 0.0.

rtol float

Relative tolerance when comparing energies to target. Default is 0.0.

timeout float

Maximum runtime in seconds. Includes preprocessing, network overhead, and quantum processing time. Default is 60.0 seconds.

max_iter Union[int, None]

Maximum number of generations before stopping. None means no limit. Default is 100 generations.

atol class-attribute instance-attribute

atol: float = DEFAULT_ATOL

backend class-attribute instance-attribute

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

max_iter class-attribute instance-attribute

max_iter: int | None = 100

model_config class-attribute instance-attribute

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

mut_rate class-attribute instance-attribute

mut_rate: float = Field(default=0.5, ge=0.0, le=1.0)

p_inc_num class-attribute instance-attribute

p_inc_num: int = 5

p_max class-attribute instance-attribute

p_max: int | None = 160

p_size class-attribute instance-attribute

p_size: int = 20

pct_random_states class-attribute instance-attribute

pct_random_states: float = 0.25

rec_method class-attribute instance-attribute

rec_method: Literal[
    "cluster_moves", "one_point_crossover", "random_crossover"
] = "random_crossover"

rec_rate class-attribute instance-attribute

rec_rate: int = 1

rtol class-attribute instance-attribute

rtol: float = DEFAULT_RTOL

select_method class-attribute instance-attribute

select_method: Literal['simple', 'shared_energy'] = 'simple'

target class-attribute instance-attribute

target: float | None = None

timeout class-attribute instance-attribute

timeout: float = 60.0

get_compatible_backends classmethod

get_compatible_backends() -> tuple[type[DWaveQpu], ...]

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() -> DWaveQpu

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.