Sari la conținutul principal

Iskay Quantum Optimizer - O Funcție Qiskit de la Kipu Quantum

Notă
  • Funcțiile Qiskit sunt o funcționalitate experimentală disponibilă doar utilizatorilor cu plan IBM Quantum® Premium, Flex și On-Prem (prin IBM Quantum Platform API). Acestea se află în stadiu de previzualizare și pot fi modificate.

Prezentare generală

Cu Iskay Quantum Optimizer de la Kipu Quantum, poți aborda probleme complexe de optimizare folosind calculatoarele® cuantice IBM. Acest solver folosește algoritmul de ultimă generație bf-DCQO al Kipu, necesitând doar funcția obiectiv ca intrare pentru a livra automat soluții la probleme. Poate gestiona probleme de optimizare cu până la 156 de qubiți, permițând utilizarea tuturor qubiților dispozitivelor cuantice IBM. Optimizer-ul folosește o mapare 1-la-1 între variabilele clasice și qubiți, ceea ce îți permite să abordezi probleme de optimizare cu până la 156 de variabile binare.

Optimizer-ul permite rezolvarea problemelor de optimizare binară neconstrânsă. Pe lângă formularea QUBO (Quadratic Unconstrained Binary Optimization) utilizată frecvent, acceptă și probleme de optimizare de ordin superior (HUBO). Solver-ul utilizează un algoritm cuantic non-variațional, efectuând cea mai mare parte a calculului pe dispozitive cuantice.

Cele ce urmează oferă mai multe detalii despre algoritmul utilizat și un ghid succint privind utilizarea funcției, precum și rezultatele testelor de performanță pe diverse instanțe de probleme de diferite dimensiuni și complexități.

Descriere

Optimizer-ul este o implementare gata de utilizare a unor algoritmi cuantici de optimizare de ultimă generație. Rezolvă probleme de optimizare rulând circuite cuantice puternic comprimate pe hardware cuantic. Această compresie este obținută prin introducerea termenilor contradiabatici în evoluția temporală a sistemului cuantic. Algoritmul execută mai multe iterații de rulări pe hardware pentru a obține soluțiile finale și le combină cu post-procesare. Acești pași sunt integrați fără probleme în fluxul de lucru al Optimizer-ului și sunt executați automat.

Cum funcționează Quantum Optimizer?

Această secțiune descrie principiile de bază ale algoritmului bf-DCQO implementat. O introducere în algoritm poate fi găsită și pe canalul YouTube Qiskit.

Algoritmul se bazează pe evoluția temporală a unui sistem cuantic care se transformă în timp, unde soluția problemei este codificată în starea de bază a sistemului cuantic la sfârșitul evoluției. Conform teoremei adiabatice, această evoluție trebuie să fie lentă pentru a garanta că sistemul rămâne în starea sa de bază. Digitizarea acestei evoluții stă la baza calculului cuantic adiabatic digitizat (DQA) și a infamului algoritm QAOA. Cu toate acestea, evoluția lentă necesară nu este fezabilă pentru dimensiuni crescânde ale problemei, deoarece duce la o adâncime crescândă a Circuit-ului. Prin utilizarea protocoalelor contradiabatice, poți suprima excitațiile nedorite care apar în timpul evoluțiilor scurte, rămânând totodată în starea de bază. Digitizarea acestui timp de evoluție mai scurt duce la Circuit-uri cuantice cu adâncime mai mică și mai puține Gate-uri de entanglare.

Circuit-urile algoritmilor bf-DCQO utilizează în mod tipic de până la zece ori mai puține Gate-uri de entanglare decât DQA și de trei până la patru ori mai puține Gate-uri de entanglare decât implementările standard QAOA. Datorită numărului mai mic de Gate-uri, apar mai puține erori în timpul execuției Circuit-ului pe hardware. Prin urmare, Optimizer-ul nu necesită utilizarea tehnicilor de suprimare sau de atenuare a erorilor. Implementarea lor în versiunile viitoare poate îmbunătăți și mai mult calitatea soluției.

Deși algoritmul bf-DCQO utilizează iterații, acesta este non-variațional. După fiecare iterație a algoritmului, distribuția stărilor este măsurată. Distribuția obținută este utilizată pentru a calcula un așa-numit câmp de polarizare (bias-field). Câmpul de polarizare permite inițierea următoarei iterații dintr-o stare energetică apropiată de soluția găsită anterior. În acest fel, algoritmul se deplasează cu fiecare iterație spre soluții de energie mai mică. De obicei, aproximativ zece iterații sunt suficiente pentru a converge la o soluție, necesitând în total un număr mult mai mic de iterații decât algoritmii variaționali, care este de ordinul a aproximativ 100 de iterații.

Optimizer-ul combină algoritmul bf-DCQO cu post-procesare clasică. După măsurarea distribuției stărilor, se efectuează o căutare locală. În timpul căutării locale, biții soluției măsurate sunt inversați aleatoriu. După inversare, energia noului șir de biți este evaluată. Dacă energia este mai mică, șirul de biți este păstrat ca noua soluție. Căutarea locală scalează liniar cu numărul de qubiți; prin urmare, este eficientă din punct de vedere computațional. Deoarece post-procesarea corectează inversările locale de biți, compensează erorile de inversare a biților care sunt adesea rezultatul imperfecțiunilor hardware și al erorilor de citire.

Flux de lucru

Urmează o schemă a fluxului de lucru al Quantum Optimizer.

Workflow

Prin utilizarea Quantum Optimizer, rezolvarea unei probleme de optimizare pe hardware cuantic poate fi redusă la

  • Formularea funcției obiectiv a problemei
  • Accesarea Optimizer-ului prin Qiskit Functions
  • Rularea Optimizer-ului și colectarea rezultatului

Benchmarks

Metricile de benchmark de mai jos arată că Optimizer-ul abordează eficient problemele cu până la 156 de qubiți și oferă o privire de ansamblu generală asupra acurateței și scalabilității Optimizer-ului pentru diferite tipuri de probleme. Reține că metricile reale de performanță pot varia în funcție de caracteristicile specifice ale problemei, cum ar fi numărul de variabile, densitatea și localitatea termenilor din funcția obiectiv și ordinul polinomial.

Tabelul următor include raportul de aproximare (AR), o metrică definită astfel:

AR=CCmaxCminCmax,AR = \frac{C^{*} - C_\textrm{max}}{C_{\textrm{min}} - C_{\textrm{max}}},

unde CC este funcția obiectiv, CminC_{\textrm{min}}, CmaxC_{\textrm{max}} sunt valorile sale minime și maxime, iar CC^{*} este costul celei mai bune soluții găsite, respectiv. Prin urmare, AR=100% înseamnă că s-a obținut starea de bază a problemei.

ExempluNumăr de qubițiRaport de aproximareTimp total (s)Utilizare runtime (s)Număr total de shotsNumăr de iterații
Unweighted MaxCut28100%1803030k5
Unweighted MaxCut30100%1803030k5
Unweighted MaxCut32100%1803030k5
Unweighted MaxCut80100%4806090k9
Unweighted MaxCut100100%3306060k6
Unweighted MaxCut120100%3706060k6
HUBO 1156100%60070100k10
HUBO 2156100%60070100k10
  • Instanțele MaxCut cu 28, 30 și 32 de qubiți au rulat pe ibm_sherbrooke. Instanțele cu 80, 100 și 120 au rulat pe un procesor Heron r2.
  • Instanțele HUBO au rulat de asemenea pe un procesor Heron r2.

Toate instanțele de benchmark sunt accesibile pe GitHub (vezi instanțe benchmark Kipu). Un exemplu pentru rularea acestor instanțe poate fi găsit în Exemplul 3: Instanțe benchmark.

Intrări și ieșiri

Intrare

Consultă tabelul următor pentru toți parametrii de intrare acceptați de Quantum Optimizer. Secțiunea Opțiuni de mai jos oferă detalii suplimentare despre options disponibile.

NumeTipDescriereObligatoriuImplicitExemplu
problemDict[str, float]Coeficienții problemei de optimizare formulate ca QUBO/HUBO sau în format spin. Pentru mai multe informații despre specificarea problemei, vezi Formate acceptate pentru problemeDaN/A{"()": -21.0, "(0, 4)": 0.5,"(0, 2)": 0.5,"(0, 1)": 0.5,"(1, 3)": 0.5}
problem_typestrSpecifică dacă coeficienții problemei sunt în format binar (QUBO/HUBO) sau spin. Cele două variante posibile sunt "spin" sau "binary"DaN/A"spin"
backend_namestrNumele Backend-ului pe care se efectuează interogareaDaN/A"ibm_fez"
optionsDict[str, Any]Opțiuni pentru gestionarea trimiterii pe hardware, cum ar fi numărul de măsurători. Pentru mai multe detalii despre configurarea opțiunilor, vezi secțiunea OpțiuniNuPentru a vedea valorile implicite ale configurației opțiunilor, consultă secțiunea Opțiuni{"shots": 5000, "num_iterations": 3, "use_session": True, "seed_transpiler": 42}

Formate acceptate pentru probleme

Argumentele problem și problem_type codifică o problemă de optimizare de forma

min(x1,x2,,xn)DC(x1,x2,,xn)\begin{align} \min_{(x_1, x_2, \ldots, x_n) \in D} C(x_1, x_2, \ldots, x_n) \nonumber \end{align}

unde

C(x1,...,xn)=a+ibixi+i,jci,jxixj+...+k1,...,kmgk1,...,kmxk1...xkmC(x_1, ... , x_n) = a + \sum_{i} b_i x_i + \sum_{i, j} c_{i, j} x_i x_j + ... + \sum_{k_1, ..., k_m} g_{k_1, ..., k_m} x_{k_1} ... x_{k_m}
  • Alegând problem_type = "binary", specifici că funcția de cost este în format binary, ceea ce înseamnă că D={0,1}nD = \{0, 1\}^{n}, adică funcția de cost este scrisă în formulare QUBO/HUBO.
  • Pe de altă parte, alegând problem_type = "spin", funcția de cost este scrisă în formulare Ising, unde D={1,1}nD = \{-1, 1\}^{n}.

Coeficienții problemei trebuie codificați într-un dicționar după cum urmează:

{"()":a,"(i,)":bi,"(i, j)":ci,j,"(k1,...,km)":gk1,...,km,}\begin{align} \nonumber &\texttt{\{} \\ \nonumber &\texttt{"()"}&: \quad &a, \\ \nonumber &\texttt{"(i,)"}&: \quad &b_i, \\ \nonumber &\texttt{"(i, j)"}&: \quad &c_{i, j}, \\ \nonumber &\quad \vdots \\ \nonumber &\texttt{"(} k_1, ..., k_m \texttt{)"} &: \quad &g_{k_1, ..., k_m}, \\ \nonumber &\texttt{\}} \end{align}
  • Reține că cheile dicționarului trebuie să fie șiruri de caractere care conțin un tuplu valid de numere întregi nerepetate.

Opțiuni

Iskay oferă posibilități de reglaj fin prin parametri opționali. Deși valorile implicite funcționează bine pentru majoritatea problemelor, poți personaliza comportamentul pentru cerințe specifice:

ParametruTipImplicitDescriere
shotsint10000Măsurători cuantice per iterație (mai multe = mai precis)
num_iterationsint10Iterații ale algoritmului (mai multe iterații pot îmbunătăți calitatea soluției)
use_sessionboolTrueFolosește Session-uri IBM pentru timpi de așteptare reduși
seed_transpilerintNoneSetează pentru compilare reproductibilă a Circuit-ului cuantic
direct_qubit_mappingboolFalseMapează Qubit-urile virtuale direct pe Qubit-urile fizice
job_tagsList[str]NoneEtichete personalizate pentru urmărirea joburilor
preprocessing_levelint0Intensitatea preprocesării problemei (0-3) - vezi detaliile de mai jos
postprocessing_levelint2Nivelul de rafinare a soluției (0-2) - vezi detaliile de mai jos
transpilation_levelint0Încercări de optimizare ale Transpiler-ului (0-5) - vezi detaliile de mai jos
transpile_onlyboolFalseAnalizează optimizarea Circuit-ului fără a rula execuția completă

Niveluri de preprocesare (0-3): Deosebit de importante pentru problemele mai mari care nu pot fi în prezent rulate în timpii de coerență ai hardware-ului. Nivelurile mai ridicate de preprocesare obțin adâncimi mai mici ale Circuit-ului prin aproximări în transpilarea problemei:

  • Nivelul 0: Exact, circuite mai lungi
  • Nivelul 1: Echilibru bun între acuratețe și aproximare, eliminând doar porțile cu unghiuri în cel mai mic percentil 10
  • Nivelul 2: Aproximare ușor mai ridicată, eliminând porțile cu unghiuri în cel mai mic percentil 20 și folosind approximation_degree=0.95 în transpilare
  • Nivelul 3: Nivel maxim de aproximare, eliminând porțile din cel mai mic percentil 30 și folosind approximation_degree=0.90 în transpilare

Niveluri de transpilare (0-5): Controlează încercările avansate de optimizare ale Transpiler-ului pentru compilarea Circuit-ului cuantic. Aceasta poate duce la o creștere a suprasolicitării clasice și, în unele cazuri, s-ar putea să nu modifice adâncimea Circuit-ului. Valoarea implicită 2 conduce în general la cel mai mic Circuit și este relativ rapidă.

  • Nivelul 0: Optimizarea Circuit-ului DCQO descompus (plasare, rutare, planificare)
  • Nivelul 1: Optimizarea PauliEvolutionGate și apoi a Circuit-ului DCQO descompus (max_trials=10)
  • Nivelul 2: Optimizarea PauliEvolutionGate și apoi a Circuit-ului DCQO descompus (max_trials=15)
  • Nivelul 3: Optimizarea PauliEvolutionGate și apoi a Circuit-ului DCQO descompus (max_trials=20)
  • Nivelul 4: Optimizarea PauliEvolutionGate și apoi a Circuit-ului DCQO descompus (max_trials=25)
  • Nivelul 5: Optimizarea PauliEvolutionGate și apoi a Circuit-ului DCQO descompus (max_trials=50)

Niveluri de postprocesare (0-2): Controlează cât de multă optimizare clasică, ce compensează erorile de bit-flip, se aplică prin diferite număr de treceri greedy ale unei căutări locale:

  • Nivelul 0: 1 trecere
  • Nivelul 1: 2 treceri
  • Nivelul 2: 3 treceri

Modul numai-transpilare: Acum disponibil pentru utilizatorii care doresc să analizeze optimizarea Circuit-ului fără a rula execuția completă a algoritmului cuantic.

Exemplu de configurare personalizată: Iată cum ai putea configura Iskay cu setări diferite:

# Added by doQumentation — required packages for this notebook
!pip install -q PyGithub networkx qiskit-ibm-catalog
custom_options = {
"shots": 15_000, # Higher shot count for better statistics
"num_iterations": 12, # More iterations for solution refinement
"preprocessing_level": 1, # Light preprocessing for problem simplification
"postprocessing_level": 2, # Maximum postprocessing for solution quality
"transpilation_level": 3, # Using higher transpilation level for circuit optimization
"seed_transpiler": 42, # Fixed seed for reproducible results
"job_tags": ["custom_config"], # Custom tracking tags
}

Optimizarea seed-ului: Reține că seed_transpiler este setat la None în mod implicit. Aceasta permite procesului automat de optimizare al Transpiler-ului. Când este None, sistemul va iniția o încercare cu mai multe seed-uri și îl va selecta pe cel care produce cea mai bună adâncime a Circuit-ului, valorificând la maximum parametrul max_trials pentru fiecare nivel de transpilare.

Performanța nivelului de transpilare: Creșterea numărului de max_trials cu valori mai mari pentru transpilation_level va crește inevitabil timpul de transpilare, dar s-ar putea să nu modifice întotdeauna Circuit-ul final — aceasta depinde în mare măsură de structura și complexitatea specifice ale Circuit-ului. Cu toate acestea, pentru unele circuite/probleme, diferența dintre 10 încercări (nivelul 1) și 50 de încercări (nivelul 5) poate fi dramatică, astfel că explorarea acestor parametri ar putea fi cheia pentru a găsi cu succes o soluție.

Ieșire

NumeTipDescriereExemplu
resultDict[str, Any]Soluție și metadate. Structura variază în funcție de opțiunea transpile_only.Vezi „Conținutul dicționarului de rezultate" de mai jos

Conținutul dicționarului de rezultate

Structura dicționarului de rezultate depinde de modul de execuție:

CâmpTipModDescriereExemplu
solutionDict[str, int]StandardSoluția mapată și sortată, unde cheile sunt indicii variabilelor (ca șiruri de caractere) sortați numeric, iar valorile sunt valorile corespunzătoare ale variabilelor (1/-1 pentru problemele spin, 1/0 pentru problemele binare).{'0': -1, '1': -1, '2': -1, '3': 1, '4': 1}
solution_infoDict[str, Any]StandardInformații detaliate despre soluție (vezi detaliile de mai jos){'bitstring': '11100', 'cost': -13.8, 'seed_transpiler': 42, 'mapping': {0: 0, 1: 1, 2: 2, 3: 3, 4: 4}}
prob_typestrStandardTipul problemei de optimizare ('spin' sau 'binary')'spin'
transpilation_infoDict[str, Any]Numai-transpilareAnaliza Circuit-ului și detalii de transpilare (vezi detaliile de mai jos){'best_seed': 42, 'transpilation_time_seconds': 50.06, 'transpiled_circuit': {'depth': 576, 'gate_count': 4177, 'num_qubits': 156, 'width': 176, 'operations': {'sx': 1325, 'rx': 891, 'cz': 783, 'rz': 650, 'rzz': 466, 'x': 42, 'measure': 20}}}

Execuție standard

Când parametrul opțional transpile_only=False:

Dicționarul solution_info:

  • "bitstring" (str): Reprezentarea brută a soluției ca șir de biți.
  • "cost" (float): Valoarea costului/energiei asociate soluției.
  • "seed_transpiler" (int): Seed-ul aleatoriu folosit pentru Transpiler care a produs acest rezultat.
  • "mapping" (Dict[int, int]): Maparea originală Qubit-la-variabilă folosită în calcul.
  • "qpu_time" (float, opțional): Timpul de execuție QPU în secunde.

Note privind maparea variabilelor:

  • Dicționarul solution este obținut din șirul de biți al soluției, folosind obiectul mapping pentru indexarea variabilelor.
  • Când problem_type=spin, folosim atribuirea 11,011 \rightarrow -1, \quad 0 \rightarrow 1.
  • Cheile din dicționarul de soluții sunt indicii variabilelor sortați numeric ca șiruri de caractere.

Analiza transpilării

Când parametrul opțional transpile_only=True:

Dicționarul transpilation_info:

  • "best_seed" (int): Seed-ul optim găsit pentru transpilare
  • "transpilation_time_seconds" (float): Timpul necesar pentru procesul de transpilare
  • "transpiled_circuit" (Dict): Analiza Circuit-ului conținând:
    • "depth" (int): Adâncimea Circuit-ului (numărul de straturi)
    • "gate_count" (int): Numărul total de Gate-uri din Circuit
    • "num_qubits" (int): Numărul de Qubit-uri folosite
    • "width" (int): Lățimea Circuit-ului
    • "operations" (Dict[str, int]): Numărul fiecărui tip de Gate utilizat

Utilizarea modului numai-transpilare:

  • Disponibil pentru utilizatorii care doresc să analizeze optimizarea Circuit-ului fără a rula execuția completă a algoritmului cuantic.
  • Util pentru analiza Circuit-ului, studii de optimizare a adâncimii și înțelegerea efectelor transpilării înainte de a se angaja la execuția completă.

Începe

În această documentație, vom parcurge pașii pentru a utiliza Iskay Quantum Optimizer. În acest proces, vom arăta rapid cum să încarci funcția din catalog și cum să convertești problema ta într-un input valid, demonstrând totodată cum poți experimenta cu diferiți parametri opționali.

Pentru un exemplu mai detaliat, consultă tutorialul Rezolvă problema Market Split cu Iskay Quantum Optimizer de la Kipu Quantum, unde parcurgem întregul proces de utilizare a Iskay Solver pentru a aborda problema Market Split, care reprezintă o provocare reală de alocare a resurselor în care piețele trebuie împărțite în regiuni de vânzare echilibrate pentru a satisface ținte exacte de cerere.

Autentifică-te folosind cheia ta API, disponibilă pe panoul de bord IBM Quantum Platform, și selectează Qiskit Function după cum urmează:

# ruff: noqa: F821
notă

Codul următor presupune că ți-ai salvat acreditările. Dacă nu ai făcut acest lucru, urmează instrucțiunile din salvează contul tău IBM Cloud pentru a te autentifica cu cheia ta API.

from qiskit_ibm_catalog import QiskitFunctionsCatalog

catalog = QiskitFunctionsCatalog(
channel="ibm_quantum_platform",
instance="INSTANCE_CRN",
token="YOUR_API_KEY", # Use the 44-character API_KEY you created and saved from the IBM Quantum Platform Home dashboard
)

# Access Function
optimizer = catalog.load("kipu-quantum/iskay-quantum-optimizer")

Example 1: Funcție de cost simplă

Consideră funcția de cost în formulare spin:

C(x0,x1,x2,x3,x4)=1+1.5x0+2x1+1.3x2+2.5x0x3+3.5x1x4+4x0x1x2C(x_0, x_1, x_2, x_3, x_4) = 1 + 1.5x_0 + 2x_1 + 1.3x_2 + 2.5x_0x_3 + 3.5x_1x_4 + 4x_0x_1x_2

unde (x0,...,x4){1,1}5(x_0, ..., x_4) \in \{-1, 1\}^5.

Soluția acestei funcții de cost simple este

(x0,x1,x2,x3,x4)=(1,1,1,1,1)(x_0, x_1, x_2, x_3, x_4) = (-1, -1, -1, 1, 1)

cu valoarea minimă C=6C^{*} = -6

1. Creează funcția obiectiv

Începem prin a crea un dicționar cu coeficienții funcției obiectiv, după cum urmează:

objective_func = {
"()": 1,
"(0,)": 1.5,
"(1,)": 2,
"(2,)": 1.3,
"(0, 3)": 2.5,
"(1, 4)": 3.5,
"(0, 1, 2)": 4,
}

2. Rulează Optimizer-ul

Rezolvăm problema rulând Optimizer-ul. Deoarece (x0,...,x4){1,1}5(x_0, ..., x_4) \in \{-1, 1\}^5, trebuie să setăm problem_type=spin.

# Setup options to run the optimizer
options = {"shots": 5000, "num_iterations": 5, "use_session": True}

arguments = {
"problem": objective_func,
"problem_type": "spin",
"backend_name": backend_name, # such as "ibm_fez"
"options": options,
}

job = optimizer.run(**arguments)

3. Recuperează rezultatul

Soluția problemei de optimizare este furnizată direct de către Optimizer.

print(job.result())

Aceasta va afișa un dicționar de forma:

{'solution': {'0': -1, '1': -1, '2': -1, '3': 1, '4': 1},
'solution_info': {'bitstring': '11100',
'cost': -13.8,
'seed_transpiler': 42,
'mapping': {0: 0, 1: 1, 2: 2, 3: 3, 4: 4}},
'prob_type': 'spin'}

Observă că dicționarul solution afișează vectorul rezultat (x0,x1,x2,x3,x4)=(1,1,1,1,1)(x_0, x_1, x_2, x_3, x_4) = (-1, -1, -1, 1, 1).

Exemplul 2: MaxCut

Multe probleme de grafuri, precum MaxCut sau mulțimea independentă maximă, sunt probleme NP-dificile și candidați ideali pentru testarea algoritmilor și hardware-ului cuantic. Acest exemplu demonstrează rezolvarea problemei MaxCut pe un graf 3-regulat cu ajutorul Quantum Optimizer.

Pentru a rula acest exemplu, trebuie să instalezi pachetul networkx în plus față de qiskit-ibm-catalog. Pentru a-l instala, rulează următoarea comandă:

# %pip install networkx numpy

1. Creează funcția obiectiv

Începe prin generarea unui graf aleatoriu 3-regulat. Pentru acest graf, definim funcția obiectiv a problemei MaxCut.

import networkx as nx

# Create a random 3-regular graph
G = nx.random_regular_graph(3, 10, seed=42)

# Create the objective function for MaxCut in Ising formulation
def graph_to_ising_maxcut(G):
"""
Convert a NetworkX graph to an Ising Hamiltonian for the Max-Cut problem.
Args:
G (networkx.Graph): The input graph.
Returns:
dict: The objective function of the Ising model
"""
# Initialize the linear and quadratic coefficients
objective_func = {}
# Populate the coefficients
for i, j in G.edges:
objective_func[f"({i}, {j})"] = 0.5
return objective_func

objective_func = graph_to_ising_maxcut(G)

2. Rulează Optimizer-ul

Rezolvă problema rulând Optimizer-ul.

options = {"shots": 5000, "num_iterations": 5, "use_session": True}

arguments = {
"problem": objective_func,
"problem_type": "spin",
"backend_name": backend_name, # such as "ibm_fez"
"options": options,
}

job = optimizer.run(**arguments)

3. Obține rezultatul

Obține rezultatul și mapează șirul de biți al soluției înapoi la nodurile grafului original.

print(job.result())

Soluția problemei Maxcut este conținută direct în sub-dicționarul solution al obiectului rezultat

maxcut_solution = job.result()["solution"]

Exemplul 3: Instanțe de referință

Instanțele de referință sunt disponibile pe GitHub: Kipu benchmark instances.

Instanțele pot fi încărcate folosind biblioteca pygithub. Pentru a o instala, rulează următoarea comandă:

# %pip install pygithub

Căile pentru instanțele de referință sunt:

Maxcut:

  • 'maxcut/maxcut_28_nodes.json'
  • 'maxcut/maxcut_30_nodes.json'
  • 'maxcut/maxcut_32_nodes.json'
  • 'maxcut/maxcut_80_nodes.json'
  • 'maxcut/maxcut_100_nodes.json'
  • 'maxcut/maxcut_120_nodes.json'

HUBO:

  • 'HUBO/hubo1_marrakesh.json'
  • 'HUBO/hubo2_marrakesh.json'

Pentru a reproduce performanța de referință pentru instanțele HUBO, selectează Backend-ul ibm_marrakesh și setează direct_qubit_mapping la True în sub-dicționarul options. Următorul exemplu rulează instanța Maxcut cu 32 de noduri.

from github import Github
import urllib
import json
import ast

repo = "Kipu-Quantum-GmbH/benchmark-instances"
path = "maxcut/maxcut_32_nodes.json"
gh = Github()
repo = gh.get_repo(repo)
branch = "main"
file = repo.get_contents(urllib.parse.quote(path), ref=branch)

# load json file with benchmark problem
problem_json = json.loads(file.decoded_content)

# convert objective function to compatible format
objective_func = {
key: ast.literal_eval(value) for key, value in problem_json.items()
}

# Setup configuration to run the optimizer
options = {
"shots": 5_000,
"num_iterations": 5,
"use_session": True,
"direct_qubit_mapping": False,
}

arguments = {
"problem": objective_func,
"problem_type": "spin",
"backend_name": "ibm_brisbane",
"options": options,
}

job = optimizer.run(**arguments)

result = job.result()

Cazuri de utilizare

Cazurile de utilizare tipice pentru solverul de optimizare sunt problemele de optimizare combinatorie. Poți rezolva probleme din multe industrii, precum finanțe, farmacie sau logistică. Câteva exemple urmează.

Dacă ești interesat să abordezi un caz de utilizare specific și să dezvolți o mapare dedicată, te putem ajuta. Contactează-ne.

Obține suport

Pentru suport, contactează support@kipu-quantum.com.

Pași următori

Informații suplimentare

Iskay, la fel ca numele companiei noastre Kipu Quantum, este un cuvânt peruan. Deși suntem un startup din Germania, aceste cuvinte provin din țara natală a unuia dintre co-fondatorii noștri, unde Quipu a fost una dintre primele mașini de calcul dezvoltate de umanitate cu 2000 de ani î.Hr.