{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "f7d9993f",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Iskay Quantum Optimizer - Una funzione Qiskit di Kipu Quantum\"\n",
        "description: \"Risolvi in modo efficiente i problemi di ottimizzazione con Iskay Quantum Optimizer di Kipu Quantum, disponibile su 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 funzione Qiskit di Kipu Quantum\n",
        "\n",
        "*Consulta la [documentazione dell'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",
        "  * Le funzioni Qiskit sono una funzione sperimentale disponibile solo per gli utenti di IBM Quantum® Premium Plan, Flex Plan e On-Prem (tramite IBM Quantum Platform API) Plan. Sono in stato di anteprima e sono soggetti a modifiche.\n",
        "</Admonition>\n",
        "\n",
        "<span id=\"overview\" />\n",
        "\n",
        "## Panoramica\n",
        "\n",
        "Con l'Iskay Quantum Optimizer di Kipu Quantum è possibile affrontare complessi problemi di ottimizzazione utilizzando i computer quantistici di IBM®. Questo risolutore sfrutta [l'algoritmo bf-DCQO](https://doi.org/10.48550/arXiv.2409.04477) all'avanguardia di Kipu, che richiede solo la funzione obiettivo come input per fornire automaticamente soluzioni ai problemi. Può gestire problemi di ottimizzazione che coinvolgono fino a 156 qubit, consentendo di utilizzare tutti i qubit dei dispositivi quantistici IBM. L'ottimizzatore utilizza una mappatura 1-to-1 tra variabili classiche e qubit, che consente di affrontare problemi di ottimizzazione con un massimo di 156 variabili binarie.\n",
        "\n",
        "L'Optimizer consente di risolvere problemi di ottimizzazione binaria non vincolata. Oltre alla formulazione QUBO (Quadratic Unconstrained Binary Optimization) comunemente utilizzata, supporta anche problemi di ottimizzazione di ordine superiore (HUBO). Il risolutore utilizza un algoritmo quantistico non variazionale, eseguendo la maggior parte del calcolo su dispositivi quantistici.\n",
        "\n",
        "Di seguito vengono forniti maggiori dettagli sull'algoritmo utilizzato e una breve guida all'uso della funzione, oltre ai risultati di benchmarking su varie istanze di problemi di diverse dimensioni e complessità.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5f761442",
      "metadata": {},
      "source": [
        "<span id=\"description\" />\n",
        "\n",
        "## Descrizione\n",
        "\n",
        "Optimizer è un'implementazione pronta all'uso di algoritmi di ottimizzazione quantistica all'avanguardia. Risolve problemi di ottimizzazione eseguendo circuiti quantistici altamente compressi su hardware quantistico. Questa compressione si ottiene introducendo termini controdiabatici nell'evoluzione temporale del sistema quantistico. L'algoritmo esegue diverse iterazioni di corse hardware per ottenere le soluzioni finali e le combina con la post-elaborazione. Queste fasi sono perfettamente integrate nel flusso di lavoro di Optimizer e vengono eseguite automaticamente.\n",
        "\n",
        "<span id=\"how-does-the-quantum-optimizer-work\" />\n",
        "\n",
        "### Come funziona il Quantum Optimizer?\n",
        "\n",
        "Questa sezione illustra le basi dell'algoritmo bf-DCQO implementato. Un'introduzione all'algoritmo è disponibile anche sul [canale](https://www.youtube.com/watch?v=33QmsXhIlpU\\&t=1223s) Qiskit YouTube.\n",
        "\n",
        "L'algoritmo si basa sull'evoluzione temporale di un sistema quantistico che si trasforma nel tempo, dove la soluzione del problema è codificata nello stato fondamentale del sistema quantistico alla fine dell'evoluzione. Secondo il [teorema adiabatico](https://en.wikipedia.org/wiki/Adiabatic_theorem), questa evoluzione deve essere lenta per garantire che il sistema rimanga nel suo stato fondamentale. La digitalizzazione di questa evoluzione è alla base del calcolo quantistico adiabatico digitalizzato (DQA) e del famoso algoritmo QAOA. Tuttavia, l'evoluzione lenta richiesta non è fattibile per problemi di dimensioni crescenti, poiché comporta un aumento della profondità del circuito. Utilizzando protocolli controdiabatici, è possibile sopprimere le eccitazioni indesiderate che si verificano durante i brevi tempi di evoluzione, pur rimanendo allo stato fondamentale. In questo caso, digitalizzando questo tempo di evoluzione più breve si ottengono circuiti quantistici con una profondità minore e un numero inferiore di porte di entangling.\n",
        "\n",
        "I circuiti degli algoritmi bf-DCQO utilizzano in genere un numero di porte di entangling fino a dieci volte inferiore rispetto a DQA e da tre a quattro volte inferiore rispetto alle implementazioni standard di QAOA. Grazie al numero ridotto di porte, si verificano meno errori durante l'esecuzione del circuito sull'hardware. Pertanto, l'ottimizzatore non richiede l'uso di tecniche come la soppressione o l'attenuazione degli errori. La loro implementazione nelle versioni future può migliorare ulteriormente la qualità della soluzione.\n",
        "\n",
        "Sebbene l'algoritmo bf-DCQO utilizzi iterazioni, non è variazionale. Dopo ogni iterazione dell'algoritmo, viene misurata la distribuzione degli stati. La distribuzione ottenuta viene utilizzata per calcolare il cosiddetto campo di polarizzazione. Il campo di polarizzazione consente di iniziare l'iterazione successiva da uno stato energetico vicino alla soluzione trovata in precedenza. In questo modo, l'algoritmo si sposta a ogni iterazione verso soluzioni di energia inferiore. In genere, sono sufficienti circa dieci iterazioni per convergere a una soluzione, richiedendo in totale un numero di iterazioni molto inferiore rispetto agli algoritmi variazionali, che sono dell'ordine di circa 100 iterazioni.\n",
        "\n",
        "L'ottimizzatore combina l'algoritmo bf-DCQO con la classica post-elaborazione. Dopo aver misurato la distribuzione degli stati, viene eseguita una ricerca locale. Durante la ricerca locale, i bit della soluzione misurata vengono invertiti casualmente. Dopo il salto mortale, viene valutata l'energia della nuova stringa di bit. Se l'energia è inferiore, la stringa di bit viene mantenuta come nuova soluzione. La ricerca locale scala solo linearmente con il numero di qubit; di conseguenza, è computazionalmente economica. Poiché la post-elaborazione corregge i bitflip locali, compensa gli errori di bit-flip che spesso sono il risultato di imperfezioni hardware e di errori di lettura.\n",
        "\n",
        "<span id=\"workflow\" />\n",
        "\n",
        "### Flusso di lavoro\n",
        "\n",
        "Segue uno schema del flusso di lavoro del Quantum Optimizer.\n",
        "\n",
        "![Flusso di lavoro](https://quantum.cloud.ibm.com/docs/images/guides/kipu-optimization/workflow.svg \"Flusso di lavoro dell'Ottimizzatore Quantistico\")\n",
        "\n",
        "Utilizzando il Quantum Optimizer, la soluzione di un problema di ottimizzazione su hardware quantistico può essere ridotta a\n",
        "\n",
        "* Formulare la funzione obiettivo del problema\n",
        "* Accesso all'ottimizzatore tramite le funzioni di Qiskit\n",
        "* Eseguire l'ottimizzatore e raccogliere i risultati\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b34fe075",
      "metadata": {},
      "source": [
        "<span id=\"benchmarks\" />\n",
        "\n",
        "## Benchmark\n",
        "\n",
        "Le metriche di benchmark riportate di seguito mostrano che l'ottimizzatore affronta efficacemente problemi che coinvolgono fino a 156 qubit e offrono una panoramica generale dell'accuratezza e della scalabilità dell'ottimizzatore in diversi tipi di problemi. Si noti che le metriche di prestazione effettive possono variare a seconda delle caratteristiche specifiche del problema, come il numero di variabili, la densità e la localizzazione dei termini nella funzione obiettivo e l'ordine polinomiale.\n",
        "\n",
        "La tabella seguente include il rapporto di approssimazione (AR), una metrica definita come segue:\n",
        "\n",
        "$$\n",
        "AR = \\frac{C^{*} - C_\\textrm{max}}{C_{\\textrm{min}} - C_{\\textrm{max}}},\n",
        "$$\n",
        "\n",
        "dove $C$ è la funzione obiettivo, $C_{\\textrm{min}}$, $C_{\\textrm{max}}$ sono rispettivamente i suoi valori minimo e massimo e $C^{*}$ è il costo della migliore soluzione trovata. Pertanto, AR=100% significa che è stato ottenuto lo stato fondamentale del problema.\n",
        "\n",
        "| Esempio              | Numero di qubit | Rapporto di approssimazione | Tempo totale | Utilizzo del tempo di esecuzione (s) | Numero totale di scatti | Numero di iterazioni |\n",
        "| -------------------- | :-------------: | :-------------------------: | :----------: | :----------------------------------: | :---------------------: | :------------------: |\n",
        "| Non ponderato MaxCut |        28       |             100%            |      180     |                  30                  |           30k           |           5          |\n",
        "| Non ponderato MaxCut |        30       |             100%            |      180     |                  30                  |           30k           |           5          |\n",
        "| Non ponderato MaxCut |        32       |             100%            |      180     |                  30                  |           30k           |           5          |\n",
        "| Non ponderato MaxCut |        80       |             100%            |      480     |                  60                  |           90k           |           9          |\n",
        "| Non ponderato MaxCut |       100       |             100%            |      330     |                  60                  |           60k           |           6          |\n",
        "| Non ponderato MaxCut |       120       |             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",
        "* Le istanze di MaxCut con 28, 30 e 32 qubit sono state eseguite su ibm\\_sherbrooke. Le istanze con 80, 100 e 120 sono state eseguite su un processore Heron r2.\n",
        "* Anche le istanze di HUBO sono state eseguite su un processore Heron r2.\n",
        "\n",
        "Tutte le istanze di benchmark sono accessibili su GitHub (vedi [istanze di benchmark Kipu](https://github.com/Kipu-Quantum-GmbH/benchmark-instances) ). Un esempio di esecuzione di queste istanze si trova nell' [Esempio 3: Istanze di benchmark](#example-3-benchmark-instances).\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "73390a19",
      "metadata": {},
      "source": [
        "<span id=\"get-started\" />\n",
        "\n",
        "## Introduzione\n",
        "\n",
        "In questa documentazione, illustreremo i passaggi necessari per utilizzare Iskay Quantum Optimizer. Nel corso della procedura mostreremo rapidamente come caricare la funzione dal catalogo e come convertire il problema in un input valido, illustrando al contempo come sperimentare diversi parametri opzionali.\n",
        "\n",
        "Per un esempio più dettagliato, consulta il tutorial [Risolvi il problema della suddivisione del mercato con Iskay Quantum Optimizer di Kipu Quantum](/docs/tutorials/solve-market-split-problem-with-iskay-quantum-optimizer), in cui illustriamo l'intero processo di utilizzo di Iskay Solver per affrontare il problema della suddivisione del mercato, che rappresenta una sfida reale nell'allocazione delle risorse in cui i mercati devono essere suddivisi in regioni di vendita equilibrate per soddisfare obiettivi di domanda precisi.\n",
        "\n",
        "Autenticatevi utilizzando la vostra chiave API, che si trova nella [dashboard di IBM Quantum Platform](http://quantum.cloud.ibm.com/), e selezionate la funzione Qiskit come segue:\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e5cd4ac8",
      "metadata": {},
      "source": [
        "<Admonition type=\"note\">\n",
        "  Il codice che segue presuppone che tu abbia salvato le tue credenziali. Se non l'hai ancora fatto, segui le istruzioni riportate nella guida [\"Salva il tuo account IBM Cloud \"](/docs/guides/functions-get-started#install-qiskit-functions-catalog-client) per effettuare l'autenticazione con la tua chiave 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",
        "## Esempio di configurazione personalizzata\n",
        "\n",
        "Ecco come puoi configurare Iskay con diverse impostazioni:\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": [
        "**Ottimizzazione dei semi** : si noti che `seed_transpiler` è impostato su `None` per impostazione predefinita. Ciò consente il processo di ottimizzazione automatica del transpiler. Quando `None`, il sistema avvierà una prova con più seed e selezionerà quello che produce la migliore profondità del circuito, sfruttando tutta la potenza del `max_trials` parametro per ogni livello di transpilazione.\n",
        "\n",
        "**Prestazioni a livello di transpilazione** : aumentando il numero di `max_trials` con valori più elevati per `transpilation_level` si aumenterà inevitabilmente il tempo di transpilazione, ma ciò potrebbe non modificare sempre il circuito finale, poiché ciò dipende in larga misura dalla struttura e dalla complessità specifiche del circuito. Per alcuni circuiti/problemi, tuttavia, la differenza tra 10 tentativi (livello 1) e 50 tentativi (livello 5) può essere notevole, quindi esplorare questi parametri potrebbe essere la chiave per trovare con successo una soluzione.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d4ca2590",
      "metadata": {},
      "source": [
        "<span id=\"example-1-simple-cost-function\" />\n",
        "\n",
        "## Esempio 1: Funzione di costo semplice\n",
        "\n",
        "Consideriamo la funzione di costo nella formulazione di 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",
        "dove $(x_0, ..., x_4) \\in \\{-1, 1\\}^5$.\n",
        "\n",
        "La soluzione a questa semplice funzione di costo è\n",
        "\n",
        "$$\n",
        "(x_0, x_1, x_2, x_3, x_4) = (-1, -1, -1, 1, 1)\n",
        "$$\n",
        "\n",
        "con valore minimo $C^{*} = -6$\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a98e8232",
      "metadata": {},
      "source": [
        "<span id=\"1-create-the-objective-function\" />\n",
        "\n",
        "### 1. Creare la funzione obiettivo\n",
        "\n",
        "Si inizia creando un dizionario con i coefficienti della funzione obiettivo come segue:\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. Eseguire l'ottimizzatore\n",
        "\n",
        "Risolviamo il problema eseguendo l'ottimizzatore. Poiché $(x_0, ..., x_4) \\in \\{-1, 1\\}^5$ dobbiamo impostare `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. Recupera il risultato\n",
        "\n",
        "La soluzione del problema di ottimizzazione viene fornita direttamente dall'ottimizzatore.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "2f74d7e2",
      "metadata": {},
      "outputs": [],
      "source": [
        "print(job.result())"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c4d0a0f8",
      "metadata": {},
      "source": [
        "Verrà visualizzato un dizionario della 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",
        "Si noti che il dizionario `solution` visualizza il vettore di risultati $(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",
        "## Esempio 2: MaxCut\n",
        "\n",
        "Molti problemi di grafi come MaxCut o Maximum independent set sono problemi NP-hard e candidati ideali per testare algoritmi e hardware quantistici. Questo esempio dimostra la risoluzione del problema MaxCut di un grafo 3-regolare con il Quantum Optimizer.\n",
        "\n",
        "Per eseguire questo esempio è necessario installare il pacchetto `networkx` oltre al pacchetto `qiskit-ibm-catalog`. Per installarlo, eseguire il seguente comando:\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. Creare la funzione obiettivo\n",
        "\n",
        "Si inizia generando un grafo 3-regolare casuale. Per questo grafico, definiamo la funzione obiettivo 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. Eseguire l'ottimizzatore\n",
        "\n",
        "Risolvere il problema eseguendo l'ottimizzatore.\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. Recupera il risultato\n",
        "\n",
        "Recupera il risultato e mappa la bitstring della soluzione ai nodi del grafo originale.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "169cbd6e",
      "metadata": {},
      "outputs": [],
      "source": [
        "print(job.result())"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7f22d66a",
      "metadata": {},
      "source": [
        "La soluzione al problema Maxcut è contenuta direttamente nel sottodizionario `solution` dell'oggetto risultato\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",
        "## Esempio 3: Istanze di benchmark\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "98545ce3",
      "metadata": {},
      "source": [
        "Le istanze di benchmark sono disponibili su GitHub: [Istanze di benchmark Kipu](https://github.com/Kipu-Quantum-GmbH/benchmark-instances).\n",
        "\n",
        "Le istanze possono essere caricate utilizzando la libreria `pygithub` . Per installarlo, eseguire il seguente comando:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "1d8777e4",
      "metadata": {},
      "outputs": [],
      "source": [
        "# %pip install pygithub"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e3a03447",
      "metadata": {},
      "source": [
        "I percorsi per le istanze di benchmark sono:\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",
        "Per riprodurre le prestazioni del benchmark per le istanze HUBO, selezionare il backend `ibm_marrakesh` e impostare `direct_qubit_mapping` su `True` nel sottodizionario `options` .\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "adbed9be",
      "metadata": {},
      "source": [
        "L'esempio seguente esegue l'istanza di Maxcut con 150 nodi.\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",
        "## Casi di utilizzo\n",
        "\n",
        "I casi d'uso tipici del solutore di ottimizzazione sono i problemi di ottimizzazione combinatoria. È possibile risolvere problemi di molti settori, come quello finanziario, farmaceutico o logistico. Esempi:\n",
        "\n",
        "* Ottimizzazione del portafoglio (QUBO): [pubblicazione scientifica](https://doi.org/10.1103/PhysRevApplied.22.054037) e [libro bianco](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",
        "* Ripiegamento delle proteine (HUBO): [pubblicazione scientifica](https://doi.org/10.1103/PhysRevApplied.20.014024)\n",
        "* Pianificazione logistica (QUBO): [pubblicazione scientifica](https://doi.org/10.1103/PhysRevApplied.22.064068)\n",
        "* Ottimizzazione della rete: [webinar](https://www.youtube.com/watch?v=w5SrCIK88No)\n",
        "* Divisione del mercato (QUBO): [tutorial](/docs/tutorials/solve-market-split-problem-with-iskay-quantum-optimizer)\n",
        "\n",
        "Se sei interessato ad affrontare un caso d'uso specifico e sviluppare una mappatura dedicata, possiamo aiutarti. [Contattaci](https://share-eu1.hsforms.com/2Ff8cgWvTR9ukT_fPoaNhDw2dqpz5).\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e9ec2e67",
      "metadata": {},
      "source": [
        "<span id=\"get-support\" />\n",
        "\n",
        "## Ottenere supporto\n",
        "\n",
        "Per assistenza, contattare [support@kipu-quantum.com](mailto:support@kipu-quantum.com).\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5a6a25c8",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Passi successivi\n",
        "\n",
        "* [Richiedi l'accesso al Quantum Optimizer di Kipu Quantum](https://share-eu1.hsforms.com/2Ff8cgWvTR9ukT_fPoaNhDw2dqpz5).\n",
        "* Consulta la documentazione [di riferimento dell'API](/docs/api/functions/kipu-optimization) relativa a questa funzione di Qiskit.\n",
        "* Prova a [risolvere il problema della divisione del mercato con](/docs/tutorials/solve-market-split-problem-with-iskay-quantum-optimizer) il tutorial Iskay Quantum Optimizer di Kipu Quantum.\n",
        "* Recensione [Romero, S. V., et al. (2025).  Algoritmo quantistico controdiabatico digitalizzato con campo di bias per l'ottimizzazione binaria di ordine superiore. arXiv preprint arXiv:2409.04477](https://arxiv.org/abs/2409.04477).\n",
        "* Recensione [Cadavid, A. G., et al. (2024).  Ottimizzazione quantistica controdiabatica digitalizzata con campo di polarizzazione. arXiv preprint arXiv:2405.13898](https://arxiv.org/abs/2405.13898).\n",
        "* Recensione [Chandarana, P., et al. (2025).  Vantaggio quantistico in fase di esecuzione con ottimizzazione quantistica digitale. arXiv preprint arXiv:2505.08663](https://arxiv.org/abs/2505.08663).\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f73ef6c4",
      "metadata": {},
      "source": [
        "<span id=\"additional-information\" />\n",
        "\n",
        "## Ulteriori informazioni\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "52b5221c",
      "metadata": {},
      "source": [
        "Iskay, come il nome della nostra azienda Kipu Quantum, è una parola peruviana. Anche se siamo una startup tedesca, queste parole provengono dal paese natale di uno dei nostri co-fondatori, dove il Quipu è stata una delle prime macchine da calcolo sviluppate dall'umanità 2000 anni a.C..\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
}