Aqarios Constrained Quantum Optimizer API reference
Qiskit Functions — pre-built tools created by partner organizations — abstract away parts of the software development workflow to simplify and accelerate utility-scale algorithm discovery and application development. Click to view the guide for this Qiskit Function.
Aqarios Constrained Quantum Optimizer guide
The Aqarios Constrained Quantum Optimizer solves constrained binary optimization problems on IBM Quantum® hardware. It accepts problems in LP, MPS, or Luna Model format and internally handles all reformulation, circuit synthesis, transpilation, and iterative warm-starting by using fixed-angle QAOA with XY-mixers.
The function is loaded and invoked as follows:
optimizer = catalog.load("aqarios/constrained-quantum-optimizer")
job = optimizer.run(problem=lp_str, backend_name="ibm_phoenix")
result = job.result()The Aqarios Constrained Quantum Optimizer is available only to IBM Quantum® Premium Plan, Flex Plan, and On-Prem Plan users. It is in preview release status and subject to change.
Inputs
See the following list for all input parameters this API accepts. Required parameters must be provided on every call; all others are optional.
problem
Type: str
The serialized optimization problem to solve. Three formats are supported:
- LP (
*.lp): Standard LP file format exported as a string, for example via DOcplex'sexport_as_lp_string() - MPS (
*.mps): Standard MPS file format exported as a string, for example via DOcplex'sexport_as_mps_string() - Luna Model: Base64-encoded serialization of an Aqarios Luna Model object, obtained via
model.encode_b64()
The model must represent a binary optimization problem, either as a maximization or minimization. Constraints can be inequalities or equalities over binary variables. Integer variables are only supported when clear upper and lower bounds are specified. Continuous (real-valued) variables are not supported, and a model that contains them fails with error code 4710. The objective and constraints can be higher order and do not need to be linear only.
- Required: Yes
- Example LP:
\Problem name: MIS
Minimize
obj: ...
Subject To
c1: ...
...
Binaries
x_0 x_1
End
backend_name
Type: str or None
Valeur par défaut: None
The name of the IBM Quantum backend to run on (for example "ibm_phoenix"). When set to None, the function automatically selects the least-busy available device.
- Required: No
- Example:
"ibm_phoenix"
options
Type: dict or None
Valeur par défaut: None
Algorithm configuration options controlling the behavior of the iterative warm-starting QAOA. Options are specified as a dictionary. See the options list below for all available keys and their default values.
- Required: No
- Example:
{"reps": 2, "num_parallel": 10, "postprocessing_level": 1}
Options list
reps
Type: int
Valeur par défaut: 1
Number of QAOA layer repetitions (circuit depth parameter ). Higher values increase solution quality at the cost of deeper circuits and longer execution time, which can inflict more noise.
- Choices: Integer in range
[1, 10]
num_parallel
Type: int
Valeur par défaut: 5
Number of independent warm-start chains run in parallel. Increasing this value improves the probability of finding high-quality solutions but raises the total shot budget consumed.
- Choices: Integer in range
[1, 100]
shots
Type: int
Valeur par défaut: 500
Number of measurement shots per iteration per chain.
- Choices: Integer in range
[1, 10000]
total_shots
Type: int
Valeur par défaut: 5000
Total shot budget across all iterations for a single warm-start chain. The iteration loop terminates for a chain once this budget is exhausted.
- Choices: Integer in range
[1, 1000000]
epsilon
Type: float
Valeur par défaut: 0.1
Regularization parameter for the warm-start probabilities. Prevents the probability distribution from collapsing to a deterministic state, preserving exploration across iterations.
- Choices: Float in range
(0.01, 1)
beta
Type: float
Valeur par défaut: 10
Inverse temperature for the Boltzmann weighting used to derive new warm-start states from measurement samples. Higher values concentrate probability mass on lower-energy samples.
- Choices: Float satisfying
beta > 0
approximation_degree
Type: float
Valeur par défaut: 1.0
Controls the approximation level applied to the cost function and during transpilation. Lower values reduce circuit depth by introducing approximations, which can affect solution quality.
- Choices: Float in range
[0.0, 1.0]
postprocessing_level
Type: int
Valeur par défaut: 3
Strength of the classical postprocessing applied after each sampling step to improve solution quality. Higher levels apply more aggressive local search at the cost of additional classical compute time.
- Choices: Integer in range
[0, 3]0: Disable postprocessing.1: Single-pass local search. Try to flip every bit once in random order and keep flips that reduce energy.2: Three-pass local search. Apply level1three times with different random orders.3: Greedy local search. Repeatedly apply the bit-flip that reduces energy the most until no further improvement is possible.
penalty_override
Type: float or None
Valeur par défaut: None
Manually overrides the penalty value used when converting constraints into penalty terms added to the objective. By default, the penalty is derived automatically from the problem structure. Use this option only if the automatic value produces infeasible results.
- Choices: Float satisfying
penalty_override > 0, orNoneto use the automatic value
use_session
Type: bool
Valeur par défaut: False
Whether to use IBM Quantum Compute Service session mode for job execution. Enabling sessions reduces circuit execution overhead by keeping a dedicated connection to the QPU open across iterations, which can lower overall wall-clock time.
- Choices:
True/False
seed_transpiler
Type: int or None
Valeur par défaut: None
Seed passed to the transpiler that maps the circuit onto the selected backend. Set a fixed value to make circuit synthesis and routing reproducible across runs. When set to None, the transpiler seeds itself non-deterministically, so repeated runs of the same problem can yield different circuit layouts.
- Choices: Any integer, or
Nonefor a non-deterministic seed
job_tags
Type: list[str]
Valeur par défaut: []
Extra tags attached to every Quantum Compute job that the function submits to the QPU. The function always tags its jobs with "aqarios/constrained-quantum-optimizer", the function job ID, and the problem name; the entries given here are appended to that list. Use this to group or filter the underlying primitive jobs in your workload list.
- Choices: List of strings
- Example:
["my-experiment", "mis-benchmark"]
Outputs
The output of this API is a dictionary returned by job.result(), containing the best solutions found and associated metadata.
Type: dict[str, Any]
Result dictionary with solution assignments, objective value, feasibility status, and runtime metadata.
Example:
{
'solutions': [{'x_1': 0, 'x_2': 1, 'x_3': 0, 'x_4': 1, 'x_5': 1}],
'solution_bitstrings': ['01011'],
'raw_energy': -6.0,
'objective_value': -6.0,
'feasible': True,
'metadata': {
'resource_usage': {
'RUNNING: MAPPING': {'CPU': 5.405},
'RUNNING: OPTIMIZING_FOR_HARDWARE': {'CPU': 9.902},
'RUNNING: WAITING_FOR_QPU': {'CPU': 25.456},
'RUNNING: EXECUTING_QPU': {'QPU': 25.202},
'RUNNING: POST_PROCESSING': {'CPU': 6.481}
},
'circuit_metrics': {
'before_transpilation': {
'num_qubits': 6,
'gate_count': 42,
'depth': 15,
'two_qubit_gate_count': 12,
'two_qubit_gate_depth': 7,
'operations': {'rz': 12, 'p': 8, 'ry': 7, 'rzz': 4, 'cx': 3,
'xx_plus_yy': 3, 'global_phase': 2, 'cry': 2, 'x': 1}
},
'after_transpilation': {
'num_qubits': 6,
'gate_count': 254,
'depth': 100,
'two_qubit_gate_count': 48,
'two_qubit_gate_depth': 33,
'operations': {'rz': 78, 'sx': 122, 'cz': 48, 'measure': 6, 'x': 0}
}
},
'solver_info': {
'variable_mapping': {'x_1': 0, 'x_2': 1, 'x_3': 2, 'x_4': 3, 'x_5': 4}
}
}
}Output structure
solutions
Type: list[dict[str, int]]
A list of the best solutions found. Each entry is a dictionary mapping variable names (for example, "x_0") to their binary assignments (0 or 1). The list contains more than one entry only when multiple degenerate optima have been identified.
- Example:
[{"x_0": 1, "x_1": 0, "x_2": 1}]
solution_bitstrings
Type: list[str]
The same solutions as in solutions, encoded as bitstrings. Entry of this list corresponds to entry of solutions. Use metadata.solver_info.variable_mapping to look up which character position of a bitstring holds which variable: the value of variable v is bitstring[variable_mapping[v]].
- Example:
["101"]
objective_value
Type: float
The objective value of the best solution found, expressed in terms of the original problem. For maximization problems this value is larger for better solutions; for minimization problems it is smaller.
- Example:
42.0
raw_energy
Type: float
The raw QAOA energy of the best solution, always expressed as a minimization value. This includes any penalty terms added during problem reformulation and is useful for diagnosing constraint violations.
- Example:
-38.5
feasible
Type: bool
Whether the returned solutions satisfy all constraints of the original input model. A result can be infeasible if the penalty values are insufficient to enforce all constraints on the hardware.
- Example:
True
metadata
resource_usage
Type: dict
Quantum and classical resource consumption broken down by phase of the algorithm (mapping, hardware optimization, QPU execution, post-processing).
- Example:
{'RUNNING: MAPPING': {'CPU': 4.57},
'RUNNING: OPTIMIZING_FOR_HARDWARE': {'CPU': 0.177},
'RUNNING: WAITING_FOR_QPU': {'CPU': 9.238},
'RUNNING: EXECUTING_QPU': {'QPU': 30},
'RUNNING: POST_PROCESSING': {'CPU': 0.093}}circuit_metrics
Type: dict or None
Gate counts and circuit depths of the QAOA circuit, reported both as synthesized and as executed on the device. The value is None when the problem was solved during preprocessing and no circuit was run (error code 4712).
before_transpilation
Type: dict
Metrics of the abstract QAOA circuit as synthesized from the problem, before it is mapped to the backend.
after_transpilation
Type: dict
Metrics of the circuits actually submitted to the device. Averaged over all circuits executed during the optimization and rounded to the next integer.
Both entries hold the same fields: num_qubits (number of qubits in the circuit), gate_count (total number of operations), depth (circuit depth), two_qubit_gate_count (number of two-qubit gates), two_qubit_gate_depth (depth counting only two-qubit gates), and operations (gate name mapped to its number of occurrences).
solver_info
Type: dict or None
Additional information about how the solver represented the problem.
variable_mapping
Type: dict[str, int]
Maps each variable name to its character position in the entries of solution_bitstrings.
- Example:
{"x_0": 0, "x_1": 1, "x_2": 2}
Error handling
Code | Description |
|---|---|
4710 | The input model is not supported. The model contains continuous (real-valued) variables, which the function cannot solve, or integer variables without explicit bounds. |
4711 | The input string cannot be parsed into a model. Verify that problem is a valid LP, MPS, or Luna Model string. |
4712 | The model was solved to optimality during preprocessing and no quantum computation was performed. The result is still returned, with metadata.circuit_metrics set to None. |
4719 | Unexpected internal function error. Contact [email protected] with your job ID. |
- Unsupported variable types: The function solves discrete problems only. Continuous (real-valued) variables are not supported, and integer variables must carry an explicit lower and upper bound. A model that violates this fails with error code
4710. - Invalid problem format: If the
problemstring cannot be parsed as a valid LP, MPS, or Luna Model, the job fails with error code4711. - Option validation errors: Option keys or values outside the documented ranges cause the job to fail immediately with error code
1221.