Optimization Solver: O Funcție Qiskit de Q-CTRL Fire Opal
Funcțiile Qiskit sunt o funcționalitate experimentală disponibilă doar utilizatorilor IBM Quantum® cu abonament Premium Plan, Flex Plan și On-Prem (prin IBM Quantum Platform API) Plan. Acestea se află în stadiu de previzualizare și pot fi modificate.
Prezentare generală
Cu Fire Opal Optimization Solver, poți rezolva probleme de optimizare la scară utilă pe hardware cuantic fără a necesita expertiză în domeniul cuantic. Pur și simplu introduci definiția problemei la nivel înalt, iar Solver-ul se ocupă de restul. Întregul flux de lucru este conștient de zgomot și utilizează Fire Opal's Performance Management în fundal. Solver-ul oferă în mod constant soluții precise pentru probleme dificil de rezolvat clasic, chiar și la scara completă a dispozitivului, pe cele mai mari QPU-uri IBM®.
Solver-ul este flexibil și poate fi utilizat pentru a rezolva probleme de optimizare combinatorie definite ca funcții obiectiv sau grafuri arbitrare. Problemele nu trebuie să fie mapate la topologia dispozitivului. Atât problemele neconstrânse, cât și cele constrânse pot fi rezolvate, cu condiția că restricțiile pot fi formulate ca termeni de penalizare. Exemplele incluse în acest ghid demonstrează cum să rezolvi o problemă de optimizare neconstrânsă și una constrânsă la scară utilă, folosind diferite tipuri de intrări ale Solver-ului. Primul exemplu implică o problemă Max-Cut definită pe un graf 3-regulat cu 156 de noduri, în timp ce al doilea exemplu abordează o problemă de Acoperire Minimă a Vârfurilor cu 50 de noduri, definită printr-o funcție cost.
Pentru a obține acces la Optimization Solver, contactează Q-CTRL.
Descrierea funcției
Solver-ul optimizează și automatizează complet întregul algoritm, de la suprimarea erorilor la nivel hardware până la maparea eficientă a problemei și optimizarea clasică în buclă închisă. În fundal, pipeline-ul Solver-ului reduce erorile la fiecare etapă, permițând performanța îmbunătățită necesară pentru o scalare semnificativă. Fluxul de lucru de bază este inspirat de Quantum Approximate Optimization Algorithm (QAOA), care este un algoritm hibrid cuantic-clasic. Pentru un rezumat detaliat al fluxului complet de lucru al Optimization Solver, consultă manuscrisul publicat.
Pentru a rezolva o problemă generică cu Optimization Solver:
- Definește problema ta ca o funcție obiectiv, un graf sau un lanț de spin
SparsePauliOp. - Conectează-te la funcție prin Catalogul de Funcții Qiskit.
- Rulează problema cu Solver-ul și recuperează rezultatele.
Intrări și ieșiri
Intrări
| Nume | Tip | Descriere | Obligatoriu | Implicit | Exemplu |
|---|---|---|---|---|---|
| problem | str sau SparsePauliOp | Una dintre reprezentările enumerate la „Formate de problemă acceptate" | Da | N/A | Poly(2.0*n[0]*n[1] + 2.0*n[0]*n[2] - 3.13520241298341*n[0] + 2.0*n[1]*n[2] - 3.14469748506794*n[1] - 3.18897660121566*n[2] + 6.0, n[0], n[1], n[2], domain='RR') |
| problem_type | str | Numele clasei de problemă; folosit doar pentru definițiile de problemă pe bază de graf și lanț de spin, limitate la „maxcut" sau „spin_chain"; nu este necesar pentru definițiile de funcție obiectiv arbitrare | Nu | None | "maxcut" |
| backend_name | str | Numele Backend-ului de utilizat | Nu | Backend-ul cel mai puțin ocupat la care instanța ta are acces | "ibm_fez" |
| options | dict | Opțiuni de intrare, inclusiv: (Opțional) session_id: str; comportamentul implicit creează o nouă Session | Nu | None | {"session_id": "cw2q70c79ws0008z6g4g"} |
Formate de problemă acceptate:
- Reprezentarea expresiei polinomiale a unei funcții obiectiv. Ideal creată în Python cu un obiect SymPy Poly existent și formatată într-un șir folosind sympy.srepr.
- Reprezentarea grafului unui tip specific de problemă. Graful trebuie creat folosind biblioteca networkx în Python. Apoi trebuie convertit într-un șir folosind funcția networkx
[nx.readwrite.json_graph.adjacency_data](http://nx.readwrite.json_graph.adjacency_data.). - Reprezentarea lanțului de spin a unei probleme specifice. Lanțul de spin trebuie reprezentat ca obiect
SparsePauliOp; consultă documentația pentru mai multe detalii.
Backend-uri suportate: Rulează următorul cod pentru a vedea lista Backend-urilor care sunt suportate în prezent. Dacă dispozitivul tău nu este listat, contactează Q-CTRL pentru a adăuga suport.
# Added by doQumentation — required packages for this notebook
!pip install -q networkx numpy qiskit-ibm-catalog qiskit-ibm-runtime sympy
from qiskit_ibm_runtime import QiskitRuntimeService
service = QiskitRuntimeService()
service.backends()
[<IBMBackend('ibm_fez')>,
<IBMBackend('ibm_brisbane')>,
<IBMBackend('ibm_pittsburgh')>,
<IBMBackend('ibm_kingston')>,
<IBMBackend('ibm_torino')>,
<IBMBackend('ibm_marrakesh')>]
Opțiuni:
| Nume | Tip | Descriere | Implicit |
|---|---|---|---|
| session_id | str | ID-ul unei Session Qiskit Runtime existente | "cw4r3je6f0t010870y3g" |
| job_tags | list[str] | O listă de etichete de job | [] |
Ieșiri
| Nume | Tip | Descriere | Exemplu |
|---|---|---|---|
| result | dict[str, Any] | Soluția și metadatele enumerate la „Conținutul dicționarului de rezultate" | {'solution_bitstring_cost': 3.0, 'final_bitstring_distribution': {'000001': 100, '000011': 2}, 'iteration_count': 3, 'solution_bitstring': '000001', 'variables_to_bitstring_index_map': {n[1]': 5, 'n[2]': 4, 'n[3]': 3, 'n[4]': 2, 'n[5]': 1}, 'best_parameters': [0.19628831763697097, -1.047052334523102], 'warnings': []} |
Conținutul dicționarului de rezultate:
| Nume | Tip | Descriere |
|---|---|---|
| solution_bitstring_cost | float | Cel mai bun cost minim din toate iterațiile |
| final_bitstring_distribution | CountsDict | Dicționarul de numărări ale șirurilor de biți asociat costului minim |
| solution_bitstring | str | Șirul de biți cu cel mai bun cost din distribuția finală |
| iteration_count | int | Numărul total de iterații QAOA efectuate de Solver |
| variables_to_bitstring_index_map | float | Maparea de la variabile la bitul echivalent din șirul de biți |
| best_parameters | list[float] | Parametrii beta și gamma optimizați din toate iterațiile |
| warnings | list[str] | Avertismentele produse în timpul compilării sau rulării QAOA (implicit None) |
Benchmark-uri
Rezultatele de benchmark publicate arată că Solver-ul rezolvă cu succes probleme cu peste 120 de Qubiți, depășind chiar rezultatele publicate anterior pe dispozitivele de tip quantum annealing și trapped-ion. Următoarele metrici de benchmark oferă o indicație aproximativă a acurateței și scalabilității tipurilor de probleme, bazate pe câteva exemple. Metricile reale pot diferi în funcție de diverse caracteristici ale problemei, cum ar fi numărul de termeni din funcția obiectiv (densitate) și localitatea lor, numărul de variabile și ordinul polinomului.
„Numărul de Qubiți" indicat nu este o limitare strictă, ci reprezintă praguri aproximative unde poți anticipa o acuratețe a soluției extrem de consistentă. Dimensiunile mai mari ale problemelor au fost rezolvate cu succes, iar testarea dincolo de aceste limite este încurajată.
Conectivitatea arbitrară a Qubiților este suportată pentru toate tipurile de probleme.
| Tip de problemă | Număr de Qubiți | Exemplu | Acuratețe | Timp total (s) | Utilizare Runtime (s) | Număr de iterații |
|---|---|---|---|---|---|---|
| Probleme pătratice cu conectivitate redusă | 156 | Max-Cut 3-regulat | 100% | 1764 | 293 | 16 |
| Optimizare binară de ordin superior | 156 | Model Ising spin-glass | 100% | 1461 | 272 | 16 |
| Probleme pătratice cu conectivitate densă | 50 | Max-Cut complet conectat | 100% | 1758 | 268 | 12 |
| Problemă constrânsă cu termeni de penalizare | 50 | Acoperire Minimă Ponderată a Vârfurilor cu densitate de 8% a muchiilor | 100% | 1074 | 215 | 10 |
Începe
Mai întâi, autentifică-te folosind cheia API IBM Quantum. Apoi, selectează Funcția Qiskit după cum urmează. (Acest fragment de cod presupune că ai salvat deja contul în mediul tău local.)
from qiskit_ibm_catalog import QiskitFunctionsCatalog
catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")
# Access Function
solver = catalog.load("q-ctrl/optimization-solver")
Exemplu: Optimizare neconstrânsă
Rulează problema tăieturii maxime (Max-Cut). Următorul exemplu demonstrează capacitățile Solver-ului pe o problemă Max-Cut pe un graf 3-regulat neponderat cu 156 de noduri, dar poți rezolva și probleme pe grafuri ponderate.
Pe lângă qiskit-ibm-catalog, vei folosi și următoarele pachete pentru a rula acest exemplu: networkx și numpy. Poți instala aceste pachete decomentând celula de mai jos dacă rulezi acest exemplu într-un notebook folosind kernelul IPython.
# %pip install networkx numpy
1. Definește problema
Poți rula o problemă Max-Cut definind o problemă pe bază de graf și specificând problem_type='maxcut'.
import networkx as nx
import numpy as np
# Generate a random graph with 156 nodes
maxcut_graph = nx.random_regular_graph(d=3, n=156, seed=8)
# Optionally, visualize the graph
nx.draw_networkx(
maxcut_graph, nx.kamada_kawai_layout(maxcut_graph), node_size=100
)

Solver-ul acceptă un șir ca intrare pentru definiția problemei.
# Convert graph to string
problem_as_str = nx.readwrite.json_graph.adjacency_data(maxcut_graph)
2. Rulează problema
Când folosești metoda de intrare bazată pe graf, specifică tipul problemei.
# This cell is hidden from users
from qiskit_ibm_runtime import QiskitRuntimeService
service = QiskitRuntimeService()
backend_name = service.least_busy(n_qubits=156).name
# Solve the problem
maxcut_job = solver.run(
problem=problem_as_str,
problem_type="maxcut",
backend_name=backend_name, # E.g. "ibm_fez"
)
Verifică starea sarcinii din Funcția Qiskit sau recuperează rezultatele după cum urmează:
# Get job status
print(maxcut_job.status())
QUEUED
3. Recuperează rezultatul
Recuperează valoarea tăieturii optime din dicționarul de rezultate.
variables_to_bitstring_index_map, care ajută la verificarea ordinii.# Poll for results
maxcut_result = maxcut_job.result()
# Take the absolute value of the solution since the cost function is minimized
qctrl_maxcut = abs(maxcut_result["solution_bitstring_cost"])
# Print the optimal cut value found by the Optimization Solver
print(f"Optimal cut value: {qctrl_maxcut}")
Optimal cut value: 209.0
Poți verifica acuratețea rezultatului rezolvând problema clasic cu solvere open-source precum PuLP, dacă graful nu este dens conectat. Problemele cu densitate ridicată pot necesita solvere clasice avansate pentru a valida soluția.
Exemplu: Optimizare constrânsă
Exemplul anterior Max-Cut este o problemă de optimizare binară pătratică neconstrânsă frecventă. Optimization Solver de la Q-CTRL poate fi utilizat pentru diverse tipuri de probleme, inclusiv optimizare constrânsă. Poți rezolva tipuri arbitrare de probleme introducând definiția problemei reprezentată ca un polinom, unde restricțiile sunt modelate ca termeni de penalizare.
Următorul exemplu demonstrează cum să construiești o funcție cost pentru o problemă de optimizare constrânsă, acoperirea minimă a vârfurilor (MVC).
Pe lângă pachetele qiskit-ibm-catalog și qiskit, vei folosi și următoarele pachete pentru a rula acest exemplu: numpy, networkx și sympy. Poți instala aceste pachete decomentând celula de mai jos dacă rulezi acest exemplu într-un notebook folosind kernelul IPython.
# %pip install numpy networkx sympy
1. Definește problema
Definește o problemă MVC aleatoare generând un graf cu noduri ponderate aleator.
import networkx as nx
from sympy import symbols, Poly, srepr
# To change the weights, change the seed to any integer.
rng_seed = 18
_rng = np.random.default_rng(rng_seed)
node_count = 50
edge_probability = 0.08
mvc_graph = nx.erdos_renyi_graph(
node_count, edge_probability, seed=rng_seed, directed=False
)
# add node weights
for i in mvc_graph.nodes:
mvc_graph.add_node(i, weight=_rng.random())
# Optionally, visualize the graph
nx.draw_networkx(mvc_graph, nx.kamada_kawai_layout(mvc_graph), node_size=200)

Un model de optimizare standard pentru MVC ponderat poate fi formulat după cum urmează. Mai întâi, trebuie adăugată o penalizare pentru orice caz în care o muchie nu este conectată la un vârf din submulțime. Prin urmare, fie dacă vârful se află în acoperiș (adică în submulțime) și altfel. În al doilea rând, scopul este de a minimiza numărul total de vârfuri din submulțime, ceea ce poate fi reprezentat prin următoarea funcție:
# Construct the cost function.
variables = symbols([f"n[{i}]" for i in range(node_count)])
cost_function = Poly(0, variables)
for i in mvc_graph.nodes():
weight = mvc_graph.nodes[i].get("weight", 0)
cost_function += variables[i] * weight
Acum, fiecare muchie din graf trebuie să includă cel puțin un capăt din acoperiș, ceea ce poate fi exprimat ca inegalitate:
Orice caz în care o muchie nu este conectată la vârful acoperirii trebuie penalizat. Aceasta poate fi reprezentată în funcția cost prin adăugarea unei penalizări de forma unde este o constantă de penalizare pozitivă. Astfel, o alternativă neconstrânsă la inegalitatea constrânsă pentru MVC ponderat este:
# Add penalty term.
penalty_constant = 2
for i, j in mvc_graph.edges():
cost_function += penalty_constant * (
1 - variables[i] - variables[j] + variables[i] * variables[j]
)
2. Rulează problema
# Solve the problem
mvc_job = solver.run(
problem=srepr(cost_function),
backend_name=backend_name, # E.g. "ibm_fez"
)
Verifică starea sarcinii din Funcția Qiskit sau recuperează rezultatele după cum urmează:
print(mvc_job.status())
3. Obține rezultatul
Recuperează soluția și analizează rezultatele. Deoarece această problemă are noduri ponderate, soluția nu este pur și simplu numărul minim de noduri acoperite. În schimb, costul soluției reprezintă suma ponderilor vârfurilor incluse în acoperirea vârfurilor. Acesta reprezintă „costul" sau „greutatea" totală a acoperirii tuturor muchiilor din graf folosind vârfurile selectate.
mvc_result = mvc_job.result()
qctrl_cost = mvc_result["solution_bitstring_cost"]
# Print results
print(f"Solution cost: {qctrl_cost}")
Solution cost: 10.248198273708624
Obține suport
Pentru orice întrebări sau probleme, contactează Q-CTRL.
Pași următori
- Solicită acces la Q-CTRL Optimization Solver.
- Încearcă tutorialul Rezolvă probleme de optimizare binară de ordin superior cu Optimization Solver de la Q-CTRL.
- Consultă Sachdeva, N., et al. (2024). Quantum optimization using a 127-qubit gate-model IBM quantum computer can outperform quantum annealers for nontrivial binary optimization problems. arXiv preprint arXiv:2406.01743.
- Consultă Loco, D., et al. (2026). Practical protein-pocket hydration-site prediction for drug discovery on a quantum computer. arXiv preprint arXiv:2512.08390.
- Consultă studiul de caz Mazda.
- Consultă studiul de caz Network Rail.
- Consultă studiul de caz Australian Army.
- Consultă studiul de caz Transport for New South Wales.