Přeskočit na hlavní obsah
Tento projekt je v betě. Našel jsi chybu? Otevřít issue na GitHubu. Máš otázku nebo nápad? Zeptej se v Discussions — rádi si poslechneme tvou zpětnou vazbu!
Jaká je kvalita překladu na této stránce?

Constrained Quantum Optimizer – Qiskit Function od společnosti Aqarios

Viz referenční příručka API

poznámka

Qiskit Functions jsou experimentální funkce dostupné pouze uživatelům plánů IBM Quantum® Premium Plan, Flex Plan a On-Prem (přes IBM Quantum Platform API). Nacházejí se ve stavu preview release a mohou se měnit.

Přehled​

S nástrojem Constrained Quantum Optimizer od společnosti Aqarios můžeš řešit omezené úlohy binární optimalizace na kvantovém hardwaru IBM® bez ruční reformulace a mapování obvodů. Stačí zadat úlohu jako LP soubor, MPS soubor nebo Luna Model. Funkce automaticky zajišťuje reformulaci, syntézu obvodu, transpilaci a spuštění na hardwaru. Řešič využívá iterativní teplý start (warm-start) [1] algoritmu FlexQAOA, což je rozšíření algoritmu Quantum Approximate Optimization Algorithm (QAOA) nativně podporující omezení.

Optimalizátor je určen pro binární úlohy s omezeními. Zejména one-hot omezení a set-packing omezení lze nativně vynutit pomocí XY-mixerů. Ostatní typy omezení jsou automaticky přeformulovány jako penalizační členy.

Podporované typy proměnných

Funkce řeší pouze diskrétní problémy. Každá rozhodovací proměnná musí být binární, nebo celočíselná s explicitní dolní a horní mezí, aby ji bylo možné zakódovat do qubitů. Spojité (reálné) proměnné nejsou podporovány: model, který je obsahuje, je zamítnut s chybovým kódem 4710.

Popis​

Vyloučení odpovědnosti

Výkon může záviset jak na konkrétní instanci úlohy, tak na následných zpracovatelských krocích. V některých případech mohou klasické vzorky a kvantově generované vzorky po ekvivalentním post-processingu dosáhnout podobné konečné kvality řešení. Hodnocení by proto mělo zohledňovat celý optimalizační pracovní postup.

Constrained Quantum Optimizer implementuje algoritmus Iterative warm-start XY-mixer QAOA (IWS-QAOA) [1]. Algoritmus spouští na kvantovém hardwaru obvody QAOA s pevnými úhly a aktualizuje počáteční pravděpodobnosti teplého startu každého obvodu pomocí výsledků měření z předchozí iterace. Trénování variačních parametrů není potřeba; místo toho se volí pevná lineární rampová parametrizace.

Použitím XY-mixerů k vynucení one-hot omezení můžeš výrazně zlepšit kvalitu řešení u omezených úloh, protože se prohledávaný prostor prakticky zredukuje na menší proveditelný podprostor — a do optimalizační krajiny se nezavádí žádná další složitost způsobená penalizačními členy.

Pracovní postup​

Pracovní postup funkce je popsán níže:

  1. Předzpracování: Před syntézou obvodu optimalizátor analyzuje strukturu omezení vstupní úlohy:

    • Zpracování grafu: Pokud je to pro danou úlohu relevantní, je analyzována jako graf, kde hrany určují vztah mezi proměnnými. Tato grafová analýza umožňuje dvě vylepšení úlohy při předzpracování. Za prvé, jednotlivá omezení lze sloučit do jednoho velkého omezení pomocí slučování klik (clique merging), takže jsou reprezentována jediným XY-mixerem. Za druhé, proměnné s pouze jedním sousedem lze deterministicky fixovat, čímž se zmenší velikost a složitost úlohy.

    • Řešení omezení: Předzpracovatel zpracovává každé omezení zvlášť: Pokud je omezení typu one-hot, lze je vynutit pomocí XY-mixerů. Pokud jde o set-packing omezení, nejprve se převede na one-hot omezení. Omezení typu rovnost se řeší pomocí kvadratických penalizací a omezení typu nerovnost pomocí nevyvážené penalizace.

    • Odvození penalizace: Omezení, která nelze vyjádřit jako one-hot omezení typu rovnost, jsou převedena na penalizační členy. Optimalizátor automaticky odvozuje sílu penalizace ze struktury úlohy.

  2. Iterativní warm-start (teplý start): Optimalizátor spouští více paralelních warm-start řetězců. Každý řetězec udržuje rozdělení pravděpodobnosti nad přiřazeními proměnných, které se používá jako počáteční pravděpodobnost obvodu QAOA (warm-start stav). V každé iteraci řetězec vzorkuje z kvantového obvodu, aplikuje klasické zpracování a aktualizuje své rozdělení na základě výskytu vzorků. Napříč iteracemi se tím vyhledávání soustředí na kvalitní řešení bez variační optimalizační smyčky.

Počet řetězců (num_parallel), celkový rozpočet shotů na řetězec (total_shots) a počet opakování QAOA (reps) jsou hlavní parametry pro vyvážení kvality řešení oproti době běhu.

Workflow diagram of the Constrained Quantum Optimizer

Benchmarky​

Následující benchmarky ukazují, že Qiskit Function Constrained Quantum Optimizer dokáže najít kvalitní, proveditelná řešení omezených optimalizačních úloh s výrazně více než 100 binárními proměnnými. Přesnost je poměr nalezené hodnoty účelové funkce ke známému optimu. Doba běhu je reálný čas od zavolání funkce po doručení výsledku. Využití QPU je zúčtovatelný čas výpočtu Quantum Compute.

Zkoumány byly dvě úlohy: úloha Maximum Independent Set (MIS) a Max-kk-Cut, což je rozšíření známé úlohy MaxCut na více než dvě kategorie. Max-kk-Cut je zároveň optimalizačním ekvivalentem rozhodovacího problému barvení grafu (pokud jsou přeříznuty všechny hrany, je graf kk-obarvitelný).

ÚlohaProměnnéOmezeníQubityPřesnostProveditelnostCelková doba běhu (s)Využití QPU (s)Celkem shotů
MIS es60fst02186280124100.0%True940.2147.025.0k
MIS sloane_2dc_128128517374100.0%True347.6106.012.5k
Max-3-Cut Karate Club99339998.7%True279.5166.025.0k
Max-4-Cut Karate Club13233132100.0%True258.3200.025.0k

Poznámky k benchmarkům​

  • Výše uvedené výsledky byly získány na procesoru ibm_marrakesh Heron r2 s výchozími možnostmi a zapnutou volbou use_session. Pro instanci sloane_2dc_128 bylo použito total_shots=12500.

  • Snížený počet qubitů u instancí MIS (74 a 124 oproti 128 a 186 proměnným) odráží fixaci proměnných při předzpracování.

  • Instance úlohy MIS jsou převzaty z Quantum Optimization Benchmarking Library. - Instancí pro úlohu Max-kk-Cut je graf Zachary Karate Club, který má chromatické číslo 5.

Začínáme​

Tato příručka ukazuje základní použití nástroje Constrained Quantum Optimizer tím, že popisuje, jak funkci načíst a spustit jednoduché úlohy. Podrobnější tutoriál najdeš v Find the Maximum Independent Set with the Aqarios Constrained Quantum Optimizer.

Autentizuj se pomocí svého API klíče IBM Quantum a CRN instance, poté načti funkci z katalogu.

poznámka

Následující kód předpokládá, že máš uložené přihlašovací údaje. Pro jejich nastavení postupuj podle pokynů v Save your IBM Cloud account credentials.

# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util

_needed = {"luna_model": "luna-model", "networkx": "networkx", "qiskit_addon_opt_mapper": "qiskit-addon-opt-mapper", "qiskit_ibm_catalog": "qiskit-ibm-catalog"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
from qiskit_ibm_catalog import QiskitFunctionsCatalog

catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")

# Verify that you have access to the function
catalog.list()
[QiskitFunction(aqarios/constrained-quantum-optimizer)]
# Load the function
optimizer = catalog.load("aqarios/constrained-quantum-optimizer")
# Check the list of backends you have access to
catalog.backends()
[<IBMBackend('ibm_pittsburgh')>,
<IBMBackend('ibm_boston')>,
<IBMBackend('ibm_phoenix')>,
<IBMBackend('ibm_fez')>,
<IBMBackend('ibm_miami')>,
<IBMBackend('ibm_marrakesh')>,
<IBMBackend('ibm_kingston')>]
# Select the backend you want to use
backend = catalog.backend("ibm_phoenix")

Příklad 1: Jednoduchá omezená úloha​

První příklad ukazuje, jak použít funkci se soubory LP, běžným formátem pro zápis optimalizačních úloh používaným v operačním výzkumu. Zformuluješ následující libovolnou optimalizační úlohu s pěti binárními proměnnými xi∈{0,1}x_i \in \{0,1\} podléhajícími dvěma omezením:

min⁡x1x2+2x2x3−x3x4−2x4x5−2x1x3−4x2x5s.t.x1+x2+x3≤1x3−x4+x5=0 \min x_1 x_2 + 2 x_2 x_3 - x_3 x_4 - 2 x_4 x_5 - 2 x_1 x_3 - 4 x_2 x_5 \\ \text{s.t.}\quad x_1 + x_2 + x_3 \leq 1 \\ \quad x_3 - x_4 + x_5 = 0

1. Zformuluj úlohu​

Matematický výraz zapiš přímo v následujícím formátu LP řetězce:

lp_str = """\\Problem name: Example
Minimize
obj: [ 2 x_1 x_2 + 4 x_2 x_3 - 2 x_3 x_4 - 4 x_4 x_5 - 4 x_1 x_3 - 8 x_2 x_5 ] / 2
Subject To
c1: x_1 + x_2 + x_3 <= 1
c2: x_3 - x_4 + x_5 = 0
Binaries
x_1 x_2 x_3 x_4 x_5
End
"""

Všimni si, že [ ... ] / 2 je povinný zápis pro kvadratické účelové funkce podle standardu LP.

2. Spusť optimalizátor​

Vyřeš úlohu pomocí optimalizátoru.

# Set up low-resource options for the simple problem
options = {"total_shots": 2000, "num_parallel": 5, "use_session": True}

# Dispatch the job
job_1 = optimizer.run(
problem=lp_str, backend_name=backend.name, options=options
)

print(f"Job ID: {job_1.job_id}")
Job ID: 2e06a3a8-7c29-4c76-94d7-194293363f4a
# Monitor the job status
job_1.status()
'RUNNING: WAITING_FOR_QPU'

3. Získej výsledek​

Výsledek obsahuje řešení, které přiřazuje názvům proměnných jejich hodnoty.

result = job_1.result()

result
{'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': {'CPU': 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}}}}

Pole solutions ve vráceném slovníku obsahuje všechna nalezená degenerovaná nejlepší řešení jako slovníky, které mapují název každé proměnné na její přiřazení. Stejná řešení jsou vrácena také jako bitové řetězce v solution_bitstrings; metadata.solver_info.variable_mapping ti říká, která pozice znaku v bitovém řetězci patří které proměnné. Kromě dat řešení jsou poskytovány také objective_value, příznak feasible a další metadata.

Příklad 2: Maximum Independent Set​

Úloha Maximum Independent Set (MIS) hledá největší podmnožinu vrcholů grafu takovou, že žádné dva vrcholy v této podmnožině nesdílejí hranu. Tento příklad řeší MIS na pravidelném grafu o 12 uzlech. Více informací o úloze a rozsáhlejší příklad najdeš v tutoriálu.

Úloha je sestavena pomocí qiskit-addon-opt-mapper. V případě potřeby nainstaluj požadované balíčky:

# %pip install networkx qiskit-addon-opt-mapper

Krok 1: Definuj úlohu​

Vytvoř náhodný 3-regulární graf a vytvoř z něj optimalizační úlohu MIS. Každý uzel grafu se stane binární proměnnou a každá hrana zavádí omezení zajišťující, že bude vybrán nejvýše jeden z jejích koncových bodů.

import networkx as nx
from qiskit_addon_opt_mapper.applications import IndependentSet
from qiskit_addon_opt_mapper.translators import to_docplex_mp

# 12-node random 3-regular graph
G = nx.random_regular_graph(3, 12, seed=7)

# Build MIS problem and export as LP string
mis = IndependentSet(G)
mis_problem = mis.to_optimization_problem()
lp_str = to_docplex_mp(mis_problem).export_as_lp_string()

print(lp_str)
\ This file has been generated by DOcplex
\ ENCODING=ISO-8859-1
\Problem name: Independent set

Maximize
obj: x_0 + x_1 + x_2 + x_3 + x_4 + x_5 + x_6 + x_7 + x_8 + x_9 + x_10 + x_11
Subject To
c0: x_0 + x_4 <= 1
c1: x_0 + x_9 <= 1
c2: x_0 + x_8 <= 1
c3: x_1 + x_2 <= 1
c4: x_1 + x_7 <= 1
c5: x_1 + x_3 <= 1
c6: x_2 + x_4 <= 1
c7: x_2 + x_11 <= 1
c8: x_3 + x_10 <= 1
c9: x_3 + x_11 <= 1
c10: x_4 + x_5 <= 1
c11: x_5 + x_10 <= 1
c12: x_5 + x_6 <= 1
c13: x_6 + x_8 <= 1
c14: x_6 + x_7 <= 1
c15: x_7 + x_9 <= 1
c16: x_8 + x_11 <= 1
c17: x_9 + x_10 <= 1

Bounds
0 <= x_0 <= 1
0 <= x_1 <= 1
0 <= x_2 <= 1
0 <= x_3 <= 1
0 <= x_4 <= 1
0 <= x_5 <= 1
0 <= x_6 <= 1
0 <= x_7 <= 1
0 <= x_8 <= 1
0 <= x_9 <= 1
0 <= x_10 <= 1
0 <= x_11 <= 1

Binaries
x_0 x_1 x_2 x_3 x_4 x_5 x_6 x_7 x_8 x_9 x_10 x_11
End

Krok 2: Spusť optimalizátor​

Vyřeš úlohu pomocí optimalizátoru.

options = {"total_shots": 2000, "use_session": True}

# Dispatch the job
job_2 = optimizer.run(
problem=lp_str, backend_name=backend.name, options=options
)

print(f"Job ID: {job_2.job_id}")
Job ID: f041431c-b42e-4627-afe5-522fea61faf6
# Monitor the job status
job_2.status()
'QUEUED'

Krok 3: Získej a interpretuj výsledky​

Nakonec získáš řešení a ověříš jeho správnost.

result = job_2.result()

print(f"Feasible: {result['feasible']}")
print(f"Independent set size: {int(result['objective_value'])}")

# Extract the selected nodes
solution = result["solutions"][0]
independent_set = [
int(k.split("_")[1]) for k, v in solution.items() if v == 1
]
print(f"Selected nodes: {sorted(independent_set)}")

# Verify no two selected nodes share an edge
conflicts = [
(u, v)
for u, v in G.edges()
if u in independent_set and v in independent_set
]
print(f"Edge conflicts: {conflicts}")
Feasible: True
Independent set size: 5
Selected nodes: [1, 4, 6, 9, 11]
Edge conflicts: []

Příklad 3: Barvení grafu 3 barvami (Max-3-Cut)​

Úloha Max-kk-Cut rozděluje vrcholy grafu do kk skupin tak, aby se maximalizoval počet hran, jejichž koncové body patří do různých skupin. Pro k=3k = 3 je to ekvivalentní hledání obarvení třemi barvami, které maximalizuje počet hran mezi různými barvami.

Formálně přiřaď každý uzel i∈Vi \in V do jedné z kk skupin pomocí binárních proměnných xi,cx_{i,c} pro barvu c∈{1,…,k}c \in \{1, \ldots, k\}. One-hot omezení ∑cxi,c=1\sum_c x_{i,c} = 1 pro každý uzel vynucuje jednoznačné přiřazení. Účelová funkce maximalizuje hrany mezi skupinami:

min⁡∑(u,v)∈E∑cxu,c xv,cs.t.∑cxi,c=1∀i∈V\min \sum_{(u,v) \in E} \sum_c x_{u,c} \, x_{v,c}\\ \text{s.t.} \sum_{c} x_{i,c} = 1 \quad \forall i \in V

One-hot omezení jsou ideální pro XY-mixery, které optimalizátor zpracovává nativně.

Tento příklad používá graf Zachary Karate Club (34 uzlů, 78 hran) a sestavuje model pomocí Luna Model. V případě potřeby nainstaluj požadované balíčky:

# %pip install networkx matplotlib luna-model

Krok 1: Definuj úlohu​

Nejprve vygeneruj binární proměnné pomocí balíčku luna-model. Poté definuj účelovou funkci a přidej do modelu omezení.

import networkx as nx
from luna_model import Model, quicksum

k = 3
G = nx.karate_club_graph()

# Instantiate the Model object
model = Model(name="Max-3-Cut")

# Add binary variables
x = model.add_variables("x", shape=(G.number_of_nodes(), k))

# Add the objective by using the numpy dot abstraction
model.objective = quicksum(x[i].dot(x[j]) for i, j in G.edges)

# Bulk-add the one-hot constraints
model.add_constraints(x.sum(axis=1) == 1)

# Encode the model to send via API
model_enc = model.encode_b64()

Krok 2: Spusť optimalizátor​

Vyřeš úlohu pomocí optimalizátoru.

options = {"use_session": True}

# Dispatch the job
job_3 = optimizer.run(
problem=model_enc, backend_name=backend.name, options=options
)

print(f"Job ID: {job_3.job_id}")
Job ID: df911d83-9df7-44a1-bfad-5d66e08676c3
# Monitor the job status
job_3.status()
'RUNNING: WAITING_FOR_QPU'

Krok 3: Získej a vizualizuj výsledky​

Získej a vizualizuj výsledky.

result = job_3.result()
solution = result["solutions"][0]

# Map each node to its assigned color group
node_group = {}
for i in G.nodes:
for c in range(k):
if solution[f"x{i},{c}"] == 1:
node_group[i] = c

print(f"Feasible: {result['feasible']}")
print(f"Violations: {int(result['objective_value'])}")

# Visualize the partition
colors = ["tab:blue", "tab:orange", "tab:green"]
node_colors = [colors[node_group[i]] for i in G.nodes()]
nx.draw(G, nx.kamada_kawai_layout(G), node_color=node_colors, node_size=200)
Feasible: True
Violations: 4

Output of the previous code cell

Seznam změn​

[0.4.0] - 2026-09-22​

Nekompatibilní změny

  • Vstupní parametr model byl přejmenován na problem.
  • Výstupní pole obj_value bylo přejmenováno na objective_value.
  • Volba postprocessing byla nahrazena volbou postprocessing_level, která místo řetězce přijímá celé číslo v rozsahu [0, 3]. Předchozí hodnoty se mapují takto: "off" -> 0, "weak" -> 1, "medium" -> 2 a "strong" -> 3; výchozí hodnota zůstává 3.
  • Struktura metadata.circuit_metrics byla změněna. Nyní uvádí num_qubits, gate_count, depth, two_qubit_gate_count, two_qubit_gate_depth a operations odděleně pro before_transpilation a after_transpilation, místo jednoho plochého slovníku průměrných počtů hradel. Pole má hodnotu None, pokud byl problém vyřešen během předzpracování a žádný obvod nebyl spuštěn (chybový kód 4712).

Novinky

  • Přidána volba seed_transpiler, která zajišťuje reprodukovatelnou syntézu a směrování obvodů napříč běhy.
  • Přidána volba job_tags, která umožňuje připojit vlastní značky ke každé úloze Qiskit Runtime, kterou funkce odešle.
  • Přidáno výstupní pole solution_bitstrings, které vrací stejná řešení jako solutions ve formě bitových řetězců.
  • Přidáno metadata.solver_info.variable_mapping, které mapuje název každé proměnné na její pozici znaku v položkách solution_bitstrings.

Dokumentace

  • Zdokumentováno, že spojité (reálné) proměnné nejsou podporovány a že celočíselné proměnné vyžadují explicitní meze. Takové modely selžou s chybovým kódem 4710.

Získej podporu​

S dotazy nebo problémy kontaktuj support@aqarios.com a uveď ID svého jobu.

Další kroky​

Doporučení

Reference​

  1. Bucher et al. (2026), Constrained Quantum Optimization via Iterative Warm-Start XY-Mixers 10.1088/1367-2630/ae8ea2