{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "title",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Resolva o problema da divisão do mercado com o Iskay Quantum Optimizer da Kipu Quantum\"\n",
        "description: \"Aprenda a resolver o problema da divisão do mercado usando o Iskay Quantum Optimizer com o algoritmo bf-DCQO em um hardwar IBM Quantum\"\n",
        "---\n",
        "\n",
        "<span id=\"solve-the-market-split-problem-with-kipu-quantums-iskay-quantum-optimizer\" />\n",
        "\n",
        "# Resolva o problema da divisão do mercado com o Iskay Quantum Optimizer da Kipu Quantum\n",
        "\n",
        "{/* cspell:ignore adiabaticity, HUBO, bitflip, metaheuristic, fontweight, fontsize, QOBLIB, Zuse, Kochenberger, Tramontani, Weninger, edgecolor, nonumber */}\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "note",
      "metadata": {},
      "source": [
        "<Admonition type=\"note\" title=\"Nota\">\n",
        "  Qiskit Functions são um recurso experimental disponível apenas para usuários dos planos IBM Quantum® Premium Plan, Flex Plan e On-Prem (via IBM Quantum Platform API). Eles estão no status de versão prévia e estão sujeitos a alterações.\n",
        "</Admonition>\n",
        "\n",
        "*Estimativa de uso: 20 segundos em um processador Heron r2. (OBSERVAÇÃO: essa é apenas uma estimativa. Seu tempo de execução pode variar)*\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "background",
      "metadata": {},
      "source": [
        "<span id=\"background\" />\n",
        "\n",
        "## Segundo plano\n",
        "\n",
        "Este tutorial demonstra como resolver o problema de divisão de mercado usando [o otimizador quântico Iskay do Kipu Quantum](/docs/guides/kipu-optimization) [\\[1\\]](#references). O problema de divisão de mercado representa um desafio de alocação de recursos do mundo real em que os mercados devem ser divididos em regiões de vendas equilibradas para atender às metas exatas de demanda.\n",
        "\n",
        "<span id=\"the-market-split-challenge\" />\n",
        "\n",
        "### O desafio da divisão do mercado\n",
        "\n",
        "O problema de divisão de mercado apresenta um desafio aparentemente simples, mas computacionalmente formidável, na alocação de recursos. Considere uma empresa com $m$ produtos sendo vendidos em $n$ mercados diferentes, onde cada mercado compra um pacote específico de produtos (representado pelas colunas da matriz $A$ ). O objetivo comercial é dividir esses mercados em duas regiões de vendas equilibradas, de modo que cada região receba exatamente metade da demanda total de cada produto.\n",
        "\n",
        "**Formulação matemática:**\n",
        "\n",
        "Buscamos um vetor de atribuição binária $x$, onde:\n",
        "\n",
        "* $x_j = 1$ atribui o mercado $j$ à região A\n",
        "* $x_j = 0$ atribui o mercado $j$ à Região B\n",
        "* A restrição $Ax = b$ deve ser satisfeita, em que $b$ representa a meta de vendas (normalmente, metade da demanda total por produto)\n",
        "\n",
        "**Função de custo:**\n",
        "\n",
        "Para resolver esse problema, minimizamos a violação da restrição ao quadrado:\n",
        "\n",
        "$C(x) = ||Ax - b||^2 = \\sum_{i=1}^{m} \\left(\\sum_{j=1}^{n} A_{ij}x_j - b_i\\right)^2$\n",
        "\n",
        "em que:\n",
        "\n",
        "* $A_{ij}$ representa as vendas do produto $i$ no mercado $j$\n",
        "* $x_j \\in \\{0,1\\}$ é a atribuição binária de mercado $j$\n",
        "* $b_i$ é a meta de vendas do produto $i$ em cada região\n",
        "* O custo é igual a zero exatamente quando todas as restrições são satisfeitas\n",
        "\n",
        "Cada termo na soma representa o desvio quadrático da meta de vendas de um determinado produto. Quando expandimos essa função de custo, obtemos:\n",
        "\n",
        "$C(x) = x^T A^T A x - 2b^T A x + b^T b$\n",
        "\n",
        "Como $b^T b$ é uma constante, minimizar $C(x)$ é equivalente a minimizar a função quadrática $x^T A^T A x - 2b^T A x$, que é exatamente um problema QUBO (Quadratic Unconstrained Binary Optimization).\n",
        "\n",
        "**Complexidade computacional:**\n",
        "\n",
        "Apesar de sua interpretação comercial simples, esse problema apresenta uma notável intratabilidade computacional:\n",
        "\n",
        "* **Falha em pequena escala** : Os solucionadores convencionais de programação inteira mista falham em instâncias com apenas sete produtos em um tempo limite de uma hora [\\[4\\]](#references)\n",
        "* **Crescimento exponencial** : O espaço de solução cresce exponencialmente ( $2^n$ atribuições possíveis), tornando inviáveis as abordagens de força bruta\n",
        "\n",
        "Essa grave barreira computacional, combinada com sua relevância prática para o planejamento de territórios e a alocação de recursos, torna o problema de divisão de mercado uma referência ideal para algoritmos de otimização quântica [\\[4\\]](#references).\n",
        "\n",
        "<span id=\"what-makes-iskays-approach-unique\" />\n",
        "\n",
        "### O que torna a abordagem de Iskay única?\n",
        "\n",
        "O otimizador Iskay usa o algoritmo **bf-DCQO (bias-field digitized counterdiabatic quantum optimization)** [\\[1\\]](#references), que representa um avanço significativo na otimização quântica:\n",
        "\n",
        "**Eficiência do circuito** : O algoritmo bf-DCQO alcança uma notável redução de portas [\\[1\\]](#references) :\n",
        "\n",
        "* Até **10 vezes menos portas de emaranhamento** do que o Digital Quantum Annealing (DQA)\n",
        "* Possibilita circuitos significativamente mais rasos:\n",
        "  * Menor acúmulo de erros durante a execução quântica\n",
        "  * Capacidade de lidar com problemas maiores no hardware quântico atual\n",
        "  * Não há necessidade de técnicas de atenuação de erros\n",
        "\n",
        "**Projeto não variacional** : Ao contrário dos algoritmos variacionais que exigem aproximadamente 100 iterações, o bf-DCQO normalmente precisa de apenas **aproximadamente 10 iterações** [\\[1\\]](#references). Isso é realizado por meio de:\n",
        "\n",
        "* Cálculos inteligentes de campo de polarização a partir de distribuições de estados medidos\n",
        "* Iniciar cada iteração a partir de um estado de energia próximo à solução anterior\n",
        "* Pós-processamento clássico integrado com pesquisa local\n",
        "\n",
        "**Protocolos contra-diabáticos** : O algoritmo incorpora termos contra-diabáticos que suprimem excitações quânticas indesejadas durante curtos tempos de evolução, permitindo que o sistema permaneça próximo ao estado fundamental mesmo com transições rápidas [\\[1\\]](#references).\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "requirements",
      "metadata": {},
      "source": [
        "<span id=\"requirements\" />\n",
        "\n",
        "## Requisitos\n",
        "\n",
        "Antes de iniciar este tutorial, verifique se você tem os seguintes itens instalados:\n",
        "\n",
        "* Qiskit IBM Runtime (`pip install qiskit-ibm-runtime`)\n",
        "* Qiskit Functions (`pip install qiskit-ibm-catalog`)\n",
        "* NumPy (`pip install numpy`)\n",
        "* Solicitações (`pip install requests`)\n",
        "* Addon do Opt Mapper Qiskit (`pip install qiskit-addon-opt-mapper`)\n",
        "\n",
        "Você também precisará obter acesso à [função Iskay Quantum Optimizer](/functions?id=kipu-quantum-iskay-quantum-optimizer) no site Qiskit Functions Catalog.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "setup",
      "metadata": {},
      "source": [
        "<span id=\"setup\" />\n",
        "\n",
        "## Instalação\n",
        "\n",
        "Primeiro, importe todos os pacotes necessários para este tutorial.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "imports",
      "metadata": {},
      "outputs": [],
      "source": [
        "import os\n",
        "import tempfile\n",
        "import time\n",
        "from typing import Tuple, Optional\n",
        "\n",
        "import numpy as np\n",
        "import requests\n",
        "\n",
        "from qiskit_ibm_catalog import QiskitFunctionsCatalog\n",
        "\n",
        "from qiskit_addon_opt_mapper import OptimizationProblem\n",
        "from qiskit_addon_opt_mapper.converters import OptimizationProblemToQubo\n",
        "\n",
        "print(\"All required libraries imported successfully\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "credentials",
      "metadata": {},
      "source": [
        "<span id=\"configure-ibm-quantum-credentials\" />\n",
        "\n",
        "### Configurar credenciais d IBM Quantum\n",
        "\n",
        "Defina suas [IBM Quantum® Platform](/) credenciais. Você precisará de:\n",
        "\n",
        "* **Token de API** : Sua chave de API de 44 caracteres de IBM Quantum Platform\n",
        "* **CRN da instância** : Seu identificador de instância IBM Cloud®\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "creds",
      "metadata": {},
      "outputs": [],
      "source": [
        "token = \"<YOUR_API_KEY>\"\n",
        "instance = \"<YOUR_INSTANCE_CRN>\""
      ]
    },
    {
      "cell_type": "markdown",
      "id": "step1",
      "metadata": {},
      "source": [
        "<span id=\"step-1-map-classical-inputs-to-a-quantum-problem\" />\n",
        "\n",
        "## Passo 1: Mapear entradas clássicas para um problema quântico\n",
        "\n",
        "Começamos mapeando nosso problema clássico para uma representação compatível com o quantum. Essa etapa envolve:\n",
        "\n",
        "1. Conexão com o Iskay Quantum Optimizer\n",
        "2. Carregamento e formulação do problema de divisão de mercado\n",
        "3. Entendendo o algoritmo bf-DCQO que o resolverá\n",
        "\n",
        "<span id=\"connect-to-iskay-quantum-optimizer\" />\n",
        "\n",
        "### Conecte-se ao Iskay Quantum Optimizer\n",
        "\n",
        "Começamos estabelecendo uma conexão com o site Qiskit Functions Catalog e carregando o Iskay Quantum Optimizer. O Iskay Optimizer é uma função quântica fornecida pela Kipu Quantum que implementa o algoritmo bf-DCQO para resolver problemas de otimização em hardware quântico.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "load_solver",
      "metadata": {},
      "outputs": [],
      "source": [
        "catalog = QiskitFunctionsCatalog(token=token, instance=instance)\n",
        "iskay_solver = catalog.load(\"kipu-quantum/iskay-quantum-optimizer\")\n",
        "\n",
        "print(\"Iskay optimizer loaded successfully\")\n",
        "print(\"Ready to solve optimization problems using bf-DCQO algorithm\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "step2",
      "metadata": {},
      "source": [
        "<span id=\"load-and-formulate-the-problem\" />\n",
        "\n",
        "### Carregue e formule o problema\n",
        "\n",
        "<span id=\"understand-the-problem-data-format\" />\n",
        "\n",
        "#### Entenda o formato dos dados do problema\n",
        "\n",
        "As instâncias de problemas da QOBLIB (Quantum Optimization Benchmarking Library) [\\[2\\]](#references) são armazenadas em um formato de texto simples. Vamos examinar o conteúdo real de nossa instância de destino `ms_03_200_177.dat`:\n",
        "\n",
        "```text\n",
        "3 20\n",
        "60   92  161   53   97    2   75   81    6  139  132   45  108  112  181   93  152  200  164   51 1002\n",
        "176  196   41  143    2   88    0   79   10   71   75  148   82  135   34  187   33  155   58   46  879\n",
        "68   68  179  173  127  163   48   49   99   78   44   52  173  131   73  198   84  109  180   95 1040\n",
        "```\n",
        "\n",
        "**Estrutura do formato:**\n",
        "\n",
        "* **Primeira linha:** `3 20`\n",
        "  * `3` = número de produtos (restrições/linhas na matriz $A$ )\n",
        "  * `20` = número de mercados (variáveis/colunas na matriz $A$ )\n",
        "\n",
        "* **Próximas 3 linhas:** Matriz de coeficiente $A$ e vetor de destino $b$\n",
        "  * Cada linha tem 21 números: os primeiros 20 são coeficientes de linha, o último é o alvo\n",
        "  * Linha 2: `60 92 161 ... 51 | 1002`\n",
        "    * Primeiros 20 números: Quanto do Produto 1 cada um dos 20 mercados vende\n",
        "    * Último número (1002): Meta de vendas para o Produto 1 em uma região\n",
        "  * Linha 3: `176 196 41 ... 46 | 879`\n",
        "    * Vendas do produto 2 por mercado e meta (879)\n",
        "  * Linha 4: `68 68 179 ... 95 | 1040`\n",
        "    * Vendas do produto 3 por mercado e meta (1040)\n",
        "\n",
        "**Interpretação de negócios:**\n",
        "\n",
        "* O Mercado 0 vende: 60 unidades do Produto 1, 176 unidades do Produto 2, 68 unidades do Produto 3\n",
        "* O Mercado 1 vende: 92 unidades do Produto 1, 196 unidades do Produto 2, 68 unidades do Produto 3\n",
        "* E assim por diante para todos os 20 mercados...\n",
        "* **Meta** : Dividir esses 20 mercados em duas regiões em que cada região receba exatamente 1002 unidades do Produto 1, 879 unidades do Produto 2 e 1040 unidades do Produto 3\n",
        "\n",
        "<span id=\"qubo-transformation\" />\n",
        "\n",
        "#### Transformação QUBO\n",
        "\n",
        "<span id=\"from-constraints-to-qubo-the-mathematical-transformation\" />\n",
        "\n",
        "## Das restrições ao QUBO: a transformação matemática\n",
        "\n",
        "O poder da otimização quântica está na transformação de problemas com restrições em formas quadráticas sem restrições [\\[4\\]](#references). Para o problema de Market Split, convertemos as restrições de igualdade\n",
        "\n",
        "$Ax = b$\n",
        "\n",
        "onde $x ∈ \\{0,1\\}^n$, em um QUBO, penalizando as violações de restrições.\n",
        "\n",
        "**O método de penalidade:** Como precisamos que $Ax = b$ se mantenha exatamente, minimizamos a violação ao quadrado: $f(x) = ||Ax - b||^2$\n",
        "\n",
        "Isso é igual a zero exatamente quando todas as restrições são satisfeitas. Expandindo algebricamente: $f(x) = (Ax - b)^T(Ax - b) = x^T A^T A x - 2b^T A x + b^T b$\n",
        "\n",
        "**Objetivo do QUBO:** Como $b^T b$ é constante, nossa otimização se torna: $\\text{minimize} \\quad Q(x) = x^T(A^T A)x - 2(A^T b)^T x$\n",
        "\n",
        "**Principais percepções:** Essa transformação é exata, não aproximada. As restrições de igualdade se enquadram naturalmente na forma quadrática sem exigir variáveis auxiliares ou parâmetros de penalidade, o que torna essa formulação matematicamente elegante e computacionalmente eficiente para solucionadores quânticos [\\[4\\]](#references). Usaremos a classe `OptimizationProblem` para definir nosso problema restrito e, em seguida, convertê-lo para o formato QUBO usando `OptimizationProblemToQubo`, ambos do pacote **qiskit\\_addon\\_opt\\_mapper**. Isso lida automaticamente com a transformação baseada em penalidades.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "functions_intro",
      "metadata": {},
      "source": [
        "<span id=\"implement-data-loading-and-qubo-conversion-functions\" />\n",
        "\n",
        "### Implementar funções de carregamento de dados e conversão QUBO\n",
        "\n",
        "Agora definimos três funções de utilidade:\n",
        "\n",
        "1. `parse_marketsplit_dat()` - Analisa o formato de arquivo `.dat` e extrai as matrizes $A$ e $b$\n",
        "2. `fetch_marketsplit_data()` - Faz o download de instâncias de problemas diretamente do repositório QOBLIB\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "functions",
      "metadata": {},
      "outputs": [],
      "source": [
        "def parse_marketsplit_dat(filename: str) -> Tuple[np.ndarray, np.ndarray]:\n",
        "    \"\"\"\n",
        "    Parse a market split problem from a .dat file format.\n",
        "\n",
        "    Parameters\n",
        "    ----------\n",
        "    filename : str\n",
        "        Path to the .dat file containing the market split problem data.\n",
        "\n",
        "    Returns\n",
        "    -------\n",
        "    A : np.ndarray\n",
        "        Coefficient matrix of shape (m, n) where m is the number of products\n",
        "        and n is the number of markets.\n",
        "    b : np.ndarray\n",
        "        Target vector of shape (m,) containing the target sales per product.\n",
        "    \"\"\"\n",
        "    with open(filename, \"r\", encoding=\"utf-8\") as f:\n",
        "        lines = [\n",
        "            line.strip()\n",
        "            for line in f\n",
        "            if line.strip() and not line.startswith(\"#\")\n",
        "        ]\n",
        "\n",
        "    if not lines:\n",
        "        raise ValueError(\"Empty or invalid .dat file\")\n",
        "\n",
        "    # First line: m n (number of products and markets)\n",
        "    m, n = map(int, lines[0].split())\n",
        "\n",
        "    # Next m lines: each row of A followed by corresponding element of b\n",
        "    A, b = [], []\n",
        "    for i in range(1, m + 1):\n",
        "        values = list(map(int, lines[i].split()))\n",
        "        A.append(values[:-1])  # First n values: product sales per market\n",
        "        b.append(values[-1])  # Last value: target sales for this product\n",
        "\n",
        "    return np.array(A, dtype=np.int32), np.array(b, dtype=np.int32)\n",
        "\n",
        "\n",
        "def fetch_marketsplit_data(\n",
        "    instance_name: str = \"ms_03_200_177.dat\",\n",
        ") -> Tuple[Optional[np.ndarray], Optional[np.ndarray]]:\n",
        "    \"\"\"\n",
        "    Fetch market split data directly from the QOBLIB repository.\n",
        "\n",
        "    Parameters\n",
        "    ----------\n",
        "    instance_name : str\n",
        "        Name of the .dat file to fetch (default: \"ms_03_200_177.dat\").\n",
        "\n",
        "    Returns\n",
        "    -------\n",
        "    A : np.ndarray or None\n",
        "        Coefficient matrix if successful, None if failed.\n",
        "    b : np.ndarray or None\n",
        "        Target vector if successful, None if failed.\n",
        "    \"\"\"\n",
        "    url = f\"https://git.zib.de/qopt/qoblib-quantum-optimization-benchmarking-library/-/raw/main/01-marketsplit/instances/{instance_name}\"\n",
        "\n",
        "    try:\n",
        "        response = requests.get(url, timeout=30)\n",
        "        response.raise_for_status()\n",
        "\n",
        "        with tempfile.NamedTemporaryFile(\n",
        "            mode=\"w\", suffix=\".dat\", delete=False, encoding=\"utf-8\"\n",
        "        ) as f:\n",
        "            f.write(response.text)\n",
        "            temp_path = f.name\n",
        "\n",
        "        try:\n",
        "            return parse_marketsplit_dat(temp_path)\n",
        "        finally:\n",
        "            os.unlink(temp_path)\n",
        "    except Exception as e:\n",
        "        print(f\"Error: {e}\")\n",
        "        return None, None"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "load_intro",
      "metadata": {},
      "source": [
        "<span id=\"load-the-problem-instance\" />\n",
        "\n",
        "### Carregar a instância do problema\n",
        "\n",
        "Agora carregamos a instância específica do problema `ms_03_200_177.dat` do QOBLIB \\[2]. Essa instância tem:\n",
        "\n",
        "* 3 produtos (restrições)\n",
        "* 20 mercados (variáveis de decisão binárias)\n",
        "* Mais de 1 milhão de possíveis atribuições de mercado para explorar ( $2^{20} = 1,048,576$ )\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "load",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Load the problem instance\n",
        "instance_name = \"ms_03_200_177.dat\"\n",
        "A, b = fetch_marketsplit_data(instance_name=instance_name)\n",
        "\n",
        "if A is not None:\n",
        "    print(\"Successfully loaded problem instance from QOBLIB\")\n",
        "    print(\"\\nProblem Instance Analysis:\")\n",
        "    print(\"=\" * 50)\n",
        "    print(f\"Coefficient Matrix A: {A.shape[0]} × {A.shape[1]}\")\n",
        "    print(f\"   → {A.shape[0]} products (constraints)\")\n",
        "    print(f\"   → {A.shape[1]} markets (decision variables)\")\n",
        "    print(f\"Target Vector b: {b}\")\n",
        "    print(\"   → Target sales per product for each region\")\n",
        "    print(\n",
        "        f\"Solution Space: \"\n",
        "        f\"2^{A.shape[1]} = {2**A.shape[1]:,} possible assignments\"\n",
        "    )"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "convert_intro",
      "metadata": {},
      "source": [
        "<span id=\"convert-to-qubo-format\" />\n",
        "\n",
        "### Converter para o formato QUBO\n",
        "\n",
        "Agora, transformamos o problema de otimização com restrições no formato QUBO:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "convert",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Create optimization problem\n",
        "ms = OptimizationProblem(instance_name.replace(\".dat\", \"\"))\n",
        "\n",
        "# Add binary variables (one for each market)\n",
        "ms.binary_var_list(A.shape[1])\n",
        "\n",
        "# Add equality constraints (one for each product)\n",
        "for idx, rhs in enumerate(b):\n",
        "    ms.linear_constraint(A[idx, :], sense=\"==\", rhs=rhs)\n",
        "\n",
        "# Convert to QUBO with penalty parameter\n",
        "qubo = OptimizationProblemToQubo(penalty=1).convert(ms)\n",
        "\n",
        "print(\"QUBO Conversion Complete:\")\n",
        "print(\"=\" * 50)\n",
        "print(f\"Number of variables: {qubo.get_num_vars()}\")\n",
        "print(f\"Constant term: {qubo.objective.constant}\")\n",
        "print(f\"Linear terms: {len(qubo.objective.linear.to_dict())}\")\n",
        "print(f\"Quadratic terms: {len(qubo.objective.quadratic.to_dict())}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1d307072",
      "metadata": {},
      "source": [
        "<span id=\"convert-qubo-to-iskay-format\" />\n",
        "\n",
        "### Converter QUBO para o formato Iskay\n",
        "\n",
        "Agora precisamos converter o objeto QUBO no formato de dicionário exigido pelo Iskay Optimizer da Kipu Quantum.\n",
        "\n",
        "Os argumentos `problem` e `problem_type` codificam um problema de otimização da forma\n",
        "\n",
        "$$\n",
        "\\begin{align}\n",
        "\\min_{(x_1, x_2, \\ldots, x_n) \\in D} C(x_1, x_2, \\ldots, x_n) \\nonumber\n",
        "\\end{align}\n",
        "$$\n",
        "\n",
        "em que\n",
        "\n",
        "$$\n",
        "C(x_1, ... , x_n) = a + \\sum_{i} b_i x_i + \\sum_{i, j} c_{i, j} x_i x_j + ... + \\sum_{k_1, ..., k_m} g_{k_1, ..., k_m} x_{k_1} ... x_{k_m}\n",
        "$$\n",
        "\n",
        "* Ao escolher `problem_type = \"binary\"`, você especifica que a função de custo está no formato `binary` , o que significa que $D = \\{0,  1\\}^{n}$, como em, a função de custo é escrita na formulação QUBO/HUBO.\n",
        "* Por outro lado, ao escolher `problem_type = \"spin\"`, a função de custo é escrita na formulação de Ising, onde $D = \\{-1, 1\\}^{n}$.\n",
        "\n",
        "Os coeficientes do problema devem ser codificados em um dicionário da seguinte forma:\n",
        "\n",
        "$$\n",
        "\\begin{align} \\nonumber\n",
        "&\\texttt{\\{} \\\\ \\nonumber\n",
        "&\\texttt{\"()\"}&: \\quad &a, \\\\ \\nonumber\n",
        "&\\texttt{\"(i,)\"}&: \\quad &b_i, \\\\ \\nonumber\n",
        "&\\texttt{\"(i, j)\"}&: \\quad &c_{i, j}, \\quad (i \\neq j) \\\\ \\nonumber\n",
        "&\\quad  \\vdots \\\\ \\nonumber\n",
        "&\\texttt{\"(} k_1, ..., k_m  \\texttt{)\"}&: \\quad &g_{k_1, ..., k_m}, \\quad (k_1 \\neq k_2 \\neq \\dots \\neq k_m) \\\\ \\nonumber\n",
        "&\\texttt{\\}}\n",
        "\\end{align}\n",
        "$$\n",
        "\n",
        "Observe que as chaves do dicionário devem ser cadeias de caracteres que contenham uma tupla válida de números inteiros não repetidos. Para problemas binários, sabemos que:\n",
        "\n",
        "$$\n",
        "x_i^2 = x_i\n",
        "$$\n",
        "\n",
        "para $i=j$ (já que $x_i \\in \\{0,1\\}$ significa $x_i \\cdot x_i = x_i$ ). Portanto, em sua formulação QUBO, se você tiver contribuições lineares $b_i x_i$ e contribuições quadráticas diagonais $c_{i,i} x_i^2$, esses termos deverão ser combinados em um único coeficiente linear:\n",
        "\n",
        "**Coeficiente linear total para a variável $x_i$** : $b_i + c_{i,i}$\n",
        "\n",
        "Ou seja:\n",
        "\n",
        "* Termos lineares como `\"(i, )\"` contêm: coeficiente linear original + coeficiente quadrático diagonal\n",
        "* Termos quadráticos diagonais como `\"(i, i)\"` **NÃO** devem aparecer no dicionário final\n",
        "* Somente os termos quadráticos fora da diagonal, como `\"(i, j)\"` onde $i \\neq j$, devem ser incluídos como entradas separadas\n",
        "\n",
        "**Exemplo:** Se seu QUBO tiver $3x_1 + 2x_1^2 + 4x_1 x_2$, o dicionário Iskay deverá conter:\n",
        "\n",
        "* `\"(0, )\"`: `5.0` (combinando $3 + 2 = 5$ )\n",
        "* `\"(0, 1)\"`: `4.0` (termo fora da diagonal)\n",
        "\n",
        "**NÃO há** entradas separadas para `\"(0, )\"`: `3.0` e `\"(0, 0)\"`: `2.0`.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "57eda6fd",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Convert QUBO to Iskay dictionary format:\n",
        "\n",
        "# Create empty Iskay input dictionary\n",
        "iskay_input_problem = {}\n",
        "\n",
        "# Convert QUBO to Iskay dictionary format\n",
        "iskay_input_problem = {\"()\": qubo.objective.constant}\n",
        "\n",
        "for i in range(qubo.get_num_vars()):\n",
        "    for j in range(i, qubo.get_num_vars()):\n",
        "        if i == j:\n",
        "            # Add linear term (including diagonal quadratic contribution)\n",
        "            iskay_input_problem[f\"({i}, )\"] = float(\n",
        "                qubo.objective.linear.to_dict().get(i)\n",
        "            ) + float(qubo.objective.quadratic.to_dict().get((i, i)))\n",
        "        else:\n",
        "            # Add off-diagonal quadratic term\n",
        "            iskay_input_problem[f\"({i}, {j})\"] = float(\n",
        "                qubo.objective.quadratic.to_dict().get((i, j))\n",
        "            )\n",
        "\n",
        "# Display Iskay dictionary summary\n",
        "print(\"Iskay Dictionary Format:\")\n",
        "print(\"=\" * 50)\n",
        "print(f\"Total coefficients: {len(iskay_input_problem)}\")\n",
        "print(f\"  • Constant term: {iskay_input_problem['()']}\")\n",
        "print(\n",
        "    f\"  • Linear terms: \"\n",
        "    f\"{sum(1 for k in iskay_input_problem.keys() if k != '()' and ', )' in k)}\"\n",
        ")\n",
        "print(\n",
        "    f\"  • Quadratic terms: \"\n",
        "    f\"{sum(1 for k in iskay_input_problem.keys() if k != '()' and ', )' not in k)}\"\n",
        ")\n",
        "print(\"\\nSample coefficients:\")\n",
        "\n",
        "# Get first 10 and last 5 items properly\n",
        "items = list(iskay_input_problem.items())\n",
        "first_10 = list(enumerate(items[:10]))\n",
        "last_5 = list(enumerate(items[-5:], start=len(items) - 5))\n",
        "\n",
        "for i, (key, value) in first_10 + last_5:\n",
        "    coeff_type = (\n",
        "        \"constant\"\n",
        "        if key == \"()\"\n",
        "        else \"linear\"\n",
        "        if \", )\" in key\n",
        "        else \"quadratic\"\n",
        "    )\n",
        "    print(f\"  {key}: {value} ({coeff_type})\")\n",
        "print(\"  ...\")\n",
        "print(\"\\n✓ Problem ready for Iskay optimizer!\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "step3",
      "metadata": {},
      "source": [
        "<span id=\"understand-the-bf-dcqo-algorithm\" />\n",
        "\n",
        "### Entenda o algoritmo bf-DCQO\n",
        "\n",
        "Antes de executarmos a otimização, vamos entender o sofisticado algoritmo quântico que alimenta o Iskay: **bf-DCQO (bias-field digitized counterdiabatic quantum optimization)** [\\[1\\]](#references).\n",
        "\n",
        "<span id=\"what-is-bf-dcqo\" />\n",
        "\n",
        "#### O que é bf-DCQO?\n",
        "\n",
        "o bf-DCQO é baseado na evolução temporal de um sistema quântico em que a solução do problema é codificada no **estado fundamental** (estado de energia mais baixa) do Hamiltoniano quântico final [\\[1\\]](#references). O algoritmo aborda um desafio fundamental na otimização quântica:\n",
        "\n",
        "**O desafio** : a computação quântica adiabática tradicional exige uma evolução muito lenta para manter as condições do estado fundamental de acordo com o teorema adiabático. Isso exige circuitos quânticos cada vez mais profundos à medida que a complexidade do problema aumenta, levando a mais operações de porta e erros acumulados.\n",
        "\n",
        "**A solução** : o bf-DCQO usa protocolos contra-diabáticos para permitir uma evolução rápida e, ao mesmo tempo, manter a fidelidade do estado fundamental, reduzindo drasticamente a profundidade do circuito.\n",
        "\n",
        "<span id=\"mathematical-framework\" />\n",
        "\n",
        "#### Estrutura matemática\n",
        "\n",
        "O algoritmo minimiza uma função de custo do tipo:\n",
        "\n",
        "$\\min_{(x_1,x_2,...,x_n) \\in D} C(x_1,x_2,...,x_n)$\n",
        "\n",
        "em que $D = \\{0,1\\}^n$ para variáveis binárias e:\n",
        "\n",
        "$C(x) = a + \\sum_i b_i x_i + \\sum_{i,j} c_{ij} x_i x_j + ... + \\sum g_{k_1,...,k_m} x_{k_1}...x_{k_m}$\n",
        "\n",
        "Para nosso problema de divisão de mercado, a função de custo é:\n",
        "\n",
        "$C(x) = ||Ax - b||^2 = x^T A^T A x - 2 b^T A x + b^T b$\n",
        "\n",
        "<span id=\"the-role-of-counterdiabatic-terms\" />\n",
        "\n",
        "#### O papel dos termos antidiabéticos\n",
        "\n",
        "**Os termos contra-diabáticos** são termos adicionais introduzidos no Hamiltoniano dependente do tempo que suprimem as excitações indesejadas durante a evolução quântica. Veja por que eles são cruciais:\n",
        "\n",
        "Na otimização quântica adiabática, evoluímos o sistema de acordo com um Hamiltoniano dependente do tempo:\n",
        "\n",
        "$H(t) = \\left(1 - \\frac{t}{T}\\right) H_{\\text{initial}} + \\frac{t}{T} H_{\\text{problem}}$\n",
        "\n",
        "em que $H_{\\text{problem}}$ codifica nosso problema de otimização. Para manter o estado fundamental durante a evolução rápida, adicionamos termos contra-diabáticos:\n",
        "\n",
        "$H_{\\text{CD}}(t) = H(t) + H_{\\text{counter}}(t)$\n",
        "\n",
        "Esses termos contra-diabáticos fazem o seguinte:\n",
        "\n",
        "1. **Suprimir transições indesejadas** : Impedir que o estado quântico salte para estados excitados durante a evolução rápida\n",
        "2. **Permitir tempos de evolução mais curtos** : Permite que alcancemos o estado final muito mais rapidamente sem violar a adiabaticidade\n",
        "3. **Reduzir a profundidade do circuito** : Uma evolução mais curta leva a menos portas e menos erros\n",
        "\n",
        "O impacto prático é significativo: o bf-DCQO usa até **10 vezes menos portas de emaranhamento** do que o Digital Quantum Annealing [\\[1\\]](#references), o que o torna prático para o hardware quântico ruidoso atual.\n",
        "\n",
        "<span id=\"bias-field-iterative-optimization\" />\n",
        "\n",
        "#### Otimização iterativa do campo de viés\n",
        "\n",
        "Diferentemente dos algoritmos variacionais que otimizam os parâmetros do circuito por meio de muitas iterações, o bf-DCQO usa uma **abordagem guiada por campo de polarização** que converge em aproximadamente 10 iterações \\[1] :\n",
        "\n",
        "**Processo de iteração:**\n",
        "\n",
        "1. **Evolução quântica inicial** : Comece com um circuito quântico implementando o protocolo de evolução contra-diabática\n",
        "\n",
        "2. **Medição** : Medir o estado quântico para obter uma distribuição de probabilidade sobre cadeias de bits\n",
        "\n",
        "3. **Cálculo do campo de polarização** : Analise as estatísticas de medição e calcule um campo de polarização ideal $h_i$ para cada qubit: $h_i = \\text{f}(\\text{measurement statistics}, \\text{previous solutions})$\n",
        "\n",
        "4. **Próxima iteração** : O campo de polarização modifica o Hamiltoniano para a próxima iteração: $H_{\\text{next}} = H_{\\text{problem}} + \\sum_i h_i \\sigma_i^z$\n",
        "\n",
        "   Isso permite começar perto da boa solução encontrada anteriormente, realizando efetivamente uma forma de \"pesquisa local quântica\"\n",
        "\n",
        "5. **Convergência** : Repetir até que a qualidade da solução se estabilize ou até que um número máximo de iterações seja atingido\n",
        "\n",
        "**Principal vantagem** : Cada iteração proporciona um progresso significativo em direção à solução ideal ao incorporar informações de medições anteriores, ao contrário dos métodos variacionais que precisam explorar o espaço de parâmetros às cegas.\n",
        "\n",
        "<span id=\"integrated-classical-post-processing\" />\n",
        "\n",
        "#### Pós-processamento clássico integrado\n",
        "\n",
        "Após a convergência da otimização quântica, o Iskay realiza o pós-processamento clássico **de pesquisa local** :\n",
        "\n",
        "* **Exploração de inversão de bits** : Inverter sistemática ou aleatoriamente os bits na melhor solução medida\n",
        "* **Avaliação de energia** : Calcular $C(x)$ para cada solução modificada\n",
        "* **Seleção inteligente** : Aceitar melhorias que reduzam a função de custo\n",
        "* **Múltiplas passagens** : Executar várias passagens (controladas por `postprocessing_level`)\n",
        "\n",
        "Essa abordagem híbrida compensa os erros de inversão de bits causados por imperfeições de hardware e erros de leitura, garantindo soluções de alta qualidade mesmo em dispositivos quânticos com ruído.\n",
        "\n",
        "<span id=\"why-bf-dcqo-excels-on-current-hardware\" />\n",
        "\n",
        "#### Por que o bf-DCQO se destaca no hardware atual\n",
        "\n",
        "O algoritmo bf-DCQO foi projetado especificamente para se destacar nos dispositivos quânticos atuais de escala intermediária e ruidosa (NISQ) [\\[1\\]](#references) :\n",
        "\n",
        "1. **Resiliência a erros** : Menos portas (redução de 10 vezes) significa muito menos acúmulo de erros\n",
        "2. **Não é necessária a mitigação de erros** : A eficiência inerente do algoritmo elimina a necessidade de técnicas caras de atenuação de erros [\\[1\\]](#references)\n",
        "3. **Escalabilidade** : Pode lidar com problemas de até 156 qubits (156 variáveis binárias) com mapeamento direto de qubits [\\[1\\]](#references)\n",
        "4. **Desempenho comprovado** : Atinge taxas de aproximação de 100% nas instâncias de referência MaxCut e HUBO [\\[1\\]](#references)\n",
        "\n",
        "Agora vamos ver esse poderoso algoritmo em ação em nosso problema de divisão de mercado!\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "step4",
      "metadata": {},
      "source": [
        "<span id=\"step-2-optimize-problem-for-quantum-hardware-execution\" />\n",
        "\n",
        "## Etapa 2: Otimizar o problema para execução em hardware quântico\n",
        "\n",
        "O algoritmo bf-DCQO lida automaticamente com a otimização de circuitos, criando circuitos quânticos rasos com termos contra-diabáticos projetados especificamente para o backend de destino.\n",
        "\n",
        "<span id=\"configure-the-optimization\" />\n",
        "\n",
        "### Configure a otimização\n",
        "\n",
        "O Iskay Optimizer requer vários parâmetros-chave para resolver efetivamente seu problema de otimização. Vamos examinar cada parâmetro e sua função no processo de otimização quântica:\n",
        "\n",
        "<span id=\"required-parameters\" />\n",
        "\n",
        "#### Parâmetros necessários\n",
        "\n",
        "| Parâmetro          | Tipo               | Descrição                                                             | Exemplo                                     |\n",
        "| ------------------ | ------------------ | --------------------------------------------------------------------- | ------------------------------------------- |\n",
        "| **problema**       | `Dict[str, float]` | Coeficientes QUBO em formato de chave de cadeia                       | `{\"()\": -21.0, \"(0,4)\": 0.5, \"(0,1)\": 0.5}` |\n",
        "| **problema\\_tipo** | `str`              | Especificação do formato: `\"binary\"` para QUBO ou `\"spin\"` para Ising | `\"binary\"`                                  |\n",
        "| **backend\\_name**  | `str`              | Dispositivo quântico alvo                                             | `\"ibm_fez\"`                                 |\n",
        "\n",
        "<span id=\"essential-concepts\" />\n",
        "\n",
        "#### Conceitos essenciais\n",
        "\n",
        "* **Formato do problema** : Usamos o site `\"binary\"` , pois nossas variáveis são binárias (0/1), representando atribuições de mercado.\n",
        "* **Seleção de back-end** : Escolha entre as QPUs disponíveis (por exemplo, `\"ibm_fez\"`) com base em suas necessidades e na instância do recurso de computação.\n",
        "* **Estrutura QUBO** : Nosso dicionário de problemas contém os coeficientes exatos da transformação matemática.\n",
        "\n",
        "<span id=\"advanced-options-optional\" />\n",
        "\n",
        "#### Opções avançadas (opcional)\n",
        "\n",
        "O Iskay oferece recursos de ajuste fino por meio de parâmetros opcionais. Embora os padrões funcionem bem para a maioria dos problemas, você pode personalizar o comportamento para atender a requisitos específicos:\n",
        "\n",
        "| Parâmetro                   | Tipo        | Padrão | Descrição                                                                     |\n",
        "| --------------------------- | ----------- | ------ | ----------------------------------------------------------------------------- |\n",
        "| **Tentativas**              | `int`       | 10000  | Medições quânticas por iteração (maior = mais preciso)                        |\n",
        "| **num\\_iterações**          | `int`       | 22     | Iterações do algoritmo (mais iterações podem melhorar a qualidade da solução) |\n",
        "| **usar\\_sessão**            | `bool`      | Sim    | Use sessões IBM para reduzir o tempo de fila                                  |\n",
        "| **semente\\_transpilador**   | `int`       | Nenhum | Conjunto para compilação reproduzível de circuitos quânticos                  |\n",
        "| **direct\\_qubit\\_mapping**  | `bool`      | Não    | Mapear os qubits virtuais diretamente para os qubits físicos                  |\n",
        "| **trabalho\\_tags**          | `List[str]` | Nenhum | Tags personalizadas para rastreamento de trabalhos                            |\n",
        "| **pré-processamento\\nível** | `int`       | 0      | Intensidade de pré-processamento do problema (0-3) - veja detalhes abaixo     |\n",
        "| **pós-processamento\\nível** | `int`       | 2      | Nível de refinamento da solução (0-2) - veja detalhes abaixo                  |\n",
        "| **transpilação\\_nível**     | `int`       | 0      | Testes de otimização do transpilador (0-5) - veja detalhes abaixo             |\n",
        "| **transpile\\_only**         | `bool`      | Não    | Analise a otimização do circuito sem executar a execução completa             |\n",
        "\n",
        "**Níveis de pré-processamento (0-3)** : Especialmente importante para problemas maiores que não cabem no momento nos tempos de coerência do hardware. Níveis mais altos de pré-processamento atingem profundidades de circuito mais rasas por meio de aproximações na transpilação do problema:\n",
        "\n",
        "* **Nível 0** : Circuitos exatos e mais longos\n",
        "* **Nível 1** : Bom equilíbrio entre precisão e aproximação, cortando apenas os portões com ângulos no percentil 10 mais baixo\n",
        "* **Nível 2** : Aproximação um pouco maior, cortando os portões com ângulos no percentil 20 mais baixo e usando `approximation_degree=0.95` na transpilação\n",
        "* **Nível 3** : Nível máximo de aproximação, cortando os portões no percentil 30 mais baixo e usando `approximation_degree=0.90` na transpilação\n",
        "\n",
        "**Níveis de transpilação (0-5)** : Controle os testes avançados de otimização do transpilador para compilação de circuitos quânticos. Isso pode levar a um aumento na sobrecarga clássica e, em alguns casos, pode não alterar a profundidade do circuito. O valor padrão `2` em geral leva ao menor circuito e é relativamente rápido.\n",
        "\n",
        "* **Nível 0** : otimização do circuito DCQO decomposto (layout, roteamento, programação)\n",
        "* **Nível 1** : Otimização do site `PauliEvolutionGate` e, em seguida, do circuito DCQO decomposto ( max\\_trials=10 )\n",
        "* **Nível 2** : otimização do site `PauliEvolutionGate` e, em seguida, do circuito DCQO decomposto ( max\\_trials=15 )\n",
        "* **Nível 3** : otimização do site `PauliEvolutionGate` e, em seguida, do circuito DCQO decomposto ( max\\_trials=20 )\n",
        "* **Nível 4** : otimização de `PauliEvolutionGate` e, em seguida, o circuito DCQO decomposto ( max\\_trials=25 )\n",
        "* **Nível 5** : Otimização do site `PauliEvolutionGate` e, em seguida, do circuito DCQO decomposto ( max\\_trials=50 )\n",
        "\n",
        "**Níveis de pós-processamento (0-2)** : Controle a quantidade de otimização clássica, compensando os erros de inversão de bits com um número diferente de passagens gananciosas de uma pesquisa local:\n",
        "\n",
        "* **Nível 0** : 1 passe\n",
        "* **Nível 1** : 2 passes\n",
        "* **Nível 2** : 3 passes\n",
        "\n",
        "**Modo somente transpile** : Agora disponível para usuários que desejam analisar a otimização do circuito sem executar o algoritmo quântico completo.\n",
        "\n",
        "<span id=\"custom-configuration-example\" />\n",
        "\n",
        "#### Exemplo de configuração personalizada\n",
        "\n",
        "Veja como você pode configurar o Iskay com diferentes definições:\n",
        "\n",
        "```python\n",
        "custom_options = {\n",
        "    # Higher shot count for better statistics\n",
        "    \"shots\": 15_000,\n",
        "\n",
        "    # More iterations for solution refinement\n",
        "    \"num_iterations\": 12,\n",
        "\n",
        "    # Light preprocessing for problem simplification\n",
        "    \"preprocessing_level\": 1,\n",
        "\n",
        "    # Maximum postprocessing for solution quality\n",
        "    \"postprocessing_level\": 2,\n",
        "\n",
        "    # Using higher transpilation level for circuit optimization\n",
        "    \"transpilation_level\": 3,\n",
        "\n",
        "    # Fixed seed for reproducible results\n",
        "    \"seed_transpiler\": 42,\n",
        "\n",
        "    # Custom tracking tags\n",
        "    \"job_tags\": [\"market_split\"]\n",
        "}\n",
        "```\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "86e2b10d",
      "metadata": {},
      "source": [
        "Para este tutorial, manteremos a maioria dos parâmetros padrão e alteraremos apenas o número de iterações do campo de polarização:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "config",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Specify the target backend\n",
        "backend_name = \"ibm_fez\"\n",
        "\n",
        "# Set the number of bias-field iterations and set a tag to identify the jobs\n",
        "options = {\n",
        "    \"num_iterations\": 3,  # Change number of bias-field iterations\n",
        "    \"job_tags\": [\"market_split_example\"],  # Tag to identify jobs\n",
        "}\n",
        "\n",
        "# Configure Iskay optimizer\n",
        "iskay_input = {\n",
        "    \"problem\": iskay_input_problem,\n",
        "    \"problem_type\": \"binary\",\n",
        "    \"backend_name\": backend_name,\n",
        "    \"options\": options,\n",
        "}\n",
        "\n",
        "print(\"Iskay Optimizer Configuration:\")\n",
        "print(\"=\" * 40)\n",
        "print(f\"  Backend: {backend_name}\")\n",
        "print(f\"  Problem: {len(iskay_input['problem'])} terms\")\n",
        "print(\"  Algorithm: bf-DCQO\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "submit_intro",
      "metadata": {},
      "source": [
        "<span id=\"step-3-execute-using-qiskit-primitives\" />\n",
        "\n",
        "## Passo 3: Execute usando Qiskit primitives\n",
        "\n",
        "Agora enviamos nosso problema para ser executado no hardware IBM Quantum. O algoritmo bf-DCQO irá:\n",
        "\n",
        "1. Construir circuitos quânticos rasos com termos contra-diabáticos\n",
        "2. Execute aproximadamente 10 iterações com otimização de campo de polarização\n",
        "3. Realizar o pós-processamento clássico com pesquisa local\n",
        "4. Retornar a atribuição de mercado ideal\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "run",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Submit the optimization job\n",
        "print(\"Submitting optimization job to Kipu Quantum...\")\n",
        "print(\n",
        "    f\"Problem size: {A.shape[1]} variables, {len(iskay_input['problem'])} terms\"\n",
        ")\n",
        "print(\n",
        "    \"Algorithm: bf-DCQO (bias-field digitized counterdiabatic quantum optimization)\"\n",
        ")\n",
        "\n",
        "job = iskay_solver.run(**iskay_input)\n",
        "\n",
        "print(\"\\nJob successfully submitted!\")\n",
        "print(f\"Job ID: {job.job_id}\")\n",
        "print(\"Optimization in progress...\")\n",
        "print(\n",
        "    f\"The bf-DCQO algorithm will efficiently explore \"\n",
        "    f\"{2**A.shape[1]:,} possible assignments\"\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "status_intro",
      "metadata": {},
      "source": [
        "<span id=\"monitor-job-status\" />\n",
        "\n",
        "### Monitorar o status da tarefa\n",
        "\n",
        "Você pode verificar o status atual do seu trabalho de otimização. Os status possíveis são:\n",
        "\n",
        "* `QUEUED`: O trabalho está aguardando na fila\n",
        "* `RUNNING`: O trabalho está sendo executado atualmente no hardware quântico\n",
        "* `DONE`: Trabalho concluído com êxito\n",
        "* `CANCELED`: O trabalho foi cancelado\n",
        "* `ERROR`: O trabalho encontrou um erro\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "status",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Check job status\n",
        "print(f\"Job status: {job.status()}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "wait_intro",
      "metadata": {},
      "source": [
        "<span id=\"wait-for-completion\" />\n",
        "\n",
        "### Aguarde a conclusão\n",
        "\n",
        "Essa célula será bloqueada até que o trabalho seja concluído. O processo de otimização inclui:\n",
        "\n",
        "* Tempo de fila (aguardando acesso ao hardware quântico)\n",
        "* Tempo de execução (executando o algoritmo bf-DCQO com aproximadamente 10 iterações)\n",
        "* Tempo de pós-processamento (pesquisa local clássica)\n",
        "\n",
        "Os tempos de conclusão típicos variam de alguns minutos a dezenas de minutos, dependendo das condições da fila.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "wait",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Wait for job completion\n",
        "while True:\n",
        "    status = job.status()\n",
        "    print(\n",
        "        f\"Waiting for job {job.job_id} to complete... (status: {status})\",\n",
        "        end=\"\\r\",\n",
        "        flush=True,\n",
        "    )\n",
        "    if status in [\"DONE\", \"CANCELED\", \"ERROR\"]:\n",
        "        print(\n",
        "            f\"\\nJob {job.job_id} completed with status: {status}\" + \" \" * 20\n",
        "        )\n",
        "        break\n",
        "    time.sleep(30)\n",
        "\n",
        "# Retrieve the optimization results\n",
        "result = job.result()\n",
        "print(\"\\nOptimization complete!\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "step5",
      "metadata": {},
      "source": [
        "<span id=\"step-4-post-process-and-return-result-in-desired-classical-format\" />\n",
        "\n",
        "## Etapa 4: Pós-processamento e retorno do resultado no formato clássico desejado\n",
        "\n",
        "Agora, fazemos o pós-processamento dos resultados da execução quântica. Isso inclui:\n",
        "\n",
        "* Análise da estrutura da solução\n",
        "* Validação da satisfação das restrições\n",
        "* Avaliação comparativa com abordagens clássicas\n",
        "\n",
        "<span id=\"analyze-results\" />\n",
        "\n",
        "### Analisar resultados\n",
        "\n",
        "<span id=\"understand-the-result-structure\" />\n",
        "\n",
        "#### Entenda a estrutura do resultado\n",
        "\n",
        "O Iskay retorna um dicionário de resultados abrangente que contém:\n",
        "\n",
        "* **`solution`**: Um dicionário que mapeia os índices de variáveis para seus valores ideais (0 ou 1)\n",
        "* **`solution_info`**: Informações detalhadas, incluindo:\n",
        "  * `bitstring`: A atribuição ideal como uma string binária\n",
        "  * `cost`: O valor da função objetiva (deve ser 0 para satisfação perfeita das restrições)\n",
        "  * `mapping`: Como as posições de bitstring são mapeadas para as variáveis do problema\n",
        "  * `seed_transpiler`: Semente usada para reprodutibilidade\n",
        "* **`prob_type`**: Se a solução está em formato binário ou spin\n",
        "\n",
        "Vamos examinar a solução retornada pelo otimizador quântico.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "results",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Display the optimization results\n",
        "print(\"Optimization Results\")\n",
        "print(\"=\" * 50)\n",
        "print(f\"Problem Type: {result['prob_type']}\")\n",
        "print(\"\\nSolution Info:\")\n",
        "print(f\"  Bitstring: {result['solution_info']['bitstring']}\")\n",
        "print(f\"  Cost: {result['solution_info']['cost']}\")\n",
        "print(\"\\nSolution (first 10 variables):\")\n",
        "for i, (var, val) in enumerate(list(result[\"solution\"].items())[:10]):\n",
        "    print(f\"  {var}: {val}\")\n",
        "print(\"  ...\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "validation_intro",
      "metadata": {},
      "source": [
        "<span id=\"solution-validation\" />\n",
        "\n",
        "#### Validação de solução\n",
        "\n",
        "Agora, validamos se a solução quântica satisfaz as restrições do Market Split. O processo de validação verifica:\n",
        "\n",
        "**O que é uma violação de restrição?**\n",
        "\n",
        "* Para cada produto $i$, calculamos as vendas reais na Região A: $(Ax)_i$\n",
        "* Comparamos isso com a meta de vendas $b_i$\n",
        "* A **violação** é a diferença absoluta: $|(Ax)_i - b_i|$\n",
        "* Uma **solução viável** tem zero violações para todos os produtos\n",
        "\n",
        "**O que esperamos:**\n",
        "\n",
        "* **Caso ideal** : Violação total = 0 (todas as restrições perfeitamente satisfeitas)\n",
        "  * A região A recebe exatamente 1002 unidades do Produto 1, 879 unidades do Produto 2 e 1040 unidades do Produto 3\n",
        "  * A região B recebe as unidades restantes (também 1002, 879 e 1040, respectivamente)\n",
        "* **Bom caso** : A violação total é pequena (solução quase ideal)\n",
        "* **Caso ruim** : Grandes violações indicam que a solução não atende aos requisitos comerciais\n",
        "\n",
        "A função de validação será computada:\n",
        "\n",
        "1. Vendas reais por produto em cada região\n",
        "2. Violações de restrições para cada produto\n",
        "3. Distribuição do mercado entre as regiões\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "validate",
      "metadata": {},
      "outputs": [],
      "source": [
        "def validate_solution(A, b, solution):\n",
        "    \"\"\"Validate market split solution.\"\"\"\n",
        "    x = np.array(solution)\n",
        "    region_a = A @ x\n",
        "    region_b = A @ (1 - x)\n",
        "    violations = np.abs(region_a - b)\n",
        "\n",
        "    return {\n",
        "        \"target\": b,\n",
        "        \"region_a\": region_a,\n",
        "        \"region_b\": region_b,\n",
        "        \"violations\": violations,\n",
        "        \"total_violation\": np.sum(violations),\n",
        "        \"is_feasible\": np.sum(violations) == 0,\n",
        "        \"region_a_markets\": int(np.sum(x)),\n",
        "        \"region_b_markets\": len(x) - int(np.sum(x)),\n",
        "    }\n",
        "\n",
        "\n",
        "# Convert bitstring to list of integers and validate\n",
        "optimal_assignment = [\n",
        "    int(bit) for bit in result[\"solution_info\"][\"bitstring\"]\n",
        "]\n",
        "validation = validate_solution(A, b, optimal_assignment)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "validation_results_intro",
      "metadata": {},
      "source": [
        "<span id=\"interpret-the-validation-results\" />\n",
        "\n",
        "#### Interprete os resultados da validação\n",
        "\n",
        "Os resultados da validação mostram se o Quantum Optimizer encontrou uma solução viável. Vamos examinar o seguinte:\n",
        "\n",
        "**Verificação de viabilidade:**\n",
        "\n",
        "* **`is_feasible = True`** significa que a solução satisfaz perfeitamente todas as restrições (violação total = 0)\n",
        "* **`is_feasible = False`** significa que algumas restrições foram violadas\n",
        "\n",
        "**Análise de vendas:**\n",
        "\n",
        "* Comparar as vendas pretendidas com as vendas reais de cada produto\n",
        "* Para uma solução perfeita: Real = Meta para todos os produtos em ambas as regiões\n",
        "* A diferença indica o quanto estamos próximos da divisão de mercado desejada\n",
        "\n",
        "**Distribuição de mercado:**\n",
        "\n",
        "* Mostra quantos mercados estão atribuídos a cada região\n",
        "* Não há exigência de um número igual de mercados, apenas que as metas de vendas sejam atingidas\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "display_validation",
      "metadata": {},
      "outputs": [],
      "source": [
        "print(\"Solution Validation\")\n",
        "print(\"=\" * 50)\n",
        "print(f\"Feasible solution: {validation['is_feasible']}\")\n",
        "print(f\"Total constraint violation: {validation['total_violation']}\")\n",
        "\n",
        "print(\"\\nSales Analysis (Target vs Actual):\")\n",
        "for i, (target, actual_a, actual_b) in enumerate(\n",
        "    zip(validation[\"target\"], validation[\"region_a\"], validation[\"region_b\"])\n",
        "):\n",
        "    violation_a = abs(actual_a - target)\n",
        "    violation_b = abs(actual_b - target)\n",
        "    print(f\"  Product {i+1}:\")\n",
        "    print(f\"    Target: {target}\")\n",
        "    print(f\"    Region A: {actual_a} (violation: {violation_a})\")\n",
        "    print(f\"    Region B: {actual_b} (violation: {violation_b})\")\n",
        "\n",
        "print(\"\\nMarket Distribution:\")\n",
        "print(f\"  Region A: {validation['region_a_markets']} markets\")\n",
        "print(f\"  Region B: {validation['region_b_markets']} markets\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "interpretation",
      "metadata": {},
      "source": [
        "<span id=\"solution-quality-assessment\" />\n",
        "\n",
        "#### Avaliação da qualidade da solução\n",
        "\n",
        "Com base nos resultados de validação acima, podemos avaliar a qualidade da solução quântica:\n",
        "\n",
        "**Se `is_feasible = True` (violação total = 0):**\n",
        "\n",
        "* O Quantum Optimizer encontrou com sucesso uma solução ideal\n",
        "* Todas as restrições comerciais são perfeitamente atendidas\n",
        "* Isso demonstra a vantagem quântica em um problema em que os solucionadores clássicos têm dificuldades [\\[4\\]](#references)\n",
        "\n",
        "**Se `is_feasible = False` (Total violation > 0):**\n",
        "\n",
        "* A solução é quase ideal, mas não perfeita\n",
        "* Pequenas violações podem ser aceitáveis na prática\n",
        "* Considere o ajuste dos parâmetros do otimizador:\n",
        "  * Aumente o site `num_iterations` para obter mais passes de otimização\n",
        "  * Aumente `postprocessing_level` para um refinamento mais clássico\n",
        "  * Aumente o site `shots` para obter melhores estatísticas de medição\n",
        "\n",
        "**Interpretação da função de custo:**\n",
        "\n",
        "* O valor `cost` de `solution_info` é igual a $||Ax - b||^2$\n",
        "* Custo = 0 indica satisfação perfeita das restrições\n",
        "* Valores de custo mais altos indicam maiores violações de restrições\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "conclusion",
      "metadata": {},
      "source": [
        "<span id=\"conclusion\" />\n",
        "\n",
        "## Conclusão\n",
        "\n",
        "<span id=\"what-we-accomplished\" />\n",
        "\n",
        "### O que conseguimos\n",
        "\n",
        "Neste tutorial, teremos sucesso:\n",
        "\n",
        "1. Carregamento **de um problema de otimização real** : obteve uma instância desafiadora de Market Split da biblioteca de benchmark QOBLIB \\[2]\n",
        "2. **Transformado para o formato QUBO** : Converteu o problema restrito em uma formulação quadrática sem restrições \\[3]\n",
        "3. Aproveitamento **de algoritmos quânticos avançados** : Usou o algoritmo bf-DCQO da Kipu Quantum com termos contra-diabáticos \\[1]\n",
        "4. **Obteve soluções ótimas** : Encontrou soluções viáveis que satisfazem todas as restrições\n",
        "\n",
        "<span id=\"key-takeaways\" />\n",
        "\n",
        "### Principais conclusões\n",
        "\n",
        "**Inovação do algoritmo** : O algoritmo bf-DCQO representa um avanço significativo [\\[1\\]](#references) :\n",
        "\n",
        "* **10 vezes menos portas** do que o recozimento quântico digital\n",
        "* **Aproximadamente 10 iterações** em vez de aproximadamente 100 para métodos variacionais\n",
        "* **Resiliência a erros incorporada** por meio da eficiência do circuito\n",
        "\n",
        "**Termos contra-diabáticos** : Permitem a rápida evolução quântica e, ao mesmo tempo, mantêm a fidelidade do estado fundamental, tornando a otimização quântica prática no hardware ruidoso atual [\\[1\\]](#references).\n",
        "\n",
        "**Orientação de campo de polarização** : A abordagem iterativa de campo de polarização permite que cada iteração comece perto de boas soluções encontradas anteriormente, proporcionando uma forma de pesquisa local aprimorada por quantum [\\[1\\]](#references).\n",
        "\n",
        "<span id=\"next-steps\" />\n",
        "\n",
        "### Próximas etapas\n",
        "\n",
        "Para aprofundar seu entendimento e explorar mais:\n",
        "\n",
        "1. **Experimente instâncias diferentes** : Faça experiências com outras instâncias do QOBLIB de tamanhos variados\n",
        "2. **Sintonizar parâmetros** : Adjust `num_iterations`, `preprocessing_level`, `postprocessing_level`\n",
        "3. **Comparação com o clássico** : Benchmark em relação aos solucionadores de otimização clássicos\n",
        "4. **Experimente estratégias diferentes** : Tente encontrar uma codificação melhor para o problema ou formule-o como HUBO (se possível)\n",
        "5. **Aplique em seu domínio** : Adaptar as técnicas de formulação QUBO/HUBO a seus próprios problemas de otimização\n",
        "\n",
        "<span id=\"references\" />\n",
        "\n",
        "### Referências\n",
        "\n",
        "\\[1] IBM Quantum. \"[Otimização quântica da Kipu](/docs/guides/kipu-optimization) \" *IBM Quantum Documentação*.\n",
        "\n",
        "\\[2] QOBLIB - Biblioteca de Benchmarking de Otimização Quântica. Instituto Zuse de Berlim (ZIB). [https://git.zib.de/qopt/qoblib-quantum-optimization-benchmarking-library](https://git.zib.de/qopt/qoblib-quantum-optimization-benchmarking-library)\n",
        "\n",
        "\\[3] Glover, F., Kochenberger, G., & Du, Y. (2019). \"Análise de ponte quântica I: um tutorial sobre a formulação e o uso de modelos QUBO\" *4OR: A Quarterly Journal of Operations Research*, 17(4), 335-371.\n",
        "\n",
        "\\[4] Lodi, A., Tramontani, A., & Weninger, K. (2023). \"O decatlo intratável: Benchmarking Hard Combinatorial Problems\" *INFORMS Journal on Computing*.\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"
    },
    "hours": 1,
    "qpuSeconds": 20
  },
  "nbformat": 4,
  "nbformat_minor": 5
}