{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "f7d9993f",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Iskay Quantum Optimizer - Une fonction Qiskit par Kipu Quantum\"\n",
        "description: \"Résolvez efficacement vos problèmes d'optimisation grâce à l'optimiseur quantique Iskay de Kipu Quantum, disponible sur l' IBM Qiskit Functions Catalog\"\n",
        "---\n",
        "\n",
        "{/* cspell:ignore Kipu, DCQO, QUBO, HUBO, counterdiabatic, Iskay, bitflips, Cadavid, Chandarana */}\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "dde95705",
      "metadata": {},
      "source": [
        "<span id=\"iskay-quantum-optimizer---a-qiskit-function-by-kipu-quantum\" />\n",
        "\n",
        "# Iskay Quantum Optimizer - Une fonction Qiskit par Kipu Quantum\n",
        "\n",
        "*Consultez la [documentation de l'API](/docs/api/functions/kipu-optimization)*\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "61da1dd5",
      "metadata": {
        "tags": [
          "version-info"
        ]
      },
      "source": [
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c60ba821",
      "metadata": {},
      "source": [
        "<Admonition type=\"note\" title=\"Remarque\">\n",
        "  * Les fonctions Qiskit sont une fonctionnalité expérimentale disponible uniquement pour IBM Quantum® Premium Plan, Flex Plan, et On-Prem (via IBM Quantum Platform API). Elles sont en cours de publication et peuvent être modifiées.\n",
        "</Admonition>\n",
        "\n",
        "<span id=\"overview\" />\n",
        "\n",
        "## Aperçu\n",
        "\n",
        "Avec l'optimiseur quantique Iskay de Kipu Quantum, vous pouvez vous attaquer à des problèmes d'optimisation complexes en utilisant les ordinateurs quantiques IBM®. Ce solveur exploite [l'algorithme de pointe bf-DCQO](https://doi.org/10.48550/arXiv.2409.04477) de Kipu, nécessitant uniquement la fonction objective comme entrée pour fournir automatiquement des solutions aux problèmes. Il peut traiter des problèmes d'optimisation impliquant jusqu'à 156 qubits, ce qui permet d'utiliser tous les qubits des dispositifs quantiques IBM. L'Optimizer utilise une correspondance 1-to-1 entre les variables classiques et les qubits, ce qui vous permet d'aborder les problèmes d'optimisation avec jusqu'à 156 variables binaires.\n",
        "\n",
        "L'Optimizer permet de résoudre des problèmes d'optimisation binaire sans contrainte. Outre la formulation QUBO (Quadratic Unconstrained Binary Optimization) couramment utilisée, il prend également en charge les problèmes d'optimisation d'ordre supérieur (HUBO). Le solveur utilise un algorithme quantique non variationnel, effectuant la plupart des calculs sur des dispositifs quantiques.\n",
        "\n",
        "Les paragraphes suivants fournissent plus de détails sur l'algorithme utilisé et un bref guide sur l'utilisation de la fonction, ainsi que des résultats d'analyse comparative sur diverses instances de problèmes de tailles et de complexités différentes.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5f761442",
      "metadata": {},
      "source": [
        "<span id=\"description\" />\n",
        "\n",
        "## Description\n",
        "\n",
        "L'Optimizer est une implémentation prête à l'emploi d'algorithmes d'optimisation quantique de pointe. Il résout les problèmes d'optimisation en exécutant des circuits quantiques hautement compressés sur du matériel quantique. Cette compression est obtenue en introduisant des termes contrediabatiques dans l'évolution temporelle sous-jacente du système quantique. L'algorithme exécute plusieurs itérations du matériel pour obtenir les solutions finales et les combine avec le post-traitement. Ces étapes sont intégrées de manière transparente dans le flux de travail de l'Optimizer et sont exécutées automatiquement.\n",
        "\n",
        "<span id=\"how-does-the-quantum-optimizer-work\" />\n",
        "\n",
        "### Comment fonctionne l'optimiseur quantique?\n",
        "\n",
        "Cette section présente les principes fondamentaux de l'algorithme bf-DCQO mis en œuvre. Une introduction à l'algorithme est également disponible sur la [chaîne YouTube Qiskit YouTube](https://www.youtube.com/watch?v=33QmsXhIlpU\\&t=1223s).\n",
        "\n",
        "L'algorithme est basé sur l'évolution temporelle d'un système quantique qui est transformé au fil du temps, où la solution du problème est encodée dans l'état fondamental du système quantique à la fin de l'évolution. Selon le [théorème adiabatique](https://en.wikipedia.org/wiki/Adiabatic_theorem), cette évolution doit être lente pour que le système reste dans son état fondamental. La numérisation de cette évolution est à la base du calcul quantique adiabatique numérisé (CQA) et du tristement célèbre algorithme QAOA. Cependant, l'évolution lente requise n'est pas réalisable pour des problèmes de taille croissante, car elle entraîne une augmentation de la profondeur du circuit. En utilisant des protocoles contrediabatiques, vous pouvez supprimer les excitations indésirables survenant pendant des temps d'évolution courts tout en restant dans l'état fondamental. Ici, la numérisation de ce temps d'évolution plus court permet d'obtenir des circuits quantiques avec une profondeur plus courte et moins de portes d'enchevêtrement.\n",
        "\n",
        "Les circuits des algorithmes bf-DCQO utilisent généralement jusqu'à dix fois moins de portes d'enchevêtrement que l'AQD, et trois à quatre fois moins de portes d'enchevêtrement que les implémentations standard de l'AQAO. En raison du nombre réduit de portes, moins d'erreurs se produisent lors de l'exécution du circuit sur le matériel. L'optimiseur n'a donc pas besoin d'utiliser des techniques telles que la suppression ou l'atténuation des erreurs. Leur mise en œuvre dans les versions futures peut encore améliorer la qualité de la solution.\n",
        "\n",
        "Bien que l'algorithme bf-DCQO utilise des itérations, il n'est pas variationnel. Après chaque itération de l'algorithme, la distribution des états est mesurée. La distribution obtenue est utilisée pour calculer ce que l'on appelle le champ de polarisation. Le champ de biais permet de démarrer l'itération suivante à partir d'un état d'énergie proche de la solution trouvée précédemment. De cette manière, l'algorithme se déplace à chaque itération vers des solutions de moindre énergie. Typiquement, une dizaine d'itérations suffisent pour converger vers une solution, ce qui nécessite au total un nombre d'itérations bien inférieur à celui des algorithmes variationnels, qui est de l'ordre d'une centaine d'itérations.\n",
        "\n",
        "L'optimiseur combine l'algorithme bf-DCQO avec un post-traitement classique. Après avoir mesuré la distribution des états, une recherche locale est effectuée. Pendant la recherche locale, les bits de la solution mesurée sont inversés de manière aléatoire. Après le retournement, l'énergie de la nouvelle chaîne de bits est évaluée. Si l'énergie est inférieure, la chaîne de bits est conservée comme nouvelle solution. La recherche locale n'évolue que linéairement avec le nombre de qubits; elle est donc peu coûteuse sur le plan informatique. Étant donné que le post-traitement corrige les inversions locales de bits, il compense les erreurs d'inversions de bits qui résultent souvent d'imperfections matérielles et d'erreurs de lecture.\n",
        "\n",
        "<span id=\"workflow\" />\n",
        "\n",
        "### Flux de travaux\n",
        "\n",
        "Voici un schéma du déroulement des opérations de l'Optimiseur quantique.\n",
        "\n",
        "![Flux de travail](https://quantum.cloud.ibm.com/docs/images/guides/kipu-optimization/workflow.svg \"Flux de travail de l'optimiseur quantique\")\n",
        "\n",
        "En utilisant l'Optimiseur quantique, la résolution d'un problème d'optimisation sur du matériel quantique peut être réduite à\n",
        "\n",
        "* Formuler la fonction objective du problème\n",
        "* Accéder à l'Optimizer via les fonctions Qiskit\n",
        "* Exécuter l'Optimizer et collecter les résultats\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b34fe075",
      "metadata": {},
      "source": [
        "<span id=\"benchmarks\" />\n",
        "\n",
        "## Tests de performances\n",
        "\n",
        "Les mesures de référence ci-dessous montrent que l'optimiseur traite efficacement des problèmes impliquant jusqu'à 156 qubits et offrent un aperçu général de la précision et de l'évolutivité de l'optimiseur pour différents types de problèmes. Notez que les mesures de performance réelles peuvent varier en fonction des caractéristiques spécifiques du problème, telles que le nombre de variables, la densité et la localité des termes de la fonction objective, et l'ordre polynomial.\n",
        "\n",
        "Le tableau suivant inclut le ratio d'approximation (RA), une mesure définie comme suit :\n",
        "\n",
        "$$\n",
        "AR = \\frac{C^{*} - C_\\textrm{max}}{C_{\\textrm{min}} - C_{\\textrm{max}}},\n",
        "$$\n",
        "\n",
        "où $C$ est la fonction objective, $C_{\\textrm{min}}$, $C_{\\textrm{max}}$ sont ses valeurs minimale et maximale, et $C^{*}$ est le coût de la meilleure solution trouvée, respectivement. Par conséquent, AR=100% signifie que l'état fondamental du problème a été obtenu.\n",
        "\n",
        "| Exemple            | Nombre de qubits | Rapport d'approximation | Durée totale (s) | Utilisation du temps d'exécution (s) | Nombre total de tirs | Nombre d'itérations |\n",
        "| ------------------ | :--------------: | :---------------------: | :--------------: | :----------------------------------: | :------------------: | :-----------------: |\n",
        "| Non pondéré MaxCut |        28        |          100 %          |        180       |                  30                  |          30k         |          5          |\n",
        "| Non pondéré MaxCut |        30        |          100 %          |        180       |                  30                  |          30k         |          5          |\n",
        "| Non pondéré MaxCut |        32        |          100 %          |        180       |                  30                  |          30k         |          5          |\n",
        "| Non pondéré MaxCut |        80        |          100 %          |        480       |                  60                  |          90k         |          9          |\n",
        "| Non pondéré MaxCut |        100       |          100 %          |        330       |                  60                  |          60k         |          6          |\n",
        "| Non pondéré MaxCut |        130       |          100 %          |        370       |                  60                  |          60k         |          6          |\n",
        "| HUBO 1             |        156       |          100 %          |        600       |                  70                  |         100k         |          10         |\n",
        "| HUBO 2             |        156       |          100 %          |        600       |                  70                  |         100k         |          10         |\n",
        "\n",
        "* Les instances MaxCut avec 28, 30 et 32 qubits ont été exécutées sur ibm\\_sherbrooke. Les instances de 80, 100 et 120 ont été exécutées sur un processeur Heron r2.\n",
        "* Les instances HUBO ont également été exécutées sur un processeur Heron r2.\n",
        "\n",
        "Toutes les instances de référence sont accessibles sur GitHub (voir [instances de référence Kipu](https://github.com/Kipu-Quantum-GmbH/benchmark-instances) ). Un exemple d'exécution de ces instances est présenté dans l' [exemple 3 : Instances de référence.](#example-3-benchmark-instances)\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "73390a19",
      "metadata": {},
      "source": [
        "<span id=\"get-started\" />\n",
        "\n",
        "## Premiers pas\n",
        "\n",
        "Dans cette documentation, nous allons passer en revue les étapes d'utilisation de l'optimiseur quantique Iskay. Au cours de ce processus, nous vous montrerons rapidement comment charger la fonction à partir du catalogue et comment convertir votre problème en une entrée valide, tout en vous montrant comment vous pouvez tester différents paramètres optionnels.\n",
        "\n",
        "Pour un exemple plus détaillé, veuillez consulter le tutoriel « [Résoudre le problème de la segmentation du marché avec l'optimiseur Iskay Quantum de Kipu Quantum](/docs/tutorials/solve-market-split-problem-with-iskay-quantum-optimizer) », dans lequel nous parcourons l'ensemble du processus d'utilisation du solveur Iskay pour résoudre le problème de la segmentation du marché, qui représente un défi réel en matière d'allocation des ressources, où les marchés doivent être divisés en zones de vente équilibrées afin de répondre à des objectifs de demande précis.\n",
        "\n",
        "Authentifiez-vous à l'aide de votre clé API, que vous trouverez sur le [tableau de bord de la plate-forme Quantum IBM](http://quantum.cloud.ibm.com/), et sélectionnez la fonction Qiskit comme suit :\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e5cd4ac8",
      "metadata": {},
      "source": [
        "<Admonition type=\"note\">\n",
        "  Le code suivant part du principe que vous avez enregistré vos identifiants. Si ce n'est pas le cas, suivez les instructions de la section [« Sauvegarder votre compte IBM Cloud »](/docs/guides/functions-get-started#install-qiskit-functions-catalog-client) pour vous authentifier à l'aide de votre clé API.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "68d3ecea-f7e3-4b4b-b299-1670abc72415",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "[QiskitFunction(qunova/hivqe-chemistry),\n",
              " QiskitFunction(global-data-quantum/quantum-portfolio-optimizer),\n",
              " QiskitFunction(algorithmiq/tem),\n",
              " QiskitFunction(qedma/qesem),\n",
              " QiskitFunction(multiverse/singularity),\n",
              " QiskitFunction(ibm/circuit-function),\n",
              " QiskitFunction(q-ctrl/optimization-solver),\n",
              " QiskitFunction(colibritd/quick-pde),\n",
              " QiskitFunction(q-ctrl/performance-management),\n",
              " QiskitFunction(kipu-quantum/iskay-quantum-optimizer)]"
            ]
          },
          "execution_count": 3,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit_ibm_catalog import QiskitFunctionsCatalog\n",
        "\n",
        "catalog = QiskitFunctionsCatalog(\n",
        "    channel=\"ibm_quantum_platform\",\n",
        "    instance=\"INSTANCE_CRN\",\n",
        "    # For `token`, use the 44-character API_KEY you created\n",
        "    # and saved from the IBM Quantum Platform Home dashboard\n",
        "    token=\"YOUR_API_KEY\",\n",
        ")\n",
        "\n",
        "# verify that you have access to the function\n",
        "catalog.list()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "95a715d2",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Access Function\n",
        "optimizer = catalog.load(\"kipu-quantum/iskay-quantum-optimizer\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4a8e24f7",
      "metadata": {},
      "source": [
        "<span id=\"custom-configuration-example\" />\n",
        "\n",
        "## Exemple de configuration personnalisée\n",
        "\n",
        "Voici comment vous pouvez configurer Iskay avec différents paramètres :\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "712dbae3",
      "metadata": {},
      "outputs": [],
      "source": [
        "custom_options = {\n",
        "    \"shots\": 15_000,  # Higher shot count for better statistics\n",
        "    \"num_iterations\": 12,  # More iterations for solution refinement\n",
        "    \"preprocessing_level\": 1,  # Light preprocessing for problem simplification\n",
        "    \"postprocessing_level\": 2,  # Maximum postprocessing for solution quality\n",
        "    \"transpilation_level\": 3,  # Use higher transpilation level to optimize circuit\n",
        "    \"seed_transpiler\": 42,  # Fixed seed for reproducible results\n",
        "    \"job_tags\": [\"custom_config\"],  # Custom tracking tags\n",
        "}"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "50690350",
      "metadata": {},
      "source": [
        "**Optimisation des graines** : Notez que `seed_transpiler` est défini par défaut `None` sur. Cela permet le processus d'optimisation automatique du transcompilateur. Lorsque `None`, le système lancera un essai avec plusieurs graines et sélectionnera celle qui produit la meilleure profondeur de circuit, en exploitant toute la puissance du `max_trials` paramètre pour chaque niveau de transpilation.\n",
        "\n",
        "**Performances au niveau de la transpilation** : augmenter le nombre de `max_trials` avec des valeurs plus élevées pour `transpilation_level` augmentera inévitablement le temps de transpilation, mais cela ne modifiera pas nécessairement le circuit final. Cela dépend en grande partie de la structure et de la complexité spécifiques du circuit. Pour certains circuits/problèmes, cependant, la différence entre 10 essais (niveau 1) et 50 essais (niveau 5) peut être considérable, de sorte que l'exploration de ces paramètres pourrait être la clé pour trouver une solution.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d4ca2590",
      "metadata": {},
      "source": [
        "<span id=\"example-1-simple-cost-function\" />\n",
        "\n",
        "## Exemple 1 : Fonction de coût simple\n",
        "\n",
        "Considérons la fonction de coût dans la formulation de spin :\n",
        "\n",
        "$$\n",
        "C(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\n",
        "$$\n",
        "\n",
        "où $(x_0, ..., x_4) \\in \\{-1, 1\\}^5$.\n",
        "\n",
        "La solution à cette fonction de coût simple est la suivante\n",
        "\n",
        "$$\n",
        "(x_0, x_1, x_2, x_3, x_4) = (-1, -1, -1, 1, 1)\n",
        "$$\n",
        "\n",
        "avec une valeur minimale $C^{*} = -6$\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a98e8232",
      "metadata": {},
      "source": [
        "<span id=\"1-create-the-objective-function\" />\n",
        "\n",
        "### 1. Créer la fonction objectif\n",
        "\n",
        "Nous commençons par créer un dictionnaire avec les coefficients de la fonction objective comme suit :\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "3b4a58b1",
      "metadata": {},
      "outputs": [],
      "source": [
        "objective_func = {\n",
        "    \"()\": 1,\n",
        "    \"(0,)\": 1.5,\n",
        "    \"(1,)\": 2,\n",
        "    \"(2,)\": 1.3,\n",
        "    \"(0, 3)\": 2.5,\n",
        "    \"(1, 4)\": 3.5,\n",
        "    \"(0, 1, 2)\": 4,\n",
        "}"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ab63b08f",
      "metadata": {},
      "source": [
        "<span id=\"2-run-the-optimizer\" />\n",
        "\n",
        "### 2. Exécutez l'optimiseur\n",
        "\n",
        "Nous résolvons le problème en exécutant l'optimiseur. Puisque $(x_0, ..., x_4) \\in \\{-1, 1\\}^5$ nous devons mettre `problem_type=spin`.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "469ae361",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Setup options to run the optimizer\n",
        "options = {\"shots\": 5000, \"num_iterations\": 5, \"use_session\": True}\n",
        "\n",
        "arguments = {\n",
        "    \"problem\": objective_func,\n",
        "    \"problem_type\": \"spin\",\n",
        "    \"backend_name\": backend_name,  # such as \"ibm_fez\"\n",
        "    \"options\": options,\n",
        "}\n",
        "\n",
        "job = optimizer.run(**arguments)\n",
        "\n",
        "# Print the ID so you can use it later, if necessary\n",
        "print(job.job_id)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1e3a8542",
      "metadata": {},
      "source": [
        "<span id=\"3-retrieve-the-result\" />\n",
        "\n",
        "### 3. Récupérer le résultat\n",
        "\n",
        "La solution du problème d'optimisation est fournie directement par l'optimiseur.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "2f74d7e2",
      "metadata": {},
      "outputs": [],
      "source": [
        "print(job.result())"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c4d0a0f8",
      "metadata": {},
      "source": [
        "Un dictionnaire de la forme s'affiche :\n",
        "\n",
        "```\n",
        "{'solution': {'0': -1, '1': -1, '2': -1, '3': 1, '4': 1},\n",
        " 'solution_info': {'bitstring': '11100',\n",
        "  'cost': -13.8,\n",
        "  'seed_transpiler': 42,\n",
        "  'mapping': {0: 0, 1: 1, 2: 2, 3: 3, 4: 4}},\n",
        " 'prob_type': 'spin'}\n",
        "```\n",
        "\n",
        "Remarquez que le dictionnaire `solution` affiche le vecteur de résultat $(x_0, x_1, x_2, x_3, x_4) = (-1, -1, -1, 1, 1)$.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7eaa5cac",
      "metadata": {},
      "source": [
        "<span id=\"example-2-maxcut\" />\n",
        "\n",
        "## Exemple 2 : MaxCut\n",
        "\n",
        "De nombreux problèmes de graphes tels que MaxCut ou Maximum independent set sont des problèmes NP-hard et des candidats idéaux pour tester les algorithmes et le matériel quantiques. Cet exemple illustre la résolution du problème MaxCut d'un graphe 3-régulier à l'aide de Quantum Optimizer.\n",
        "\n",
        "Pour exécuter cet exemple, vous devez installer le paquet `networkx` en plus du paquet `qiskit-ibm-catalog`. Pour l'installer, exécutez la commande suivante :\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "9ea6d138",
      "metadata": {},
      "outputs": [],
      "source": [
        "# %pip install networkx numpy"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0c63487f",
      "metadata": {},
      "source": [
        "<span id=\"1-create-the-objective-function\" />\n",
        "\n",
        "### 1. Créer la fonction objectif\n",
        "\n",
        "Commencez par générer un graphe 3-régulier aléatoire. Pour ce graphique, nous définissons la fonction objective du problème MaxCut.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "d1d4017f",
      "metadata": {},
      "outputs": [],
      "source": [
        "import networkx as nx\n",
        "\n",
        "# Create a random 3-regular graph\n",
        "G = nx.random_regular_graph(3, 10, seed=42)\n",
        "\n",
        "\n",
        "# Create the objective function for MaxCut in Ising formulation\n",
        "def graph_to_ising_maxcut(G):\n",
        "    \"\"\"\n",
        "    Convert a NetworkX graph to an Ising Hamiltonian for the max-cut problem.\n",
        "    Args:\n",
        "        G (networkx.Graph): The input graph.\n",
        "    Returns:\n",
        "        dict: The objective function of the Ising model\n",
        "    \"\"\"\n",
        "    # Initialize the linear and quadratic coefficients\n",
        "    objective_func = {}\n",
        "    # Populate the coefficients\n",
        "    for i, j in G.edges:\n",
        "        objective_func[f\"({i}, {j})\"] = 0.5\n",
        "    return objective_func\n",
        "\n",
        "\n",
        "objective_func = graph_to_ising_maxcut(G)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3be09664",
      "metadata": {},
      "source": [
        "<span id=\"2-run-the-optimizer\" />\n",
        "\n",
        "### 2. Exécutez l'optimiseur\n",
        "\n",
        "Résoudre le problème en exécutant l'optimiseur.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "2499ab67",
      "metadata": {},
      "outputs": [],
      "source": [
        "options = {\"shots\": 5000, \"num_iterations\": 5, \"use_session\": True}\n",
        "\n",
        "arguments = {\n",
        "    \"problem\": objective_func,\n",
        "    \"problem_type\": \"spin\",\n",
        "    \"backend_name\": backend_name,  # such as \"ibm_fez\"\n",
        "    \"options\": options,\n",
        "}\n",
        "\n",
        "job = optimizer.run(**arguments)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3548f6dc",
      "metadata": {},
      "source": [
        "<span id=\"3-retrieve-the-result\" />\n",
        "\n",
        "### 3. Récupérer le résultat\n",
        "\n",
        "Récupérer le résultat et faire correspondre la chaîne de bits de la solution aux nœuds du graphe d'origine.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "169cbd6e",
      "metadata": {},
      "outputs": [],
      "source": [
        "print(job.result())"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7f22d66a",
      "metadata": {},
      "source": [
        "La solution au problème Maxcut est directement contenue dans le sous-dictionnaire `solution` de l'objet résultat\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "38309554",
      "metadata": {},
      "outputs": [],
      "source": [
        "maxcut_solution = job.result()[\"solution\"]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "19a664c4",
      "metadata": {},
      "source": [
        "<span id=\"example-3-benchmark-instances\" />\n",
        "\n",
        "## Exemple 3 : Instances de référence\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "98545ce3",
      "metadata": {},
      "source": [
        "Les instances de référence sont disponibles sur GitHub: [Instances de référence Kipu](https://github.com/Kipu-Quantum-GmbH/benchmark-instances).\n",
        "\n",
        "Les instances peuvent être chargées à l'aide de la bibliothèque `pygithub` . Pour l'installer, exécutez la commande suivante :\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "1d8777e4",
      "metadata": {},
      "outputs": [],
      "source": [
        "# %pip install pygithub"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e3a03447",
      "metadata": {},
      "source": [
        "Les chemins pour les instances de référence sont les suivants :\n",
        "\n",
        "**Maxcut :**\n",
        "\n",
        "* `'maxcut/maxcut_regular_3_100_nodes_weighted.json'`\n",
        "* `'maxcut/maxcut_regular_3_140_nodes_weighted.json'`\n",
        "* `'maxcut/maxcut_regular_3_150_nodes_weighted.json'`\n",
        "* `'maxcut/maxcut_regular_4_130_nodes_weighted.json'`\n",
        "\n",
        "**HUBO :**\n",
        "\n",
        "* `'HUBO/hubo1_marrakesh.json'`\n",
        "* `'HUBO/hubo2_marrakesh.json'`\n",
        "\n",
        "Pour reproduire les performances du benchmark pour les instances HUBO, sélectionnez le backend `ibm_marrakesh` et définissez `direct_qubit_mapping` comme `True` dans le sous-dictionnaire `options` .\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "adbed9be",
      "metadata": {},
      "source": [
        "L'exemple suivant exécute l'instance Maxcut avec 150 nœuds.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "da681a18",
      "metadata": {},
      "outputs": [],
      "source": [
        "from github import Github\n",
        "import urllib\n",
        "import json\n",
        "import ast\n",
        "\n",
        "repo = \"Kipu-Quantum-GmbH/benchmark-instances\"\n",
        "path = \"maxcut/maxcut_regular_3_150_nodes_weighted.json\"\n",
        "gh = Github()\n",
        "repo = gh.get_repo(repo)\n",
        "branch = \"main\"\n",
        "file = repo.get_contents(urllib.parse.quote(path), ref=branch)\n",
        "\n",
        "# load json file with benchmark problem\n",
        "problem_json = json.loads(file.decoded_content)\n",
        "\n",
        "# convert objective function to compatible format\n",
        "objective_func = {\n",
        "    key: ast.literal_eval(value) for key, value in problem_json.items()\n",
        "}\n",
        "\n",
        "\n",
        "# Setup configuration to run the optimizer\n",
        "options = {\n",
        "    \"shots\": 5_000,\n",
        "    \"num_iterations\": 5,\n",
        "    \"use_session\": True,\n",
        "    \"direct_qubit_mapping\": False,\n",
        "}\n",
        "\n",
        "arguments = {\n",
        "    \"problem\": objective_func,\n",
        "    \"problem_type\": \"spin\",\n",
        "    \"backend_name\": \"<BACKEND-NAME>\",\n",
        "    \"options\": options,\n",
        "}\n",
        "\n",
        "job = optimizer.run(**arguments)\n",
        "\n",
        "result = job.result()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "664476ff",
      "metadata": {},
      "source": [
        "<span id=\"use-cases\" />\n",
        "\n",
        "## Cas d'utilisation\n",
        "\n",
        "Les cas d'utilisation typiques du solveur d'optimisation sont les problèmes d'optimisation combinatoire. Vous pouvez résoudre des problèmes dans de nombreux secteurs tels que la finance, la pharmacie ou la logistique. En voici quelques exemples.\n",
        "\n",
        "* Optimisation de portefeuille (QUBO) : [publication scientifique](https://doi.org/10.1103/PhysRevApplied.22.054037) et [livre blanc](https://kipu-quantum.com/zope64/kipu_2024/content/e3915/e3916/e4187/White-Paper-2-Financial-modeling-on-quantum-computers-using-digitally-compressed-algorithms-1.pdf)\n",
        "* Pliage des protéines (HUBO) : [publication scientifique](https://doi.org/10.1103/PhysRevApplied.20.014024)\n",
        "* Ordonnancement logistique (QUBO) : [publication scientifique](https://doi.org/10.1103/PhysRevApplied.22.064068)\n",
        "* Optimisation du réseau : [webinaire](https://www.youtube.com/watch?v=w5SrCIK88No)\n",
        "* Division du marché (QUBO) : [tutoriel](/docs/tutorials/solve-market-split-problem-with-iskay-quantum-optimizer)\n",
        "\n",
        "Si vous souhaitez aborder un cas d'utilisation spécifique et développer un mappage dédié, nous pouvons vous aider. [Contactez-nous](https://share-eu1.hsforms.com/2Ff8cgWvTR9ukT_fPoaNhDw2dqpz5).\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e9ec2e67",
      "metadata": {},
      "source": [
        "<span id=\"get-support\" />\n",
        "\n",
        "## Obtenir de l'aide\n",
        "\n",
        "Pour obtenir de l'aide, contactez [support@kipu-quantum.com](mailto:support@kipu-quantum.com).\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5a6a25c8",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Etapes suivantes\n",
        "\n",
        "* [Demandez l'accès à Quantum Optimizer de Kipu Quantum](https://share-eu1.hsforms.com/2Ff8cgWvTR9ukT_fPoaNhDw2dqpz5).\n",
        "* Consultez [la documentation de l'API](/docs/api/functions/kipu-optimization) relative à cette fonction Qiskit.\n",
        "* Essayez le tutoriel [« Résoudre le problème de la division du marché » avec l'optimiseur Iskay Quantum de Kipu Quantum](/docs/tutorials/solve-market-split-problem-with-iskay-quantum-optimizer).\n",
        "* Critique [Romero, S. V., et al. (2025).  Algorithme quantique contre-diabatique numérisé à champ de biais pour l'optimisation binaire d'ordre supérieur. arXiv prépublication arXiv:2409.04477](https://arxiv.org/abs/2409.04477).\n",
        "* Critique [Cadavid, A. G., et al. (2024).  Optimisation quantique contre-diabatique numérisée dans un champ de polarisation. arXiv prépublication arXiv:2405.13898](https://arxiv.org/abs/2405.13898).\n",
        "* Critique [Chandarana, P., et al. (2025).  Avantage quantique en termes de temps d'exécution grâce à l'optimisation quantique numérique. arXiv prépublication arXiv:2505.08663](https://arxiv.org/abs/2505.08663).\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f73ef6c4",
      "metadata": {},
      "source": [
        "<span id=\"additional-information\" />\n",
        "\n",
        "## Renseignements supplémentaires\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "52b5221c",
      "metadata": {},
      "source": [
        "Iskay, comme le nom de notre entreprise Kipu Quantum, est un mot péruvien. Bien que nous soyons une startup allemande, ces mots viennent du pays natal de l'un de nos cofondateurs, où le Quipu était l'une des toutes premières machines à calculer développées par l'humanité 2000 ans avant notre ère.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}