SQOA Solver - eine Qiskit Function von JIJ
Siehe die API-Referenz.
Qiskit Functions sind eine experimentelle Funktion, die nur für Nutzer des IBM Quantum® Premium Plans, Flex Plans und On-Prem-Plans (über die IBM Quantum Platform API) verfügbar ist. Sie befinden sich im Preview-Status und können sich ändern.
Überblick
Mit SQOA Solver von JIJ kannst du große kombinatorische Optimierungsprobleme auf IBM® Quantencomputern lösen. Der Solver basiert auf dem Sampling-based Quantum Optimization Algorithm with Quantum Relaxation (SQOA-QR) [1]. Anders als Quantenalgorithmen, die eine Eins-zu-eins-Abbildung zwischen klassischen Entscheidungsvariablen und Qubits verwenden, kann SQOA Solver Optimierungsprobleme mit mehr Variablen behandeln, als auf aktuellen Quantengeräten Qubits zur Verfügung stehen. Sein samplingbasiertes Design macht ihn außerdem weniger empfindlich gegenüber dem physikalischen Rauschen aktueller Quantenhardware. Zusammen machen diese Eigenschaften SQOA Solver gut geeignet für Optimierungsprobleme in der heutigen Phase des Quantencomputings.
Der Solver behandelt Probleme der Quadratic Unconstrained Binary Optimization (QUBO), die als klassische mathematische Formulierung vorliegen, und bildet die klassische Formulierung automatisch auf das Quantenmodell ab. Du kannst auch Probleme mit Nebenbedingungen mithilfe der Penalty-Methode in Probleme ohne Nebenbedingungen umwandeln.
Die folgenden Abschnitte beschreiben den Workflow des Solvers, Benchmark-Ergebnisse und End-to-End-Beispiele, die Probleme mit qiskit-addon-opt-mapper und optional mit Open Mathematical prograMming eXchange (OMMX) modellieren. OMMX ist ein offenes Datenformat und SDK, das den Austausch von Optimierungsproblemen zwischen Softwarewerkzeugen vereinfacht.
Beschreibung
SQOA Solver implementiert den Sampling-based Quantum Optimization Algorithm with Quantum Relaxation (SQOA-QR) und umgibt ihn mit klassischer Vor- und Nachverarbeitung. Dieser Abschnitt erklärt das SQOA-Framework und wie es sich vom Quantum Approximate Optimization Algorithm (QAOA) unterscheidet.
Die folgende Abbildung zeigt eine schematische Darstellung des SQOA-Solver-Workflows.
Das SQOA-Framework
SQOA ist ein samplingbasiertes Framework für kombinatorische Optimierung [1]. Es kombiniert zwei Techniken: Quantum Random Access Optimization (QRAO) [2], das das Problem in einer Quantenrelaxation kodiert, und Sample-based Quantum Diagonalization (SQD) [3], auch bekannt als Quantum-selected Configuration Interaction (QSCI) [4], das den Quantencomputer nur zum Sampeln von Bitstrings verwendet und den Zustand niedrigster Energie auf einem klassischen Computer findet. SQOA ist insofern ein Framework, als es diese Kombination festlegt, die Details aber der jeweiligen Implementierung überlässt, etwa wie die Variablen den Qubits zugewiesen werden und welche Circuits die Samples erzeugen.
-
Quantenrelaxation mit QRAO. QAOA und andere Ising-basierte Ansätze stellen jede binäre Variable durch den Operator ihres Qubits dar. QRAO verwendet zusätzlich die Operatoren und . Mit einem (3,1)-Quantum Random Access Code (QRAC) teilen sich bis zu drei binäre Variablen ein Qubit, und jede Variable wird durch einen anderen Pauli-Operator dargestellt.
Das QUBO wird dadurch zu einem relaxierten Hamiltonian, der weniger Qubits benötigt als der Ising-Hamiltonian. Variablen, die im QUBO wechselwirken, müssen auf verschiedenen Qubits liegen. Würden sie sich ein Qubit teilen, würde sich das Produkt ihrer Pauli-Operatoren auf einen einzelnen Operator auf diesem Qubit reduzieren (zum Beispiel ), und der relaxierte Hamiltonian würde ihre Wechselwirkung nicht mehr abbilden.
Die Zuweisung der Variablen zu Qubits bestimmt daher sowohl die Anzahl der Qubits als auch die Qualität der Relaxation, und SQOA Solver entwirft diese Zuweisung in seiner Vorverarbeitung.
-
Sample-based Quantum Diagonalization (SQD). Der Quantencomputer bereitet zunächst einen Quantenzustand vor, der mit Zuständen niedriger Energie des relaxierten Hamiltonians überlappt, und sampelt daraus Bitstrings. Ein klassischer Computer projiziert den relaxierten Hamiltonian auf den von den gesampelten Bitstrings aufgespannten Unterraum und diagonalisiert ihn, um den Grundzustand zu approximieren.
Da der relaxierte Hamiltonian nicht diagonal ist, kombiniert die Diagonalisierung die gesampelten Bitstrings zu einer Superposition. Bei einem diagonalen Ising-Hamiltonian ist jeder Bitstring bereits ein Eigenzustand, und die Diagonalisierung würde nur das beste Sample auswählen. Derselbe Ansatz wurde auf große Probleme in der Quantenchemie angewendet.
Der durch SQD erhaltene approximative Grundzustand entspricht nicht direkt einer klassischen Lösung des ursprünglichen Problems, daher muss die klassische Lösung daraus dekodiert werden. Da dieser Zustand auf einem klassischen Computer berechnet wird, ist die Dekodierung, genannt Rounding, eine klassische Nachverarbeitung. SQOA Solver verwendet Dekodierungstechniken, die heuristisch bessere klassische Lösungen liefern sollen.
Die folgende Tabelle vergleicht SQOA mit QAOA, einem verbreiteten variationalen Ansatz für dieselbe Problemklasse.
| QAOA | SQOA | |
|---|---|---|
| Qubits für binäre Variablen | Ein Qubit hält bis zu drei der Variablen. Die genaue Anzahl hängt von der Problemstruktur ab | |
| Nutzung der QPU | Schätzt wiederholt die Energie parametrisierter Circuits innerhalb einer klassischen Optimierungsschleife | Sampelt nur Bitstrings. Auf der QPU werden keine Circuit-Parameter trainiert |
| Von den Samples zur Lösung | Wählt den besten gemessenen Bitstring aus | Diagonalisiert den relaxierten Hamiltonian im gesampelten Unterraum auf einem klassischen Computer und rundet den resultierenden Zustand |
Um SQOA-QR herum ergänzt SQOA Solver klassische Verarbeitung. Die Vorverarbeitung fixiert Variablen, deren optimale Werte sich vorab bestimmen lassen, und entwirft die Zuweisung der Variablen zu Qubits. Die Nachverarbeitung verfeinert die gerundete Lösung mit einer lokalen Suche, die du mit postprocessing_level=0 ausschalten kannst.
Benchmarks
Die Leistung kann sowohl von der Probleminstanz als auch von den nachfolgenden Verarbeitungsschritten abhängen. In manchen Fällen können klassische Samples und quantengenerierte Samples nach gleichwertiger Nachverarbeitung eine ähnliche endgültige Lösungsqualität erreichen. Die Bewertung sollte daher den gesamten Optimierungs-Workflow berücksichtigen.
Die folgenden Benchmark-Metriken geben einen allgemeinen Hinweis auf Lösungsqualität, Qubit-Kompression und Ausführungszeit für ausgewählte Problemgrößen und -strukturen. Die Tabelle listet eine Auswahl von Maximum-Independent-Set-Instanzen aus der Quantum Optimization Benchmarking Library (QOBLIB) sowie zwei 3-reguläre MaxCut-Instanzen auf. Du kannst die QOBLIB-Instanzen zusammen mit ihren optimalen Lösungen mithilfe des Pakets ommx-quantum-benchmarks als ommx.v1.Instance-Objekte laden.
Jede Instanz wurde 10-mal auf einem IBM Heron r2-Prozessor ausgeführt. Number of qubits zählt die tatsächlich auf der Hardware verwendeten Qubits nach der Vorverarbeitung und der QRAC-Kodierung. Das Kompressionsverhältnis hängt von der Instanz ab. Approximation ratio (AR) gibt die Qualität der besten über die 10 Läufe gefundenen Lösung an:
wobei der beste gefundene Zielfunktionswert und der bekannte optimale Zielfunktionswert ist. Alle Instanzen sind Maximierungsprobleme mit positivem optimalem Wert, daher ist AR höchstens 100 %, und 100 % in der Spalte Approximation ratio bedeutet, dass der Solver eine optimale Lösung gefunden hat. Total time ist die durchschnittliche kombinierte QPU- und CPU-Zeit pro Lauf. QPU time ist die durchschnittliche IBM Quantum Compute-Nutzung pro Lauf.
| Instanz | Anzahl der Variablen | Anzahl der Qubits | Approximationsverhältnis | Gesamtzeit (Sekunden) | QPU-Zeit (Sekunden) |
|---|---|---|---|---|---|
| maxcut_384_nodes | 384 | 129 | 98.5% | 62.1 | 12.0 |
| gen200_p0-9_44 | 200 | 67 | 100% | 38.0 | 12.0 |
| es60fst02 | 186 | 42 | 100% | 24.7 | 12.0 |
| es60fst04 | 162 | 29 | 100% | 17.9 | 12.0 |
| maxcut_150_nodes | 150 | 51 | 100% | 23.1 | 12.0 |
| sloane_1dc_128 | 128 | 37 | 93.8% | 19.1 | 12.0 |
| sloane_2dc_128 | 128 | 8 | 100% | 12.3 | 11.5 |
| C125-9 | 125 | 43 | 100% | 22.3 | 12.0 |
| es60fst01 | 123 | 12 | 100% | 13.6 | 12.0 |
| es60fst03 | 113 | 26 | 100% | 14.9 | 12.0 |
| sloane_1dc_64 | 64 | 16 | 100% | 13.4 | 11.9 |
| chesapeake | 39 | 13 | 100% | 13.1 | 12.0 |
| football | 35 | 6 | 100% | 12.5 | 12.0 |
| karate | 34 | 2 | 100% | 6.2 | 6.0 |
| ibm32 | 32 | 11 | 100% | 12.9 | 12.0 |
| farm | 17 | 4 | 100% | 8.5 | 8.0 |
Erste Schritte
Zugangsinformationen für diese Qiskit Function findest du im Qiskit Functions Catalog.
Dieser Abschnitt zeigt, wie du dich authentifizierst und die Function lädst und wie du ein Problem in dem Dictionary-Format vorbereitest, das SQOA Solver akzeptiert, indem du OptimizationProblem aus qiskit-addon-opt-mapper verwendest. Die folgenden Beispiele führen die Function aus und lesen das Ergebnis aus.
Authentifizieren und die Function laden
Authentifiziere dich zunächst mit deinem IBM Quantum API-Schlüssel. (Der folgende Code setzt voraus, dass du dein Konto bereits in deiner lokalen Umgebung gespeichert hast.) Erstelle dann wie folgt einen Catalog-Client:
# 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")
Die Eingabe mit qiskit-addon-opt-mapper vorbereiten
Dieser Leitfaden modelliert Probleme mit der Klasse OptimizationProblem aus qiskit-addon-opt-mapper. SQOA Solver akzeptiert ein QUBO-Problem als Koeffizienten-Dictionary im Tupel-String-Format, das von den IBM-Optimierungsfunktionen verwendet wird, daher folgt jedes Beispiel in diesem Leitfaden demselben clientseitigen Vorbereitungsmuster:
-
Das Modell schreiben. Erstelle ein
OptimizationProblem, füge binäre Entscheidungsvariablen hinzu und lege die Zielfunktion sowie eventuelle Nebenbedingungen fest. -
In QUBO umwandeln. Wandle das Problem mit
OptimizationProblemToQuboum, das Nebenbedingungen als Penalty-Terme zur Zielfunktion hinzufügt und ein äquivalentes Minimierungsproblem ohne Nebenbedingungen zurückgibt. -
In ein Dictionary umwandeln. Übergib das QUBO an die im nächsten Abschnitt definierte Hilfsfunktion
to_problem_dict()und übergib das Ergebnis zusammen mitvariable_type="binary"alsproblemansolver.run().
SQOA Solver minimiert ein Dictionary-Problem immer, was dem Minimierungsproblem entspricht, das OptimizationProblemToQubo zurückgibt. Bei einem Maximierungsproblem ist der zurückgegebene objective_value daher das Negative der ursprünglichen Zielfunktion. Um das Ergebnis im Sinne des ursprünglichen Problems zu lesen, werte die zurückgegebene Zuweisung mit OptimizationProblem aus, wie es die Beispiele zeigen. Details zum Dictionary-Format findest du unter Akzeptierte Problemformate in der API-Referenz.
# %pip install qiskit-addon-opt-mapper
Definiere die folgende Hilfsfunktion einmal und verwende sie in jedem Beispiel wieder. Sie wandelt das von OptimizationProblemToQubo zurückgegebene QUBO in das Dictionary-Format um. Die Schlüssel verwenden die Variablenindizes des QUBO, daher entsprechen die Lösungsschlüssel x_0, x_1 und so weiter im Ergebnis diesen Indizes. Jede Variable erhält einen linearen Eintrag, auch mit Koeffizient null, damit die zurückgegebene Lösung alle Variablen abdeckt.
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()}
Beispiel 1: MaxCut auf einem 3-regulären Graphen
Viele Graphenprobleme, etwa MaxCut, sind NP-schwer und natürliche Kandidaten für Quantenoptimierung. Installiere networkx als zusätzliche Abhängigkeit, um dieses Beispiel auszuführen:
# %pip install networkx
1. Das Modell schreiben
Weise jedem Knoten eines Graphen eine binäre Variable zu, die seine Seite des Schnitts angibt. Eine Kante wird geschnitten, wenn ihre Endpunkte auf verschiedenen Seiten liegen, daher ist die Schnittgröße:
Diese Zielfunktion ist bereits ein QUBO ohne Nebenbedingungen, daher macht OptimizationProblemToQubo lediglich aus der Maximierung die äquivalente Minimierung und lässt die Variablen unverändert. Die Anwendungsklasse Maxcut in qiskit_addon_opt_mapper.applications baut dasselbe Modell mit 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. Den Solver ausführen
Wandle das Modell in ein QUBO und dann in ein Dictionary um und sende es ab. problem und variable_type sind erforderlich. backend_name ist optional. Wird er weggelassen oder ist er None, wählt die Function die am wenigsten ausgelastete betriebsbereite QPU, die deiner Instanz zur Verfügung steht.
Das Dictionary options akzeptiert shots, seed, session, postprocessing_level und job_tags. Beschreibungen und Standardwerte findest du in der API-Referenz.
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. Das Ergebnis abrufen
job.result() gibt ein Dictionary mit vier Schlüsseln zurück:
-
solutionist die vollständige Variablenzuweisung, mitx_ials Schlüssel, wobeiider Variablenindex ist (zum Beispielx_3). -
objective_valueundfeasiblesind die Zielfunktion und die Zulässigkeit dieser Zuweisung, ausgewertet auf dem abgesendeten Dictionary. -
metadataenthältsolver_infoundresource_usage.
Da das QUBO die Minimierungsform von MaxCut ist, ist objective_value das Negative der Schnittgröße. Werte die Zuweisung auf dem ursprünglichen OptimizationProblem aus, um die Schnittgröße direkt abzulesen.
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. Die Ressourcennutzung prüfen
result["metadata"]["resource_usage"] gibt die in jeder Ausführungsphase verbrachte Zeit an. Andere Phasen als RUNNING: EXECUTING_QPU melden CPU_TIME, die Wanduhrzeit der Phase in Sekunden, sofern verfügbar.
Die Phase RUNNING: EXECUTING_QPU meldet QPU_TIME, die QPU-Nutzung aller Quantum Compute-Jobs des Laufs, sofern die endgültige Nutzung für jeden Job verfügbar ist. Details findest du in der API-Referenz.
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
Beispiel 2: Ein Problem mit Nebenbedingungen in QUBO umwandeln
SQOA Solver akzeptiert Probleme ohne Nebenbedingungen. Dieses Beispiel zeigt, wie du ein Problem mit Nebenbedingungen mit OptimizationProblemToQubo in ein QUBO umwandelst und das Ergebnis auf die Variablen des ursprünglichen Problems zurückabbildest.
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 fügt die Nebenbedingungen als Penalty-Terme zur Zielfunktion hinzu und wandelt das Problem in eine Minimierung um. Das passende Penalty-Gewicht hängt vom Problem ab.
Nach dem Lauf bildet interpret() die QUBO-Zuweisung auf die Variablen des ursprünglichen Problems zurück ab.
Werte die Zielfunktion und die Zulässigkeit auf dem ursprünglichen Problem aus. Bei einem Dictionary-Problem bezieht sich das Feld feasible des Ergebnisses nur auf den Wertebereich der Variablen, da das Dictionary keine Nebenbedingungen enthält.
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.]
Beispiel 3: Eine OMMX-Instanz absenden
SQOA Solver akzeptiert auch eine ommx.v1.Instance aus dem OMMX-SDK, die Variablennamen, Indizes und Konvertierungsmetadaten zusammen mit dem Problem aufbewahrt. Im Vergleich zu einem Dictionary hat eine OMMX-Eingabe die folgenden Vorteile:
-
Das Ergebnis enthält außerdem die kanonische
ommx.v1.Solutioninsolver_info["ommx_solution"]. -
objective_valuewird im Sinne der Instanz ausgewertet, daher wird die Zielfunktion eines Maximierungsproblems nicht negiert. -
Bei einer Instanz, die mit
Instance.to_qubo()direkt umgewandelt wurde, wirdfeasiblegegen die ursprünglichen Nebenbedingungen ausgewertet.
Dieses Beispiel baut das MaxCut-Modell aus Beispiel 1 mit JijModeling, einem Modellierer für mathematische Optimierung, der Modelle zu OMMX-Instanzen kompiliert. Installiere JijModeling, wodurch auch das Paket ommx installiert wird:
# %pip install "jijmodeling~=2.8.0"
SQOA Solver tauscht OMMX-Daten als standardmäßige Base64-Strings mit Padding aus. Definiere die folgenden Hilfsfunktionen für diese Konvertierung:
-
to_problem_payload()serialisiert eineommx.v1.Instancein den String, den du alsproblemübergibst. -
to_ommx_solution()dekodiert die kanonischeommx.v1.Solutionaus dem Ergebnis.
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. Das Modell mit JijModeling schreiben
Die übliche Spin-Formulierung von MaxCut auf einem Graphen weist jedem Knoten zu. Eine Kante wird geschnitten, wenn gilt, daher ist die Schnittgröße:
JijModeling bietet keine native Spin-Entscheidungsvariable, und SQOA Solver akzeptiert binäre QUBO- Variablen. Deklariere daher und definiere den spinwertigen Ausdruck innerhalb des Modells. Mit diesem Ausdruck bleibt die Zielfunktion in der Standard-Spin-Form, und die kompilierte Instanz bleibt ein binäres QUBO.
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)
Wenn du maxcut_model in einem Notebook anzeigst, zeigt es die folgende Formulierung:
2. Die Instanz kompilieren und den Solver ausführen
Binde den Graphen aus Beispiel 1, um eine ommx.v1.Instance zu kompilieren, und sende sie mit variable_type="binary" ab. Eine OMMX-Instanz wird immer als binäres Problem abgesendet.
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. Das Ergebnis abrufen
Bei einer OMMX-Eingabe ist objective_value die Schnittgröße, und to_ommx_solution() dekodiert die kanonische Lösung, sodass du die Zuweisung nach Variablennamen lesen kannst.
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]
Support erhalten
Für Support schreibe eine E-Mail an info@j-ij.com.
Nächste Schritte
- Fordere über dieses Formular eine kostenlose Testversion von SQOA Solver an.
- Besuche die API-Referenz für diese Qiskit Function.
- Probiere ein End-to-End-Beispiel im Tutorial zum Maximum-Independent-Set-Problem aus.
- Lerne, wie du Optimierungsprobleme mit qiskit-addon-opt-mapper modellierst.
- Lerne, wie du Optimierungsprobleme mit JijModeling und OMMX modellierst und austauschst.
- Lies die SQOA-QR-Veröffentlichung [1], um mehr über das SQOA-Framework zu erfahren.
Referenzen
[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