Sari la conținutul principal
Acest proiect este în versiune beta. Ai găsit o eroare? Deschide un issue pe GitHub. Ai o întrebare sau o idee? Întreabă în Discussions — ne-ar plăcea să aflăm părerea ta!
Cum este calitatea traducerii pe această pagină?

SQOA Solver - un Qiskit Function de la JIJ

Vezi referința API.

notă

Qiskit Functions sunt o funcționalitate experimentală, disponibilă doar utilizatorilor planurilor IBM Quantum® Premium Plan, Flex Plan și On-Prem (prin API-ul IBM Quantum Platform). Se află în stadiul de versiune preview și pot suferi modificări.

Prezentare generală​

Cu SQOA Solver de la JIJ poți rezolva probleme mari de optimizare combinatorie pe calculatoare cuantice IBM®. Solverul se bazează pe Sampling-based Quantum Optimization Algorithm with Quantum Relaxation (SQOA-QR) [1]. Spre deosebire de algoritmii cuantici care folosesc o corespondență unu-la-unu între variabilele de decizie clasice și qubiți, SQOA Solver poate gestiona probleme de optimizare cu mai multe variabile decât numărul de qubiți disponibili pe dispozitivele cuantice actuale. Designul său bazat pe eșantionare îl face, de asemenea, mai puțin sensibil la zgomotul fizic al hardware-ului cuantic actual. Împreună, aceste caracteristici fac din SQOA Solver o alegere potrivită pentru problemele de optimizare în această etapă a calculului cuantic.

Solverul gestionează probleme Quadratic Unconstrained Binary Optimization (QUBO) date sub forma unei formulări matematice clasice și mapează automat formularea clasică în contextul cuantic. Poți, de asemenea, converti problemele cu constrângeri în probleme fără constrângeri folosind metoda penalizării.

Secțiunile următoare descriu fluxul de lucru al solverului, rezultatele benchmark-urilor și exemple cap-coadă care modelează probleme cu qiskit-addon-opt-mapper și, opțional, cu Open Mathematical prograMming eXchange (OMMX). OMMX este un format de date deschis și un SDK care simplifică schimbul de probleme de optimizare între instrumente software.

Descriere​

SQOA Solver implementează Sampling-based Quantum Optimization Algorithm with Quantum Relaxation (SQOA-QR) și îl înconjoară cu preprocesare și postprocesare clasică. Această secțiune explică framework-ul SQOA și prin ce diferă de Quantum Approximate Optimization Algorithm (QAOA).

Figura următoare prezintă o schemă a fluxului de lucru SQOA Solver. Schema fluxului de lucru SQOA Solver, de la preprocesarea clasică, prin eșantionarea SQOA, până la postprocesare și căutare locală

Framework-ul SQOA​

SQOA este un framework bazat pe eșantionare pentru optimizarea combinatorie [1]. Combină două tehnici: Quantum Random Access Optimization (QRAO) [2], care codifică problema într-o relaxare cuantică, și diagonalizarea cuantică bazată pe eșantioane (SQD) [3], cunoscută și ca interacțiune de configurații selectată cuantic (QSCI) [4], care folosește calculatorul cuantic doar pentru a eșantiona șiruri de biți și găsește starea de energie joasă pe un calculator clasic. SQOA este un framework în sensul că fixează această combinație, dar lasă detaliile în seama fiecărei implementări, cum ar fi modul în care variabilele sunt atribuite qubiților și ce circuite generează eșantioanele.

  • Relaxare cuantică cu QRAO. QAOA și alte abordări bazate pe Ising reprezintă fiecare variabilă binară prin operatorul ZZ al qubitului său. QRAO folosește și operatorii XX și YY. Cu un cod cuantic de acces aleatoriu (QRAC) de tip (3,1), până la trei variabile binare partajează un singur qubit, iar fiecare variabilă este reprezentată de un alt operator Pauli.

    QUBO devine astfel un Hamiltonian relaxat care necesită mai puțini qubiți decât Hamiltonianul Ising. Variabilele care interacționează în QUBO trebuie plasate pe qubiți diferiți. Dacă ar partaja un qubit, produsul operatorilor lor Pauli s-ar reduce la un singur operator pe acel qubit (de exemplu, XY=iZXY = iZ), iar Hamiltonianul relaxat nu ar mai reprezenta interacțiunea lor.

    Atribuirea variabilelor la qubiți determină, prin urmare, atât numărul de qubiți, cât și calitatea relaxării, iar SQOA Solver proiectează această atribuire în preprocesarea sa.

  • Diagonalizare cuantică bazată pe eșantioane (SQD). Calculatorul cuantic pregătește mai întâi o stare cuantică ce se suprapune cu stările de energie joasă ale Hamiltonianului relaxat și apoi eșantionează din ea șiruri de biți. Un calculator clasic proiectează Hamiltonianul relaxat pe subspațiul generat de șirurile de biți eșantionate și îl diagonalizează pentru a aproxima starea fundamentală.

    Deoarece Hamiltonianul relaxat nu este diagonal, diagonalizarea combină șirurile de biți eșantionate într-o suprapunere. Cu un Hamiltonian Ising diagonal, fiecare șir de biți este deja o stare proprie, iar diagonalizarea ar selecta doar cel mai bun eșantion. Aceeași abordare a fost aplicată unor probleme de scară mare din chimia cuantică.

Starea fundamentală aproximativă obținută prin SQD nu corespunde direct unei soluții clasice a problemei originale, deci soluția clasică trebuie decodată din ea. Deoarece această stare este calculată pe un calculator clasic, decodarea, numită rotunjire, este o postprocesare clasică. SQOA Solver folosește tehnici de decodare concepute pentru a obține euristic soluții clasice mai bune.

Tabelul următor compară SQOA cu QAOA, o abordare variațională comună pentru aceeași clasă de probleme.

 QAOASQOA
Qubiți pentru nn variabile binarennUn qubit conține până la trei dintre variabile. Numărul exact depinde de structura problemei
Utilizarea QPUEstimează în mod repetat energia circuitelor parametrizate în interiorul unei bucle clasice de optimizareDoar eșantionează șiruri de biți. Pe QPU nu se antrenează parametri de circuit
De la eșantioane la o soluțieSelectează cel mai bun șir de biți măsuratDiagonalizează pe un calculator clasic Hamiltonianul relaxat în subspațiul eșantionat și rotunjește starea rezultată

În jurul SQOA-QR, SQOA Solver adaugă procesare clasică. Preprocesarea sa fixează variabilele ale căror valori optime pot fi determinate în avans și proiectează atribuirea variabilelor la qubiți. Postprocesarea sa rafinează soluția rotunjită printr-o căutare locală, pe care o poți dezactiva cu postprocessing_level=0.

Benchmark-uri​

Declinare de responsabilitate

Performanța poate depinde atât de instanța problemei, cât și de pașii de procesare ulterioară. În unele cazuri, eșantioanele clasice și cele generate cuantic pot atinge o calitate finală similară a soluției după o postprocesare echivalentă. Evaluarea trebuie, prin urmare, să ia în considerare întregul flux de lucru de optimizare.

Următoarele metrici de benchmark oferă o indicație generală a calității soluției, a compresiei qubiților și a timpului de execuție pentru dimensiuni și structuri selectate ale problemelor. Tabelul listează o selecție de instanțe Maximum Independent Set din Quantum Optimization Benchmarking Library (QOBLIB) și două instanțe MaxCut 3-regulate. Poți încărca instanțele QOBLIB ca obiecte ommx.v1.Instance, împreună cu soluțiile lor optime, folosind pachetul ommx-quantum-benchmarks.

Fiecare instanță a fost rulată de 10 ori pe un procesor IBM Heron r2. Number of qubits numără qubiții folosiți efectiv pe hardware după preprocesare și codificarea QRAC. Raportul de compresie depinde de instanță. Approximation ratio (AR) indică calitatea celei mai bune soluții găsite în cele 10 rulări:

AR=CbestCopt,\mathrm{AR} = \frac{C_{\textrm{best}}}{C_{\textrm{opt}}},

unde CbestC_{\textrm{best}} este cea mai bună valoare a obiectivului găsită, iar CoptC_{\textrm{opt}} este valoarea optimă cunoscută a obiectivului. Toate instanțele sunt probleme de maximizare cu valoare optimă pozitivă, deci AR este cel mult 100%, iar 100% în coloana Approximation ratio indică faptul că solverul a găsit o soluție optimă. Total time este timpul mediu combinat QPU și CPU per rulare. QPU time este utilizarea medie IBM Quantum Compute per rulare.

InstanțăNumăr de variabileNumăr de qubițiRaport de aproximareTimp total (secunde)Timp QPU (secunde)
maxcut_384_nodes38412998.5%62.112.0
gen200_p0-9_4420067100%38.012.0
es60fst0218642100%24.712.0
es60fst0416229100%17.912.0
maxcut_150_nodes15051100%23.112.0
sloane_1dc_1281283793.8%19.112.0
sloane_2dc_1281288100%12.311.5
C125-912543100%22.312.0
es60fst0112312100%13.612.0
es60fst0311326100%14.912.0
sloane_1dc_646416100%13.411.9
chesapeake3913100%13.112.0
football356100%12.512.0
karate342100%6.26.0
ibm323211100%12.912.0
farm174100%8.58.0

Primii pași​

Găsește informațiile de acces pentru acest Qiskit Function în Qiskit Functions Catalog.

Această secțiune arată cum să te autentifici și să încarci funcția și cum să pregătești o problemă în formatul de dicționar acceptat de SQOA Solver, folosind OptimizationProblem din qiskit-addon-opt-mapper. Exemplele următoare rulează funcția și citesc rezultatul.

Autentifică-te și încarcă funcția​

Mai întâi, autentifică-te cu cheia ta API IBM Quantum. (Codul următor presupune că ți-ai salvat deja contul în mediul tău local.) Apoi, creează un client de catalog astfel:

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

_needed = {"jijmodeling": "jijmodeling", "networkx": "networkx", "ommx": "ommx", "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(jij/sqoa-solver)]
solver = catalog.load("jij/sqoa-solver")

Pregătește datele de intrare cu qiskit-addon-opt-mapper​

Acest ghid modelează problemele cu clasa OptimizationProblem din qiskit-addon-opt-mapper. SQOA Solver acceptă o problemă QUBO ca dicționar de coeficienți în formatul tuplu-șir folosit de funcțiile de optimizare IBM, astfel încât fiecare exemplu din acest ghid urmează același model de pregătire pe partea clientului:

  1. Scrie modelul. Creează un OptimizationProblem, adaugă variabile de decizie binare și setează obiectivul și eventualele constrângeri.

  2. Convertește în QUBO. Convertește problema cu OptimizationProblemToQubo, care adaugă eventualele constrângeri la obiectiv ca termeni de penalizare și returnează o problemă echivalentă de minimizare fără constrângeri.

  3. Convertește într-un dicționar. Transmite QUBO funcției ajutătoare to_problem_dict() definite în secțiunea următoare și transmite rezultatul lui solver.run() ca problem, împreună cu variable_type="binary".

SQOA Solver minimizează întotdeauna o problemă de tip dicționar, ceea ce corespunde problemei de minimizare returnate de OptimizationProblemToQubo. Pentru o problemă de maximizare, objective_value returnat este, prin urmare, negativul obiectivului original. Pentru a citi rezultatul în termenii problemei originale, evaluează atribuirea returnată cu OptimizationProblem, așa cum arată exemplele. Pentru detalii despre formatul dicționarului, vezi Formate de probleme acceptate în referința API.

# %pip install qiskit-addon-opt-mapper

Definește o singură dată următoarea funcție ajutătoare și reutilizeaz-o în fiecare exemplu. Ea convertește QUBO returnat de OptimizationProblemToQubo în formatul de dicționar. Cheile folosesc indicii variabilelor din QUBO, deci cheile soluției x_0, x_1 și așa mai departe din rezultat corespund acestor indici. Fiecare variabilă primește o intrare liniară, chiar și cu coeficient zero, astfel încât soluția returnată să acopere toate variabilele.

from qiskit_addon_opt_mapper import OptimizationProblem
from qiskit_addon_opt_mapper.converters import OptimizationProblemToQubo

def to_problem_dict(qubo: OptimizationProblem) -> dict[str, float]:
"""Convert a QUBO from OptimizationProblemToQubo to the SQOA Solver dictionary format."""
objective = qubo.objective
payload = {"()": objective.constant}
# Keep every variable in the problem, even with a zero linear coefficient.
payload.update({f"({i},)": 0.0 for i in range(qubo.get_num_vars())})
for i, coefficient in objective.linear.to_dict().items():
payload[f"({i},)"] += coefficient
for (i, j), coefficient in objective.quadratic.to_dict().items():
# Fold a binary diagonal term x_i * x_i = x_i into the linear term.
key = f"({i},)" if i == j else f"({i}, {j})"
payload[key] = payload.get(key, 0.0) + coefficient
return {key: float(value) for key, value in payload.items()}

Exemplul 1: MaxCut pe un graf 3-regulat​

Multe probleme de grafuri, precum MaxCut, sunt NP-hard și sunt candidate naturale pentru optimizarea cuantică. Instalează networkx ca dependență suplimentară pentru a rula acest exemplu:

# %pip install networkx

1. Scrie modelul​

Atribuie o variabilă binară xv∈{0,1}x_v \in \{0, 1\} fiecărui vârf al unui graf G=(V,E)G = (V, E) pentru a indica de ce parte a tăieturii se află. O muchie este tăiată atunci când extremitățile ei se află de părți diferite, deci dimensiunea tăieturii este:

Cut(x)=∑(u,v)∈E(xu+xv−2xuxv).\mathrm{Cut}(x) = \sum_{(u,v) \in E} \left(x_u + x_v - 2 x_u x_v\right).

Acest obiectiv este deja un QUBO fără constrângeri, așa că OptimizationProblemToQubo doar transformă maximizarea în minimizarea echivalentă și păstrează variabilele neschimbate. Clasa de aplicație Maxcut din qiskit_addon_opt_mapper.applications construiește același model cu Maxcut(G).to_optimization_problem().

import networkx as nx

G = nx.random_regular_graph(3, 40, seed=42)

linear = {v: 0 for v in G.nodes}
quadratic = {}
for u, v in G.edges:
linear[u] += 1
linear[v] += 1
quadratic[(u, v)] = -2

maxcut = OptimizationProblem("MaxCut")
maxcut.binary_var_list(G.number_of_nodes(), name="x")
maxcut.maximize(linear=linear, quadratic=quadratic)

2. Rulează solverul​

Convertește modelul într-un QUBO și apoi într-un dicționar și trimite-l. problem și variable_type sunt obligatorii. backend_name este opțional. Când este omis sau este None, funcția selectează QPU-ul operațional cel mai puțin ocupat, disponibil instanței tale.

Dicționarul options acceptă shots, seed, session, postprocessing_level și job_tags. Pentru descrieri și valori implicite, vezi referința API.

qubo = OptimizationProblemToQubo().convert(maxcut)

job = solver.run(
problem=to_problem_dict(qubo),
variable_type="binary",
backend_name="ibm_fez",
options={
"shots": 4096,
"seed": 42,
},
)

3. Obține rezultatul​

job.result() returnează un dicționar cu patru chei:

  • solution este atribuirea completă a variabilelor, cu cheile x_i, unde i este indicele variabilei (de exemplu, x_3).

  • objective_value și feasible sunt obiectivul și fezabilitatea acelei atribuiri, evaluate pe dicționarul trimis.

  • metadata conține solver_info și resource_usage.

Deoarece QUBO este forma de minimizare a lui MaxCut, objective_value este negativul dimensiunii tăieturii. Evaluează atribuirea pe OptimizationProblem original pentru a citi direct dimensiunea tăieturii.

result = job.result()

x = [result["solution"][f"x_{i}"] for i in range(maxcut.get_num_vars())]
print(f"Cut value: {maxcut.objective.evaluate(x)}")
print(f"Nodes on side 1: {[v for v, value in enumerate(x) if value > 0.5]}")
Cut value: 55.0
Nodes on side 1: [5, 7, 9, 11, 14, 16, 17, 19, 21, 23, 24, 26, 30, 31, 33, 34, 36, 37, 38]

4. Verifică utilizarea resurselor​

result["metadata"]["resource_usage"] raportează timpul petrecut în fiecare fază de execuție. Fazele altele decât RUNNING: EXECUTING_QPU raportează CPU_TIME, timpul real (wall-clock) al fazei în secunde, atunci când este disponibil.

Faza RUNNING: EXECUTING_QPU raportează QPU_TIME, utilizarea QPU a tuturor joburilor Quantum Compute ale rulării, dacă utilizarea finală este disponibilă pentru fiecare job. Pentru detalii, vezi referința API.

for phase, metrics in result["metadata"]["resource_usage"].items():
line = f"{phase:36s}"
if "CPU_TIME" in metrics:
line += f" CPU {metrics['CPU_TIME']:8.1f} s"
if "QPU_TIME" in metrics:
line += f" QPU {metrics['QPU_TIME']:8.1f} s"
print(line)
RUNNING: MAPPING CPU 3.2 s
RUNNING: OPTIMIZING_FOR_HARDWARE CPU 5.0 s
RUNNING: WAITING_FOR_QPU CPU 1.1 s
RUNNING: EXECUTING_QPU QPU 3.0 s
RUNNING: POST_PROCESSING CPU 0.9 s

Exemplul 2: Convertește o problemă cu constrângeri în QUBO​

SQOA Solver acceptă probleme fără constrângeri. Acest exemplu arată cum să convertești o problemă cu constrângeri într-un QUBO cu OptimizationProblemToQubo și să mapezi rezultatul înapoi la variabilele problemei originale.

selection = OptimizationProblem("ConstrainedExample")
selection.binary_var_list(2, name="x")
selection.maximize(linear={"x0": 1, "x1": 1})
selection.linear_constraint({"x0": 1, "x1": 1}, "<=", 1, name="at_most_one")

print(selection.prettyprint())
Problem name: ConstrainedExample

Maximize
x0 + x1

Subject to
Linear constraints (1)
x0 + x1 <= 1 'at_most_one'

Binary variables (2)
x0 x1

OptimizationProblemToQubo adaugă constrângerile la obiectiv ca termeni de penalizare și convertește problema în minimizare. Ponderea potrivită a penalizării depinde de problemă.

După rulare, interpret() mapează atribuirea QUBO înapoi la variabilele problemei originale.

Evaluează obiectivul și fezabilitatea pe problema originală. Pentru o problemă de tip dicționar, câmpul feasible al rezultatului se referă doar la domeniul variabilelor, deoarece dicționarul nu are constrângeri.

converter = OptimizationProblemToQubo(penalty=4.0)
qubo = converter.convert(selection)

job = solver.run(
problem=to_problem_dict(qubo),
variable_type="binary",
backend_name="ibm_fez",
)
result = job.result()

x_qubo = [result["solution"][f"x_{i}"] for i in range(qubo.get_num_vars())]
x = converter.interpret(x_qubo)
print("Objective:", selection.objective.evaluate(x))
print("Feasible:", selection.is_feasible(x))
print("x values:", x)
Objective: 1.0
Feasible: True
x values: [1. 0.]

Exemplul 3: Trimite o instanță OMMX​

SQOA Solver acceptă și un ommx.v1.Instance din SDK-ul OMMX, care păstrează laolaltă cu problema numele variabilelor, indicii și metadatele de conversie. Comparativ cu un dicționar, o intrare OMMX are următoarele avantaje:

  • Rezultatul conține, de asemenea, ommx.v1.Solution canonic în solver_info["ommx_solution"].

  • objective_value este evaluat în sensul instanței, deci obiectivul unei probleme de maximizare nu este negat.

  • Pentru o instanță convertită pe loc cu Instance.to_qubo(), feasible este evaluat în raport cu constrângerile originale.

Acest exemplu construiește modelul MaxCut din Exemplul 1 cu JijModeling, un instrument de modelare a optimizării matematice care compilează modelele în instanțe OMMX. Instalează JijModeling, care instalează și pachetul ommx:

# %pip install "jijmodeling~=2.8.0"

SQOA Solver schimbă datele OMMX sub forma unor șiruri Base64 standard cu padding. Definește următoarele funcții ajutătoare pentru această conversie:

  • to_problem_payload() serializează un ommx.v1.Instance în șirul pe care îl transmiți ca problem.

  • to_ommx_solution() decodează ommx.v1.Solution canonic din rezultat.

import base64

from ommx.v1 import Instance, Solution

def to_problem_payload(instance: Instance) -> str:
"""Serialize an OMMX instance into the `problem` string for SQOA Solver."""
return base64.b64encode(instance.to_bytes()).decode()

def to_ommx_solution(result: dict) -> Solution:
"""Decode the canonical OMMX solution from a SQOA Solver result."""
payload = result["metadata"]["solver_info"]["ommx_solution"]
return Solution.from_bytes(base64.b64decode(payload, validate=True))

1. Scrie modelul cu JijModeling​

Formularea obișnuită cu spini a lui MaxCut pe un graf G=(V,E)G = (V, E) atribuie sv∈{−1,+1}s_v \in \{-1, +1\} fiecărui vârf. O muchie este tăiată atunci când susv=−1s_u s_v = -1, deci dimensiunea tăieturii este:

Cut⁡(s)=∑(u,v)∈E1−susv2.\operatorname{Cut}(s) = \sum_{(u,v) \in E} \frac{1 - s_u s_v}{2}.

JijModeling nu oferă o variabilă de decizie de spin nativă, iar SQOA Solver acceptă variabile QUBO binare. Prin urmare, declară bv∈{0,1}b_v \in \{0, 1\} și definește expresia cu valori de spin sv=1−2bvs_v = 1 - 2b_v în interiorul modelului. Cu această expresie, obiectivul rămâne în forma standard cu spini, iar instanța compilată rămâne un QUBO binar.

import jijmodeling as jm

@jm.Problem.define("MaxCut", sense=jm.ProblemSense.MAXIMIZE)
def maxcut_model(problem: jm.DecoratedProblem):
V = problem.Natural() # number of nodes
E = problem.Graph(dtype=V) # edge list
b = problem.BinaryVar(shape=(V,))
s = 1 - 2 * b # spin-valued expression

problem += jm.sum((1 - s[u] * s[v]) / 2 for u, v in E)

Dacă afișezi maxcut_model într-un notebook, acesta arată următoarea formulare:

Problem ⁣:MaxCutmax⁡∑⟨u,v⟩∈E1−(1−2⋅b)u⋅(1−2⋅b)v2whereDecision Variables:bi∈{0,1}a 1-dim array of binary decision variables∀i∈{0,…,V−1}Placeholders:Ei∈V×Va 1-dim array of placeholders with elements in V×V∀i∈{0,…,len_at(E,0)−1}V∈Na scalar placeholder in N\begin{array}{rl} \text{Problem}\colon &\text{MaxCut}\\ \displaystyle \max &\displaystyle \sum _{\left\langle u,v\right\rangle \in E}{\frac{1-{\left(1-2\cdot b\right)}_{u}\cdot {\left(1-2\cdot b\right)}_{v}}{2}}\\ &\\ \text{where}&\\ &\text{Decision Variables:}\\ &\qquad \begin{alignedat}{2}{b}_{i}&\in \left\{0,1\right\}&\qquad &\text{a }1\text{-dim array of }\text{binary}\text{ decision variables}\\ &\forall i\in \left\{0,\ldots ,V-1\right\}&&\\ \end{alignedat}\\ &\\ &\text{Placeholders:}\\ &\qquad \begin{alignedat}{2}{E}_{i}&\in V\times V&\qquad &\text{a }1\text{-dim array of placeholders with elements in }V\times V\\ &\forall i\in \left\{0,\ldots ,\mathop{\mathtt{len\_{}at}}\left(E,0\right)-1\right\}&&\\ &&&\\ V&\in \mathbb{N}&\qquad &\text{a scalar placeholder in }\mathbb{N}\\ \end{alignedat}\end{array}

2. Compilează instanța și rulează solverul​

Leagă graful din Exemplul 1 pentru a compila un ommx.v1.Instance și trimite-l cu variable_type="binary". O instanță OMMX este întotdeauna trimisă ca problemă binară.

instance = maxcut_model.eval(
{"V": G.number_of_nodes(), "E": [list(edge) for edge in G.edges]}
)

job = solver.run(
problem=to_problem_payload(instance),
variable_type="binary",
backend_name="ibm_fez",
)

3. Obține rezultatul​

Pentru o intrare OMMX, objective_value este dimensiunea tăieturii, iar to_ommx_solution() decodează soluția canonică, astfel încât să poți citi atribuirea după numele variabilei.

result = job.result()
print(f"Cut value: {result['objective_value']}")

solution = to_ommx_solution(result)
b_values = solution.extract_decision_variables("b")
print(
f"Nodes on side 1: {sorted(v for (v,), value in b_values.items() if value > 0.5)}"
)
Cut value: 55.0
Nodes on side 1: [5, 7, 9, 11, 14, 16, 17, 19, 21, 23, 24, 26, 30, 31, 33, 34, 36, 37, 38]

Obține asistență​

Pentru asistență, trimite un e-mail la info@j-ij.com.

Pașii următori​

Recomandări

Referințe​

[1] Matsuyama, H., & Yamashiro, Y. (2025). Sampling-based quantum optimization algorithm with quantum relaxation. 2025 IEEE International Conference on Quantum Computing and Engineering (QCE), 1, 2323–2333. DOI, arXiv:2504.12629

[2] Fuller, B., Hadfield, C., Glick, J. R., Imamichi, T., Itoko, T., Thompson, R. J., Jiao, Y., Kagele, M. M., Blom-Schieber, A. W., Raymond, R., et al. (2024). Approximate solutions of combinatorial problems via quantum relaxations. IEEE Transactions on Quantum Engineering, 5, 1–15. DOI, arXiv:2111.03167

[3] Robledo-Moreno, J., Motta, M., Haas, H., Javadi-Abhari, A., Jurcevic, P., Kirby, W., et al. (2025). Chemistry beyond the scale of exact diagonalization on a quantum-centric supercomputer. Science Advances, 11(25), eadu9991. DOI, arXiv:2405.05068

[4] Kanno, K., Kohda, M., Imai, R., Koh, S., Mitarai, K., Mizukami, W., & Nakagawa, Y. O. (2026). Quantum-selected configuration interaction: Classical diagonalization of Hamiltonians in subspaces selected by quantum computers. Physical Review Research, 8(2), 023268. DOI, arXiv:2302.11320