{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "f7d9993f",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Iskay Quantum Optimizer - una función Qiskit de Kipu Quantum\"\n",
        "description: \"Resuelva de manera eficiente los problemas de optimización con el optimizador cuántico Iskay de Kipu Quantum, disponible en 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 - una función Qiskit de Kipu Quantum\n",
        "\n",
        "*Consulte la [referencia de la 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=\"Nota\">\n",
        "  * Las funciones Qiskit son una función experimental disponible únicamente para los usuarios de los planes IBM Quantum® Premium Plan, Flex Plan y On-Prem (a través de IBM Quantum Platform API). Se trata de versiones preliminares sujetas a cambios.\n",
        "</Admonition>\n",
        "\n",
        "<span id=\"overview\" />\n",
        "\n",
        "## Visión general\n",
        "\n",
        "Con el optimizador cuántico Iskay de Kipu Quantum, podrá abordar complejos problemas de optimización utilizando los ordenadores cuánticos de IBM®. Este solucionador aprovecha [el algoritmo bf-DCQO](https://doi.org/10.48550/arXiv.2409.04477) de vanguardia de Kipu, que requiere solo la función objetivo como entrada para entregar automáticamente soluciones al problema. Puede tratar problemas de optimización que impliquen hasta 156 qubits, lo que permite utilizar todos los qubits de los dispositivos cuánticos de IBM. El Optimizador utiliza un mapeo 1-to-1 entre variables clásicas y qubits, lo que permite abordar problemas de optimización con hasta 156 variables binarias.\n",
        "\n",
        "El optimizador permite resolver problemas de optimización binarios sin restricciones. Además de la formulación QUBO (Quadratic Unconstrained Binary Optimization) de uso común, también admite problemas de optimización de orden superior (HUBO). El solucionador utiliza un algoritmo cuántico no variacional que realiza la mayor parte del cálculo en dispositivos cuánticos.\n",
        "\n",
        "A continuación se ofrecen más detalles sobre el algoritmo utilizado y una breve guía sobre cómo utilizar la función, así como resultados de pruebas comparativas en varias instancias de problemas de distintos tamaños y complejidades.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5f761442",
      "metadata": {},
      "source": [
        "<span id=\"description\" />\n",
        "\n",
        "## Descripción\n",
        "\n",
        "El Optimizador es una implementación lista para usar de los algoritmos de optimización cuántica más avanzados. Resuelve problemas de optimización ejecutando circuitos cuánticos altamente comprimidos en hardware cuántico. Esta compresión se consigue introduciendo términos contradiabáticos en la evolución temporal subyacente del sistema cuántico. El algoritmo ejecuta varias iteraciones de carreras de hardware para obtener las soluciones finales y lo combina con el postprocesamiento. Estos pasos se integran perfectamente en el flujo de trabajo del optimizador y se ejecutan automáticamente.\n",
        "\n",
        "<span id=\"how-does-the-quantum-optimizer-work\" />\n",
        "\n",
        "### ¿Cómo funciona el optimizador cuántico?\n",
        "\n",
        "En esta sección se describen los fundamentos del algoritmo bf-DCQO implementado. También se puede encontrar una introducción al algoritmo en el [canal Qiskit YouTube](https://www.youtube.com/watch?v=33QmsXhIlpU\\&t=1223s).\n",
        "\n",
        "El algoritmo se basa en la evolución temporal de un sistema cuántico que se transforma con el tiempo, donde la solución del problema se codifica en el estado fundamental del sistema cuántico al final de la evolución. Según [el teorema adiabático](https://en.wikipedia.org/wiki/Adiabatic_theorem), esta evolución tiene que ser lenta para garantizar que el sistema permanezca en su estado fundamental. La digitalización de esta evolución es la base de la computación adiabática cuántica digitalizada (DQA) y del infame algoritmo QAOA. Sin embargo, la evolución lenta requerida no es factible para problemas de tamaño creciente, ya que da lugar a una profundidad de circuito cada vez mayor. Mediante el uso de protocolos contradiabáticos, se pueden suprimir las excitaciones no deseadas que se producen durante tiempos de evolución cortos mientras se permanece en el estado de masa. Aquí, la digitalización de este menor tiempo de evolución da lugar a circuitos cuánticos con menor profundidad y menos puertas de enredo.\n",
        "\n",
        "Los circuitos de los algoritmos bf-DCQO suelen utilizar hasta diez veces menos puertas de enredo que DQA, y de tres a cuatro veces menos puertas de enredo que las implementaciones estándar de QAOA. Debido al menor número de puertas, se producen menos errores durante la ejecución del circuito en el hardware. Por lo tanto, el optimizador no necesita utilizar técnicas como la supresión o mitigación de errores. Su aplicación en futuras versiones puede mejorar aún más la calidad de la solución.\n",
        "\n",
        "Aunque el algoritmo bf-DCQO utiliza iteraciones, no es variacional. Después de cada iteración del algoritmo, se mide la distribución de los estados. La distribución obtenida se utiliza para calcular el denominado campo de polarización. El campo de polarización permite iniciar la siguiente iteración a partir de un estado energético cercano a la solución encontrada anteriormente. De este modo, el algoritmo se desplaza en cada iteración hacia soluciones de menor energía. Normalmente, bastan unas diez iteraciones para converger a una solución, lo que en total requiere un número de iteraciones muy inferior al de los algoritmos variacionales, que es del orden de unas 100 iteraciones.\n",
        "\n",
        "El optimizador combina el algoritmo bf-DCQO con el postprocesamiento clásico. Tras medir la distribución de los estados, se realiza una búsqueda local. Durante la búsqueda local, los bits de la solución medida se invierten aleatoriamente. Tras la inversión, se evalúa la energía de la nueva cadena de bits. Si la energía es menor, la cadena de bits se mantiene como la nueva solución. La búsqueda local sólo escala linealmente con el número de qubits, por lo que es computacionalmente barata. Dado que el postprocesado corrige las desviaciones de bits locales, compensa los errores de desviación de bits que suelen ser el resultado de imperfecciones del hardware y errores de lectura.\n",
        "\n",
        "<span id=\"workflow\" />\n",
        "\n",
        "### Flujo de trabajo\n",
        "\n",
        "A continuación se presenta un esquema del flujo de trabajo del Optimizador Cuántico.\n",
        "\n",
        "![Flujo de trabajo](https://quantum.cloud.ibm.com/docs/images/guides/kipu-optimization/workflow.svg \"Flujo de trabajo del optimizador cuántico\")\n",
        "\n",
        "Utilizando el optimizador cuántico, la resolución de un problema de optimización en hardware cuántico puede reducirse a\n",
        "\n",
        "* Formular la función objetivo del problema\n",
        "* Acceso al optimizador a través de las funciones de Qiskit\n",
        "* Ejecute el Optimizador y recoja el resultado\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b34fe075",
      "metadata": {},
      "source": [
        "<span id=\"benchmarks\" />\n",
        "\n",
        "## Referencias comparativas\n",
        "\n",
        "Las métricas de referencia que se muestran a continuación demuestran que el optimizador aborda con eficacia problemas de hasta 156 qubits y ofrecen una visión general de la precisión y escalabilidad del optimizador en distintos tipos de problemas. Tenga en cuenta que las métricas de rendimiento reales pueden variar en función de las características específicas del problema, como el número de variables, la densidad y la localidad de los términos en la función objetivo y el orden polinómico.\n",
        "\n",
        "La siguiente tabla incluye el ratio de aproximación (AR), una métrica definida del siguiente modo:\n",
        "\n",
        "$$\n",
        "AR = \\frac{C^{*} - C_\\textrm{max}}{C_{\\textrm{min}} - C_{\\textrm{max}}},\n",
        "$$\n",
        "\n",
        "donde $C$ es la función objetivo, $C_{\\textrm{min}}$, $C_{\\textrm{max}}$ son sus valores mínimo y máximo, y $C^{*}$ es el coste de la mejor solución encontrada, respectivamente. Por lo tanto, AR=100% significa que se ha obtenido el estado básico del problema.\n",
        "\n",
        "| Ejemplo             | Número de qubits | Ratio de aproximación | Tiempo total (s) | Tiempo de ejecución (s) | Número total de disparos | Número de iteraciones |\n",
        "| ------------------- | :--------------: | :-------------------: | :--------------: | :---------------------: | :----------------------: | :-------------------: |\n",
        "| Sin ponderar MaxCut |        28        |         100 %         |        180       |            30           |            30k           |           5           |\n",
        "| Sin ponderar MaxCut |        30        |         100 %         |        180       |            30           |            30k           |           5           |\n",
        "| Sin ponderar MaxCut |        32        |         100 %         |        180       |            30           |            30k           |           5           |\n",
        "| Sin ponderar MaxCut |        80        |         100 %         |        480       |            60           |            90k           |           9           |\n",
        "| Sin ponderar MaxCut |        100       |         100 %         |        330       |            60           |            60k           |           6           |\n",
        "| Sin ponderar MaxCut |        120       |         100 %         |        370       |            60           |            60k           |           6           |\n",
        "| HUBO 1              |        156       |         100 %         |        600       |            73           |           100k           |           10          |\n",
        "| HUBO 2              |        156       |         100 %         |        600       |            73           |           100k           |           10          |\n",
        "\n",
        "* Las instancias MaxCut con 28, 30 y 32 qubits se ejecutaron en ibm\\_sherbrooke. Las instancias con 80, 100 y 120 se ejecutaron en un procesador Heron r2.\n",
        "* Las instancias de HUBO también se ejecutaron en un procesador Heron r2.\n",
        "\n",
        "Todas las instancias de benchmark son accesibles en GitHub (ver [instancias de benchmark Kipu](https://github.com/Kipu-Quantum-GmbH/benchmark-instances) ). Encontrará un ejemplo para ejecutar estas instancias en el [Ejemplo 3: Instancias de referencia](#example-3-benchmark-instances).\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "73390a19",
      "metadata": {},
      "source": [
        "<span id=\"get-started\" />\n",
        "\n",
        "## Cómo empezar\n",
        "\n",
        "En esta documentación, repasaremos los pasos para utilizar el optimizador cuántico Iskay. En el proceso, mostraremos rápidamente cómo cargar la función desde el catálogo y cómo convertir su problema en una entrada válida, al tiempo que le enseñamos cómo puede experimentar con diferentes parámetros opcionales.\n",
        "\n",
        "Para ver un ejemplo más detallado, consulte el tutorial [Resolver el problema de la división del mercado con el optimizador cuántico Iskay de Kipu Quantum](/docs/tutorials/solve-market-split-problem-with-iskay-quantum-optimizer), en el que repasamos todo el proceso de uso del solucionador Iskay para abordar el problema de la división del mercado, que representa un reto real de asignación de recursos en el que los mercados deben dividirse en regiones de ventas equilibradas para cumplir los objetivos de demanda exactos.\n",
        "\n",
        "Autentícate utilizando tu clave API, que encontrarás en el [panel de control de IBM Quantum Platform](http://quantum.cloud.ibm.com/), y selecciona la función Qiskit como se indica a continuación:\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e5cd4ac8",
      "metadata": {},
      "source": [
        "<Admonition type=\"note\">\n",
        "  El siguiente código da por hecho que has guardado tus credenciales. Si aún no lo has hecho, sigue las instrucciones de [«Guardar tu cuenta de IBM Cloud »](/docs/guides/functions-get-started#install-qiskit-functions-catalog-client) para autenticarte con tu clave 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",
        "## Ejemplo de configuración personalizada\n",
        "\n",
        "A continuación te mostramos cómo puedes configurar Iskay con diferentes ajustes:\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": [
        "**Optimización de semillas** : Tenga en cuenta que `seed_transpiler` está establecido en `None` de forma predeterminada. Esto permite el proceso de optimización automática del transpilador. Cuando `None`, el sistema iniciará una prueba con múltiples semillas y seleccionará la que produzca la mejor profundidad de circuito, aprovechando toda la potencia del `max_trials` parámetro para cada nivel de transpilación.\n",
        "\n",
        "**Rendimiento del nivel de transpilación** : aumentar el número de `max_trials` con valores más altos para `transpilation_level` aumentará inevitablemente el tiempo de transpilación, pero puede que no siempre cambie el circuito final, ya que esto depende en gran medida de la estructura y la complejidad específicas del circuito. Sin embargo, para algunos circuitos/problemas, la diferencia entre 10 ensayos (nivel 1) y 50 ensayos (nivel 5) puede ser considerable, por lo que explorar estos parámetros podría ser la clave para encontrar una solución satisfactoria.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d4ca2590",
      "metadata": {},
      "source": [
        "<span id=\"example-1-simple-cost-function\" />\n",
        "\n",
        "## Ejemplo 1: Función de coste simple\n",
        "\n",
        "Consideremos la función de coste en la formulación de espín:\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",
        "donde $(x_0, ..., x_4) \\in \\{-1, 1\\}^5$.\n",
        "\n",
        "La solución a esta sencilla función de costes es\n",
        "\n",
        "$$\n",
        "(x_0, x_1, x_2, x_3, x_4) = (-1, -1, -1, 1, 1)\n",
        "$$\n",
        "\n",
        "con valor mínimo $C^{*} = -6$\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a98e8232",
      "metadata": {},
      "source": [
        "<span id=\"1-create-the-objective-function\" />\n",
        "\n",
        "### 1. Crear la función objetivo\n",
        "\n",
        "Comenzamos creando un diccionario con los coeficientes de la función objetivo de la siguiente manera:\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. Ejecuta el Optimizador\n",
        "\n",
        "Resolvemos el problema ejecutando el optimizador. Dado que $(x_0, ..., x_4) \\in \\{-1, 1\\}^5$ debemos fijar `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. Recuperar el resultado\n",
        "\n",
        "La solución del problema de optimización se proporciona directamente desde el optimizador.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "2f74d7e2",
      "metadata": {},
      "outputs": [],
      "source": [
        "print(job.result())"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c4d0a0f8",
      "metadata": {},
      "source": [
        "Esto mostrará un diccionario de la forma:\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",
        "Observe que el diccionario `solution` muestra el vector de resultados $(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",
        "## Ejemplo 2: MaxCut\n",
        "\n",
        "Muchos problemas de grafos, como MaxCut o Maximum independent set, son problemas difíciles NP y candidatos ideales para probar algoritmos y hardware cuánticos. Este ejemplo demuestra la resolución del problema MaxCut de un grafo 3-regular con el Optimizador Quantum.\n",
        "\n",
        "Para ejecutar este ejemplo debe instalar el paquete `networkx` además de `qiskit-ibm-catalog`. Para instalarlo, ejecute el mandato siguiente:\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. Crear la función objetivo\n",
        "\n",
        "Empieza generando un grafo 3-regular aleatorio. Para este gráfico, definimos la función objetivo del problema 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. Ejecuta el Optimizador\n",
        "\n",
        "Resuelve el problema ejecutando el optimizador.\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. Recuperar el resultado\n",
        "\n",
        "Recupera el resultado y asigna la cadena de bits de la solución a los nodos del grafo original.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "169cbd6e",
      "metadata": {},
      "outputs": [],
      "source": [
        "print(job.result())"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7f22d66a",
      "metadata": {},
      "source": [
        "La solución al problema Maxcut se encuentra directamente en el subdiccionario `solution` del objeto resultado\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",
        "## Ejemplo 3: Instancias de referencia\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "98545ce3",
      "metadata": {},
      "source": [
        "Las instancias de referencia están disponibles en GitHub: [Instancias de referencia de Kipu](https://github.com/Kipu-Quantum-GmbH/benchmark-instances).\n",
        "\n",
        "Las instancias pueden cargarse utilizando la biblioteca `pygithub` . Para instalarlo, ejecute el mandato siguiente:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "1d8777e4",
      "metadata": {},
      "outputs": [],
      "source": [
        "# %pip install pygithub"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e3a03447",
      "metadata": {},
      "source": [
        "Las rutas para las instancias de referencia son:\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",
        "Para reproducir el rendimiento del benchmark para las instancias HUBO, seleccione el backend `ibm_marrakesh` y establezca `direct_qubit_mapping` en `True` en el subdiccionario `options` .\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "adbed9be",
      "metadata": {},
      "source": [
        "En el siguiente ejemplo se ejecuta la instancia de Maxcut con 150 nodos.\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",
        "## Casos de uso\n",
        "\n",
        "Los casos de uso típicos del solucionador de optimización son los problemas de optimización combinatoria. Puede resolver problemas de muchos sectores, como el financiero, el farmacéutico o el logístico. He aquí algunos ejemplos.\n",
        "\n",
        "* Optimización de carteras (QUBO): [publicación científica](https://doi.org/10.1103/PhysRevApplied.22.054037) y [libro blanco](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",
        "* Plegado de proteínas (HUBO): [publicación científica](https://doi.org/10.1103/PhysRevApplied.20.014024)\n",
        "* Programación logística (QUBO): [publicación científica](https://doi.org/10.1103/PhysRevApplied.22.064068)\n",
        "* Optimización de la red: [seminario web](https://www.youtube.com/watch?v=w5SrCIK88No)\n",
        "* División del mercado (QUBO): [tutorial](/docs/tutorials/solve-market-split-problem-with-iskay-quantum-optimizer)\n",
        "\n",
        "Si está interesado en abordar un caso de uso específico y desarrollar un mapeo dedicado, podemos ayudarle. [Contáctenos](https://share-eu1.hsforms.com/2Ff8cgWvTR9ukT_fPoaNhDw2dqpz5).\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e9ec2e67",
      "metadata": {},
      "source": [
        "<span id=\"get-support\" />\n",
        "\n",
        "## Obtener soporte\n",
        "\n",
        "Para obtener ayuda, póngase en contacto con [support@kipu-quantum.com](mailto:support@kipu-quantum.com).\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5a6a25c8",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Próximos pasos\n",
        "\n",
        "* [Solicita acceso al Quantum Optimizer de Kipu Quantum](https://share-eu1.hsforms.com/2Ff8cgWvTR9ukT_fPoaNhDw2dqpz5).\n",
        "* Consulta la [referencia](/docs/api/functions/kipu-optimization) de la API de esta función de Qiskit.\n",
        "* Prueba el tutorial [«Resuelve el problema de la división del mercado» con el optimizador cuántico Iskay de Kipu Quantum](/docs/tutorials/solve-market-split-problem-with-iskay-quantum-optimizer).\n",
        "* Revisión [Romero, S. V., et al. (2025).  Algoritmo cuántico contra-diabático digitalizado de campo sesgado para la optimización binaria de orden superior. arXiv Preimpresión arXiv:2409.04477](https://arxiv.org/abs/2409.04477).\n",
        "* Revisión [Cadavid, A. G., et al. (2024).  Optimización cuántica contra-diabática digitalizada con campo sesgado. arXiv Preimpresión arXiv:2405.13898](https://arxiv.org/abs/2405.13898).\n",
        "* Revisión [Chandarana, P., et al. (2025).  Ventaja cuántica en tiempo de ejecución con optimización cuántica digital. arXiv Preimpresión arXiv:2505.08663](https://arxiv.org/abs/2505.08663).\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f73ef6c4",
      "metadata": {},
      "source": [
        "<span id=\"additional-information\" />\n",
        "\n",
        "## Información adicional\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "52b5221c",
      "metadata": {},
      "source": [
        "Iskay, como el nombre de nuestra empresa, Kipu Quantum, es una palabra peruana. Aunque somos una startup de Alemania, estas palabras proceden del país natal de uno de nuestros cofundadores, donde el Quipu fue una de las primeras máquinas de cálculo desarrolladas por la humanidad 2000 años antes de Cristo.\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
}