Aller au contenu principal
Ce projet est en phase bêta. Tu as trouvé un bug ? Ouvrir un ticket GitHub. Une question ou une idée ? Pose ta question dans Discussions — tes retours sont les bienvenus !
Quelle est la qualité de la traduction sur cette page ?

SQOA Solver - une Qiskit Function de JIJ

Consulte la référence de l'API.

remarque

Les Qiskit Functions sont une fonctionnalité expérimentale disponible uniquement pour les utilisateurs des offres IBM Quantum® Premium Plan, Flex Plan et On-Prem (via l'API d'IBM Quantum Platform). Elles sont en préversion et susceptibles de changer.

Vue d'ensemble​

Avec SQOA Solver de JIJ, tu peux résoudre de grands problèmes d'optimisation combinatoire sur les ordinateurs quantiques d'IBM®. Le solveur repose sur l'algorithme d'optimisation quantique par échantillonnage avec relaxation quantique (Sampling-based Quantum Optimization Algorithm with Quantum Relaxation, SQOA-QR) [1]. Contrairement aux algorithmes quantiques qui utilisent une correspondance biunivoque entre les variables de décision classiques et les qubits, SQOA Solver peut traiter des problèmes d'optimisation comportant plus de variables que le nombre de qubits disponibles sur les dispositifs quantiques actuels. Sa conception fondée sur l'échantillonnage le rend aussi moins sensible au bruit physique du matériel quantique actuel. Ensemble, ces caractéristiques rendent SQOA Solver bien adapté aux problèmes d'optimisation au stade actuel de l'informatique quantique.

Le solveur traite les problèmes d'optimisation binaire quadratique sans contrainte (Quadratic Unconstrained Binary Optimization, QUBO) donnés sous forme de formulation mathématique classique, et il convertit automatiquement cette formulation classique vers le cadre quantique. Tu peux aussi convertir des problèmes contraints en problèmes sans contrainte grâce à la méthode de pénalité.

Les sections suivantes décrivent le workflow du solveur, les résultats de benchmarks et des exemples de bout en bout qui modélisent des problèmes avec qiskit-addon-opt-mapper et, éventuellement, Open Mathematical prograMming eXchange (OMMX). OMMX est un format de données ouvert et un SDK qui simplifient l'échange de problèmes d'optimisation entre outils logiciels.

Description​

SQOA Solver implémente l'algorithme d'optimisation quantique par échantillonnage avec relaxation quantique (SQOA-QR) et l'entoure d'un prétraitement et d'un post-traitement classiques. Cette section explique le cadre SQOA et en quoi il diffère de l'algorithme d'optimisation approximative quantique (Quantum Approximate Optimization Algorithm, QAOA).

La figure suivante montre un schéma du workflow de SQOA Solver. Schéma du workflow de SQOA Solver, du prétraitement classique à l'échantillonnage SQOA, puis au post-traitement et à la recherche locale

Le cadre SQOA​

SQOA est un cadre fondé sur l'échantillonnage pour l'optimisation combinatoire [1]. Il combine deux techniques : l'optimisation par accès aléatoire quantique (Quantum Random Access Optimization, QRAO) [2], qui encode le problème dans une relaxation quantique, et la diagonalisation quantique par échantillonnage (sample-based quantum diagonalization, SQD) [3], aussi connue sous le nom d'interaction de configurations sélectionnées quantiquement (quantum-selected configuration interaction, QSCI) [4], qui utilise l'ordinateur quantique uniquement pour échantillonner des chaînes de bits et trouve l'état de basse énergie sur un ordinateur classique. SQOA est un cadre au sens où il fixe cette combinaison mais laisse les détails à chaque implémentation, comme la manière d'affecter les variables aux qubits et les circuits qui génèrent les échantillons.

  • Relaxation quantique avec QRAO. QAOA et les autres approches fondées sur le modèle d'Ising représentent chaque variable binaire par l'opérateur ZZ de son qubit. QRAO utilise aussi les opérateurs XX et YY. Avec un code d'accès aléatoire quantique (QRAC) (3,1), jusqu'à trois variables binaires partagent un même qubit, et chaque variable est représentée par un opérateur de Pauli différent.

    Le QUBO devient alors un hamiltonien relaxé qui nécessite moins de qubits que l'hamiltonien d'Ising. Les variables qui interagissent dans le QUBO doivent être placées sur des qubits différents. Si elles partageaient un qubit, le produit de leurs opérateurs de Pauli se réduirait à un seul opérateur sur ce qubit (par exemple, XY=iZXY = iZ), et l'hamiltonien relaxé ne représenterait plus leur interaction.

    L'affectation des variables aux qubits détermine donc à la fois le nombre de qubits et la qualité de la relaxation, et SQOA Solver conçoit cette affectation dans son prétraitement.

  • Diagonalisation quantique par échantillonnage (SQD). L'ordinateur quantique prépare d'abord un état quantique qui a un recouvrement avec les états de basse énergie de l'hamiltonien relaxé, puis en échantillonne des chaînes de bits. Un ordinateur classique projette l'hamiltonien relaxé sur le sous-espace engendré par les chaînes de bits échantillonnées et le diagonalise pour approximer l'état fondamental.

    Comme l'hamiltonien relaxé n'est pas diagonal, la diagonalisation combine les chaînes de bits échantillonnées en une superposition. Avec un hamiltonien d'Ising diagonal, chaque chaîne de bits est déjà un état propre, et la diagonalisation ne ferait que sélectionner le meilleur échantillon. La même approche a été appliquée à des problèmes à grande échelle en chimie quantique.

L'état fondamental approximatif obtenu par SQD ne correspond pas directement à une solution classique du problème d'origine, il faut donc en décoder la solution classique. Comme cet état est calculé sur un ordinateur classique, le décodage, appelé arrondi, est un post-traitement classique. SQOA Solver utilise des techniques de décodage conçues pour obtenir heuristiquement de meilleures solutions classiques.

Le tableau suivant compare SQOA à QAOA, une approche variationnelle courante pour la même classe de problèmes.

 QAOASQOA
Qubits pour nn variables binairesnnUn qubit contient jusqu'à trois des variables. Le nombre exact dépend de la structure du problème
Utilisation du QPUEstime de façon répétée l'énergie de circuits paramétrés dans une boucle d'optimisation classiqueÉchantillonne uniquement des chaînes de bits. Aucun paramètre de circuit n'est entraîné sur le QPU
Des échantillons à une solutionSélectionne la meilleure chaîne de bits mesuréeDiagonalise l'hamiltonien relaxé dans le sous-espace échantillonné sur un ordinateur classique et arrondit l'état obtenu

Autour de SQOA-QR, SQOA Solver ajoute un traitement classique. Son prétraitement fixe les variables dont les valeurs optimales peuvent être déterminées à l'avance et conçoit l'affectation des variables aux qubits. Son post-traitement affine la solution arrondie par une recherche locale, que tu peux désactiver avec postprocessing_level=0.

Benchmarks​

Avertissement

Les performances peuvent dépendre à la fois de l'instance du problème et des étapes de traitement ultérieures. Dans certains cas, des échantillons classiques et des échantillons générés quantiquement peuvent atteindre une qualité de solution finale similaire après un post-traitement équivalent. L'évaluation doit donc prendre en compte l'ensemble du workflow d'optimisation.

Les métriques de benchmark suivantes donnent une indication générale de la qualité des solutions, de la compression des qubits et du temps d'exécution pour une sélection de tailles et de structures de problèmes. Le tableau liste une sélection d'instances de Maximum Independent Set issues de la Quantum Optimization Benchmarking Library (QOBLIB) et deux instances MaxCut 3-régulières. Tu peux charger les instances QOBLIB sous forme d'objets ommx.v1.Instance, avec leurs solutions optimales, grâce au paquet ommx-quantum-benchmarks.

Chaque instance a été exécutée 10 fois sur un processeur IBM Heron r2. Number of qubits compte les qubits réellement utilisés sur le matériel après le prétraitement et l'encodage QRAC. Le taux de compression dépend de l'instance. Approximation ratio (AR) indique la qualité de la meilleure solution trouvée sur les 10 exécutions :

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

où CbestC_{\textrm{best}} est la meilleure valeur d'objectif trouvée et CoptC_{\textrm{opt}} est la valeur d'objectif optimale connue. Toutes les instances sont des problèmes de maximisation avec une valeur optimale positive, donc AR vaut au plus 100 %, et 100 % dans la colonne Approximation ratio indique que le solveur a trouvé une solution optimale. Total time est le temps moyen combiné de QPU et de CPU par exécution. QPU time est l'utilisation moyenne d'IBM Quantum Compute par exécution.

InstanceNombre de variablesNombre de qubitsTaux d'approximationTemps total (secondes)Temps QPU (secondes)
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

Pour commencer​

Trouve les informations d'accès à cette Qiskit Function dans le Qiskit Functions Catalog.

Cette section montre comment t'authentifier et charger la fonction, et comment préparer un problème au format dictionnaire accepté par SQOA Solver en utilisant OptimizationProblem de qiskit-addon-opt-mapper. Les exemples qui suivent exécutent la fonction et lisent le résultat.

S'authentifier et charger la fonction​

Commence par t'authentifier avec ta clé d'API IBM Quantum. (Le code suivant suppose que tu as déjà enregistré ton compte dans ton environnement local.) Ensuite, crée un client de catalogue comme suit :

# 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")

Préparer l'entrée avec qiskit-addon-opt-mapper​

Ce guide modélise les problèmes avec la classe OptimizationProblem de qiskit-addon-opt-mapper. SQOA Solver accepte un problème QUBO sous forme de dictionnaire de coefficients au format tuple-chaîne utilisé par les fonctions d'optimisation d'IBM, de sorte que chaque exemple de ce guide suit le même schéma de préparation côté client :

  1. Écrire le modèle. Crée un OptimizationProblem, ajoute des variables de décision binaires, puis définis l'objectif et les éventuelles contraintes.

  2. Convertir en QUBO. Convertis le problème avec OptimizationProblemToQubo, qui ajoute les éventuelles contraintes à l'objectif sous forme de termes de pénalité et renvoie un problème de minimisation sans contrainte équivalent.

  3. Convertir en dictionnaire. Passe le QUBO à la fonction utilitaire to_problem_dict() définie dans la section suivante, puis passe le résultat à solver.run() comme problem, avec variable_type="binary".

SQOA Solver minimise toujours un problème sous forme de dictionnaire, ce qui correspond au problème de minimisation que renvoie OptimizationProblemToQubo. Pour un problème de maximisation, la valeur objective_value renvoyée est donc l'opposé de l'objectif d'origine. Pour lire le résultat en termes du problème d'origine, évalue l'affectation renvoyée avec OptimizationProblem, comme le montrent les exemples. Pour les détails du format dictionnaire, consulte Accepted problem formats dans la référence de l'API.

# %pip install qiskit-addon-opt-mapper

Définis une seule fois la fonction utilitaire suivante et réutilise-la dans chaque exemple. Elle convertit le QUBO renvoyé par OptimizationProblemToQubo au format dictionnaire. Les clés utilisent les indices de variables du QUBO, donc les clés de solution x_0, x_1, etc. dans le résultat correspondent à ces indices. Chaque variable reçoit une entrée linéaire, même avec un coefficient nul, afin que la solution renvoyée couvre toutes les variables.

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()}

Exemple 1 : MaxCut sur un graphe 3-régulier​

De nombreux problèmes de graphes, comme MaxCut, sont NP-difficiles et sont des candidats naturels pour l'optimisation quantique. Installe networkx comme dépendance supplémentaire pour exécuter cet exemple :

# %pip install networkx

1. Écrire le modèle​

Associe une variable binaire xv∈{0,1}x_v \in \{0, 1\} à chaque sommet d'un graphe G=(V,E)G = (V, E) pour indiquer son côté de la coupe. Une arête est coupée lorsque ses extrémités sont de part et d'autre, donc la taille de la coupe est :

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).

Cet objectif est déjà un QUBO sans contrainte, donc OptimizationProblemToQubo ne fait que transformer la maximisation en la minimisation équivalente et laisse les variables inchangées. La classe d'application Maxcut de qiskit_addon_opt_mapper.applications construit le même modèle avec 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. Exécuter le solveur​

Convertis le modèle en QUBO puis en dictionnaire, et soumets-le. problem et variable_type sont obligatoires. backend_name est facultatif. Lorsqu'il est omis ou vaut None, la fonction sélectionne le QPU opérationnel le moins occupé disponible pour ton instance.

Le dictionnaire options accepte shots, seed, session, postprocessing_level et job_tags. Pour les descriptions et les valeurs par défaut, consulte la référence de l'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. Récupérer le résultat​

job.result() renvoie un dictionnaire à quatre clés :

  • solution est l'affectation complète des variables, indexée par x_i, où i est l'indice de la variable (par exemple, x_3).

  • objective_value et feasible sont l'objectif et la faisabilité de cette affectation, évalués sur le dictionnaire soumis.

  • metadata contient solver_info et resource_usage.

Comme le QUBO est la forme de minimisation de MaxCut, objective_value est l'opposé de la taille de la coupe. Évalue l'affectation sur l'OptimizationProblem d'origine pour lire directement la taille de la coupe.

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. Vérifier l'utilisation des ressources​

result["metadata"]["resource_usage"] indique le temps passé dans chaque phase d'exécution. Les phases autres que RUNNING: EXECUTING_QPU indiquent CPU_TIME, le temps réel écoulé de la phase en secondes, lorsqu'il est disponible.

La phase RUNNING: EXECUTING_QPU indique QPU_TIME, l'utilisation du QPU de tous les jobs Quantum Compute de l'exécution, si l'utilisation finale est disponible pour chaque job. Pour plus de détails, consulte la référence de l'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

Exemple 2 : Convertir un problème contraint en QUBO​

SQOA Solver accepte les problèmes sans contrainte. Cet exemple montre comment convertir un problème contraint en QUBO avec OptimizationProblemToQubo et reporter le résultat sur les variables du problème d'origine.

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 ajoute les contraintes à l'objectif sous forme de termes de pénalité et convertit le problème en minimisation. Le poids de pénalité approprié dépend du problème.

Après l'exécution, interpret() reporte l'affectation du QUBO sur les variables du problème d'origine.

Évalue l'objectif et la faisabilité sur le problème d'origine. Pour un problème sous forme de dictionnaire, le champ feasible du résultat ne se rapporte qu'au domaine des variables, car le dictionnaire n'a aucune contrainte.

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.]

Exemple 3 : Soumettre une instance OMMX​

SQOA Solver accepte aussi une ommx.v1.Instance du SDK OMMX, qui conserve ensemble les noms de variables, les indices et les métadonnées de conversion avec le problème. Par rapport à un dictionnaire, une entrée OMMX présente les avantages suivants :

  • Le résultat contient aussi la ommx.v1.Solution canonique dans solver_info["ommx_solution"].

  • objective_value est évalué au sens de l'instance, donc l'objectif d'un problème de maximisation n'est pas inversé.

  • Pour une instance convertie sur place avec Instance.to_qubo(), feasible est évalué par rapport aux contraintes d'origine.

Cet exemple construit le modèle MaxCut de l'exemple 1 avec JijModeling, un outil de modélisation d'optimisation mathématique qui compile les modèles en instances OMMX. Installe JijModeling, qui installe aussi le paquet ommx :

# %pip install "jijmodeling~=2.8.0"

SQOA Solver échange les données OMMX sous forme de chaînes Base64 standard avec remplissage. Définis les fonctions utilitaires suivantes pour cette conversion :

  • to_problem_payload() sérialise une ommx.v1.Instance en la chaîne que tu passes comme problem.

  • to_ommx_solution() décode la ommx.v1.Solution canonique à partir du résultat.

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. Écrire le modèle avec JijModeling​

La formulation de spin habituelle de MaxCut sur un graphe G=(V,E)G = (V, E) associe sv∈{−1,+1}s_v \in \{-1, +1\} à chaque sommet. Une arête est coupée lorsque susv=−1s_u s_v = -1, donc la taille de la coupe est :

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

JijModeling ne fournit pas de variable de décision de spin native, et SQOA Solver accepte des variables binaires de QUBO. Déclare donc bv∈{0,1}b_v \in \{0, 1\} et définis l'expression à valeurs de spin sv=1−2bvs_v = 1 - 2b_v dans le modèle. Avec cette expression, l'objectif reste sous la forme de spin standard, et l'instance compilée reste un QUBO binaire.

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)

Si tu affiches maxcut_model dans un notebook, il montre la formulation suivante :

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. Compiler l'instance et exécuter le solveur​

Lie le graphe de l'exemple 1 pour compiler une ommx.v1.Instance, puis soumets-la avec variable_type="binary". Une instance OMMX est toujours soumise comme un problème binaire.

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. Récupérer le résultat​

Pour une entrée OMMX, objective_value est la taille de la coupe, et to_ommx_solution() décode la solution canonique afin que tu puisses lire l'affectation par nom de variable.

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]

Obtenir de l'aide​

Pour obtenir de l'aide, écris à info@j-ij.com.

Étapes suivantes​

Recommandations

Références​

[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