{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "11ea9666",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Solucionador de otimização - Uma função Qiskit da Q-CTRL Fire Opal\"\n",
        "description: \"Comece a resolver problemas de otimização em escala utilitária com o Fire Opal Optimization Solver da Q-CTRL\"\n",
        "---\n",
        "\n",
        "{/* cspell:ignore Sachdeva */}\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "dde95705",
      "metadata": {},
      "source": [
        "<span id=\"optimization-solver-a-qiskit-function-by-q-ctrl-fire-opal\" />\n",
        "\n",
        "# Solucionador de otimização: uma função Qiskit da Q-CTRL Fire Opal\n",
        "\n",
        "*Consulte a [referência da API](/docs/api/functions/q-ctrl-optimization-solver)*\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  As funções do Qiskit 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"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "40c2085c",
      "metadata": {
        "tags": [
          "version-info"
        ]
      },
      "source": [
        "{/*\n",
        "  DO NOT EDIT THIS CELL!!!\n",
        "  This cell's content is generated automatically by a script. Anything you add\n",
        "  here will be removed next time the notebook is run. To add new content, create\n",
        "  a new cell before or after this one.\n",
        "  */}\n",
        "\n",
        "<Accordion>\n",
        "  <AccordionItem title=\"Versões do pacote\">\n",
        "    O código desta página foi desenvolvido com base nos seguintes requisitos.\n",
        "    Recomendamos o uso dessas versões ou versões mais recentes.\n",
        "\n",
        "    ```\n",
        "    qiskit-ibm-runtime~=0.47.0\n",
        "    sympy~=1.14.0\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e30c7881",
      "metadata": {},
      "source": [
        "<span id=\"overview\" />\n",
        "\n",
        "## Visão geral\n",
        "\n",
        "Com o Fire Opal Optimization Solver, você pode resolver problemas de otimização em escala de serviços públicos em hardware quântico sem precisar de conhecimento quântico. Basta inserir a definição do problema de alto nível, e o Solver se encarrega do resto. Todo o fluxo de trabalho é sensível a ruídos e aproveita [o Fire Opal's Performance Management](/docs/guides/q-ctrl-performance-management). O Solver fornece de forma consistente soluções precisas para problemas classicamente desafiadores, mesmo em escala de dispositivo completo nas maiores QPUs IBM®.\n",
        "\n",
        "O Solver é flexível e pode ser utilizado para resolver problemas de otimização combinatória definidos como funções-objetivo ou grafos arbitrários. Os problemas não precisam ser mapeados para a topologia do dispositivo. Tanto os problemas sem restrições quanto os com restrições são solucionáveis, desde que as restrições possam ser formuladas como termos de penalidade. Os exemplos incluídos neste guia demonstram como resolver um problema de otimização em escala de utilidade, com e sem restrições, utilizando diferentes tipos de entrada do Solver. O primeiro exemplo trata de um problema de corte máximo definido em um grafo regular de grau 3 com 156 vértices, enquanto o segundo exemplo aborda um problema de cobertura mínima de vértices com 50 vértices, definido por uma função de custo.\n",
        "\n",
        "Para obter acesso ao Optimization Solver, [entre em contato com a Q-CTRL](https://form.typeform.com/to/uOAVDnGg?typeform-source=q-ctrl.com).\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5f761442",
      "metadata": {},
      "source": [
        "<span id=\"function-description\" />\n",
        "\n",
        "## Descrição da função\n",
        "\n",
        "O Solver otimiza e automatiza totalmente o algoritmo inteiro, desde a supressão de erros no nível do hardware até o mapeamento eficiente do problema e a otimização clássica de loop fechado. Nos bastidores, o pipeline do Solver reduz os erros em todos os estágios, possibilitando o desempenho aprimorado necessário para um dimensionamento significativo. O fluxo de trabalho subjacente é inspirado no Algoritmo de Otimização Aproximada Quântica (QAOA), que é um algoritmo híbrido quântico-clássico. Para obter um resumo detalhado do fluxo de trabalho completo do Optimization Solver, consulte [o manuscrito publicado](https://arxiv.org/abs/2406.01743).\n",
        "\n",
        "![Visualização do fluxo de trabalho do Optimization Solver](https://quantum.cloud.ibm.com/docs/images/guides/qctrl-optimization/solver_workflow.svg)\n",
        "\n",
        "Para resolver um problema genérico com o Optimization Solver:\n",
        "\n",
        "1. Defina seu problema como uma função objetiva, um gráfico ou uma cadeia de spin `SparsePauliOp` .\n",
        "2. Conecte-se à função por meio do Qiskit Functions Catalog.\n",
        "3. Execute o problema com o Solver e recupere os resultados.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d20af236",
      "metadata": {},
      "source": [
        "<span id=\"accepted-problem-formats\" />\n",
        "\n",
        "### Formatos de problemas aceitos\n",
        "\n",
        "* Representação de expressão polinomial de uma função objetiva. Idealmente criado em Python com um objeto SymPy Poly existente e formatado em uma string usando [sympy.srepr](https://docs.sympy.org/latest/tutorials/intro-tutorial/printing.html#srepr).\n",
        "* Representação gráfica de um tipo específico de problema. O gráfico deve ser criado usando a biblioteca networkx em Python. Em seguida, ele deve ser convertido em uma string usando a função networkx `[nx.readwrite.json_graph.adjacency_data](http://nx.readwrite.json_graph.adjacency_data.)`.\n",
        "* Representação da cadeia de spin de um problema específico. A cadeia de spin deve ser representada como um objeto `SparsePauliOp` ; consulte a [documentação](/docs/api/qiskit/qiskit.quantum_info.SparsePauliOp) para obter mais detalhes.\n",
        "\n",
        "<Admonition type=\"note\" title=\"Esta função é compatível com todos os back-ends do ` IBM `?\">\n",
        "  Se você quiser usar um backend que esta função ainda não suporta, [entre em contato com a Q-CTRL](https://form.typeform.com/to/iuujEAEI?typeform-source=q-ctrl.com) para solicitar a adição desse suporte.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1165f4f0",
      "metadata": {},
      "source": [
        "<span id=\"benchmarks\" />\n",
        "\n",
        "## Referências\n",
        "\n",
        "[Os resultados de benchmarking publicados](https://arxiv.org/abs/2406.01743) mostram que o Solver resolve com sucesso problemas com mais de 120 qubits, superando até mesmo os resultados publicados anteriormente sobre recozimento quântico e dispositivos de íons presos. As métricas de referência a seguir fornecem uma indicação aproximada da precisão e do dimensionamento dos tipos de problemas com base em alguns exemplos. As métricas reais podem diferir com base em vários recursos do problema, como o número de termos na função objetiva (densidade) e sua localidade, número de variáveis e ordem polinomial.\n",
        "\n",
        "O \"Número de qubits\" indicado não é uma limitação rígida, mas representa limites aproximados em que você pode esperar uma precisão de solução extremamente consistente. Problemas de tamanhos maiores foram resolvidos com sucesso, e os testes além desses limites são incentivados.\n",
        "\n",
        "A conectividade arbitrária de qubit é suportada em todos os tipos de problemas.\n",
        "\n",
        "| Tipo de problema                            | Número de qubits | Exemplo                                                              | Precisão | Tempo Total (s) | Uso do tempo de execução (s) | Número de iterações |\n",
        "| ------------------------------------------- | ---------------- | -------------------------------------------------------------------- | -------- | --------------- | ---------------------------- | ------------------- |\n",
        "| Problemas quadráticos com conexões esparsas | 156              | 3-corte máximo regular                                               | 100%     | 1764            | 293                          | 16                  |\n",
        "| Otimização binária de ordem superior        | 156              | Modelo de vidro de spin de Ising                                     | 100%     | 1461            | 272                          | 16                  |\n",
        "| Problemas quadráticos densamente conectados | 50               | Corte máximo com conexão total                                       | 100%     | 1758            | 268                          | 12                  |\n",
        "| Problema restrito com termos de penalidade  | 50               | Cobertura mínima ponderada de vértices com 8% de densidade de bordas | 100%     | 1074            | 215                          | 22                  |\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "73390a19",
      "metadata": {},
      "source": [
        "<span id=\"get-started\" />\n",
        "\n",
        "## Introdução\n",
        "\n",
        "Primeiro, autentique-se usando sua [chave de API IBM Quantum](http://quantum.cloud.ibm.com/). Em seguida, selecione a função do Qiskit da seguinte maneira. (Este trecho pressupõe que você já tenha [salvo sua conta](/docs/guides/functions-get-started#install-qiskit-functions-catalog-client) no seu ambiente local.)\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "95a715d2",
      "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": 1,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit_ibm_catalog import QiskitFunctionsCatalog\n",
        "\n",
        "catalog = QiskitFunctionsCatalog(channel=\"ibm_quantum_platform\")\n",
        "\n",
        "# Verify that you have access to the function\n",
        "catalog.list()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "8acf84f6",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Access Function\n",
        "solver = catalog.load(\"q-ctrl/optimization-solver\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e8837f5f",
      "metadata": {},
      "source": [
        "<span id=\"example-unconstrained-optimization\" />\n",
        "\n",
        "## Exemplo: Otimização sem restrições\n",
        "\n",
        "Resolva o problema [do corte máximo](https://en.wikipedia.org/wiki/Maximum_cut) (max-cut). O exemplo a seguir demonstra as capacidades do Solver em um problema de corte máximo em um grafo não ponderado de 156 nós e 3 arcos regulares, mas também é possível resolver problemas em grafos ponderados.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a699235b",
      "metadata": {},
      "source": [
        "Além do `qiskit-ibm-catalog`, você também usará os seguintes pacotes para executar este exemplo: `networkx` e `numpy`. Você pode instalar esses pacotes descomentando a célula a seguir se estiver executando este exemplo em um notebook usando o kernel IPython.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "a74fe6a9",
      "metadata": {},
      "outputs": [],
      "source": [
        "# %pip install networkx numpy"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a41c4a0d",
      "metadata": {},
      "source": [
        "<span id=\"1-define-the-problem\" />\n",
        "\n",
        "### 1. Defina o problema\n",
        "\n",
        "Você pode resolver um problema de corte máximo definindo um problema de grafos e especificando `problem_type='maxcut'`.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "d56e1440",
      "metadata": {},
      "outputs": [],
      "source": [
        "import networkx as nx\n",
        "import numpy as np\n",
        "\n",
        "# Generate a random graph with 156 nodes\n",
        "maxcut_graph = nx.random_regular_graph(d=3, n=156, seed=8)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "0a7255e1",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/q-ctrl-optimization-solver/extracted-outputs/0a7255e1-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# Optionally, visualize the graph\n",
        "nx.draw_networkx(\n",
        "    maxcut_graph, nx.kamada_kawai_layout(maxcut_graph), node_size=100\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e42a8d55",
      "metadata": {},
      "source": [
        "O Solver aceita uma string como entrada de definição do problema.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "2546e3e5",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Convert graph to string\n",
        "problem_as_str = nx.readwrite.json_graph.adjacency_data(maxcut_graph)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0ab6f24f",
      "metadata": {},
      "source": [
        "<span id=\"2-run-the-problem\" />\n",
        "\n",
        "### 2. Execute o problema\n",
        "\n",
        "Ao usar o método de entrada baseado em gráficos, especifique o tipo de problema.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "16c66d64",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Solve the problem\n",
        "maxcut_job = solver.run(\n",
        "    problem=problem_as_str,\n",
        "    problem_type=\"maxcut\",\n",
        "    backend_name=backend_name,  # E.g. \"ibm_fez\"\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "48069093",
      "metadata": {},
      "source": [
        "Verifique [o status](/docs/guides/functions-get-started#check-job-status) da sua carga de trabalho do Qiskit Function ou obtenha [os resultados](/docs/guides/functions-get-started#retrieve-results) da seguinte maneira:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "856fe992",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "34b53970-d95a-4e24-8763-fc6f3d112843\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "QUEUED\n"
          ]
        }
      ],
      "source": [
        "# Print the ID so you can use it later, if necessary\n",
        "print(maxcut_job.job_id)\n",
        "\n",
        "# Get job status\n",
        "print(maxcut_job.status())"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "74f48eab",
      "metadata": {},
      "source": [
        "<span id=\"3-retrieve-the-result\" />\n",
        "\n",
        "### 3. Recuperar o resultado\n",
        "\n",
        "Recupere o valor de corte ideal do dicionário de resultados.\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  O mapeamento das variáveis para a cadeia de bits pode ter mudado. O dicionário de saída contém um `variables_to_bitstring_index_map` subdicionário, que ajuda a verificar a ordem.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "6b571411",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Optimal cut value: 210.0\n"
          ]
        }
      ],
      "source": [
        "# Poll for results\n",
        "maxcut_result = maxcut_job.result()\n",
        "\n",
        "# Take the absolute value of the solution since the cost function is minimized\n",
        "qctrl_maxcut = abs(maxcut_result[\"solution_bitstring_cost\"])\n",
        "\n",
        "# Print the optimal cut value found by the Optimization Solver\n",
        "print(f\"Optimal cut value: {qctrl_maxcut}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "508e29b0",
      "metadata": {},
      "source": [
        "Você pode verificar a precisão do resultado resolvendo o problema de forma clássica com solucionadores de código aberto, como [PuLP](https://coin-or.github.io/pulp/) se o gráfico não for densamente conectado. Problemas de alta densidade podem exigir solucionadores clássicos avançados para validar a solução.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e2817b13",
      "metadata": {},
      "source": [
        "<span id=\"example-constrained-optimization\" />\n",
        "\n",
        "## Exemplo: Otimização restrita\n",
        "\n",
        "O exemplo anterior de max-cut é um problema comum de otimização binária quadrática sem restrições. O Solucionador de Otimização do Q-CTRL pode ser utilizado para diversos tipos de problemas, incluindo otimização com restrições. É possível resolver tipos arbitrários de problemas inserindo a definição do problema representada como um polinômio, no qual as restrições são modeladas como termos de penalidade.\n",
        "\n",
        "O exemplo a seguir demonstra como construir uma função de custo para um problema de otimização restrito, [cobertura mínima de vértices](https://en.wikipedia.org/wiki/Vertex_cover) (MVC).\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a9fbc0e9",
      "metadata": {},
      "source": [
        "Além dos pacotes `qiskit-ibm-catalog` e `qiskit` , você também usará os seguintes pacotes para executar este exemplo: `numpy`, `networkx`, e `sympy`. Você pode instalar esses pacotes descomentando a célula a seguir se estiver executando este exemplo em um notebook usando o kernel IPython.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "c6428fd0",
      "metadata": {},
      "outputs": [],
      "source": [
        "# %pip install numpy networkx sympy"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "98d3bfd3",
      "metadata": {},
      "source": [
        "<span id=\"1-define-the-problem\" />\n",
        "\n",
        "### 1. Defina o problema\n",
        "\n",
        "Defina um problema de MVC aleatório gerando um gráfico com nós ponderados aleatoriamente.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "c2ce65e3",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/q-ctrl-optimization-solver/extracted-outputs/c2ce65e3-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "import networkx as nx\n",
        "from sympy import symbols, Poly, srepr\n",
        "\n",
        "# To change the weights, change the seed to any integer.\n",
        "rng_seed = 18\n",
        "_rng = np.random.default_rng(rng_seed)\n",
        "node_count = 50\n",
        "edge_probability = 0.08\n",
        "mvc_graph = nx.erdos_renyi_graph(\n",
        "    node_count, edge_probability, seed=rng_seed, directed=False\n",
        ")\n",
        "\n",
        "# add node weights\n",
        "for i in mvc_graph.nodes:\n",
        "    mvc_graph.add_node(i, weight=_rng.random())\n",
        "\n",
        "# Optionally, visualize the graph\n",
        "nx.draw_networkx(mvc_graph, nx.kamada_kawai_layout(mvc_graph), node_size=200)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "89c91472",
      "metadata": {},
      "source": [
        "Um modelo de otimização padrão para MVC ponderado pode ser formulado da seguinte forma. Primeiro, uma penalidade deve ser adicionada para qualquer caso em que uma borda não esteja conectada a um vértice no subconjunto. Portanto, deixe $n_i = 1$ se o vértice $i$ estiver na cobertura (ou seja, no subconjunto) e $n_i = 0$ caso contrário. Em segundo lugar, o objetivo é minimizar o número total de vértices no subconjunto, que pode ser representado pela seguinte função:\n",
        "\n",
        "$\\textbf{Minimize}\\qquad y = \\sum_{i\\in V} \\omega_i n_i$\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "91586ee9",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Construct the cost function.\n",
        "variables = symbols([f\"n[{i}]\" for i in range(node_count)])\n",
        "cost_function = Poly(0, variables)\n",
        "\n",
        "for i in mvc_graph.nodes():\n",
        "    weight = mvc_graph.nodes[i].get(\"weight\", 0)\n",
        "    cost_function += variables[i] * weight"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9d01684b",
      "metadata": {},
      "source": [
        "Agora, cada borda do gráfico deve incluir pelo menos um ponto final da cobertura, o que pode ser expresso como a desigualdade:\n",
        "\n",
        "$n_i + n_j \\ge 1 \\texttt{ for all } (i,j)\\in E$\n",
        "\n",
        "Qualquer caso em que uma borda não esteja conectada ao vértice de cobertura deve ser penalizado. Isso pode ser representado na função de custo adicionando uma penalidade no formato $P(1-n_i-n_j+n_i n_j)$, em que $P$ é uma constante de penalidade positiva. Portanto, uma alternativa sem restrições para a desigualdade com restrições para o MVC ponderado é:\n",
        "\n",
        "$\\textbf{Minimize}\\qquad y = \\sum_{i\\in V}\\omega_i n_i + P(\\sum_{(i,j)\\in E}(1 - n_i - n_j + n_i n_j))$\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "1ff1ffcc",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Add penalty term.\n",
        "penalty_constant = 2\n",
        "for i, j in mvc_graph.edges():\n",
        "    cost_function += penalty_constant * (\n",
        "        1 - variables[i] - variables[j] + variables[i] * variables[j]\n",
        "    )"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9fd0ba9e",
      "metadata": {},
      "source": [
        "<span id=\"2-run-the-problem\" />\n",
        "\n",
        "### 2. Execute o problema\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "f380b56d",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Solve the problem\n",
        "mvc_job = solver.run(\n",
        "    problem=srepr(cost_function),\n",
        "    backend_name=backend_name,  # E.g. \"ibm_fez\"\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d154c226",
      "metadata": {},
      "source": [
        "Verifique [o status](/docs/guides/functions-get-started#check-job-status) da sua carga de trabalho do Qiskit Function ou obtenha [os resultados](/docs/guides/functions-get-started#retrieve-results) da seguinte maneira:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "id": "6de77b14",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "QUEUED\n"
          ]
        }
      ],
      "source": [
        "print(mvc_job.status())"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "8a95618e",
      "metadata": {},
      "source": [
        "<span id=\"3-get-the-result\" />\n",
        "\n",
        "### 3. Obtenha o resultado\n",
        "\n",
        "Recupere a solução e analise os resultados. Como esse problema tem nós ponderados, a solução não é simplesmente o número mínimo de nós cobertos. Em vez disso, o custo da solução representa a soma dos pesos dos vértices que estão incluídos na cobertura do vértice. Ele representa o \"custo\" ou \"peso\" total de cobrir todas as bordas do gráfico usando os vértices selecionados.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "id": "a924bf93",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Solution cost: 10.248198273708624\n"
          ]
        }
      ],
      "source": [
        "mvc_result = mvc_job.result()\n",
        "qctrl_cost = mvc_result[\"solution_bitstring_cost\"]\n",
        "\n",
        "# Print results\n",
        "print(f\"Solution cost: {qctrl_cost}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e9ec2e67",
      "metadata": {},
      "source": [
        "<span id=\"get-support\" />\n",
        "\n",
        "## Obtenha suporte\n",
        "\n",
        "Em caso de dúvidas ou problemas, entre [em contato com a Q-CTRL](https://form.typeform.com/to/iuujEAEI?typeform-source=q-ctrl.com).\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "993aa226c6ec9f5e",
      "metadata": {},
      "source": [
        "<span id=\"changelog\" />\n",
        "\n",
        "## Log de mudanças\n",
        "\n",
        "* 11/02/2026: Agora oferecemos suporte para `ibm_miami`\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5a6a25c8",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Próximas etapas\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Recomendações\">\n",
        "  * Solicite acesso ao [Solucionador de Otimização Q-CTRL](/functions?id=q-ctrl-optimization-solver).\n",
        "  * Consulte a [referência da API](/docs/api/functions/q-ctrl-optimization-solver) para esta função do Qiskit.\n",
        "  * Experimente o tutorial [Solve higher-order binary optimization problems with Q-CTRL's Optimization Solver](/docs/tutorials/solve-higher-order-binary-optimization-problems-with-q-ctrls-optimization-solver).\n",
        "  * Revisão [Sachdeva, N., et al. (2024).  A otimização quântica usando um computador quântico de 127 qubits com modelo de porta IBM pode superar os annealers quânticos em problemas de otimização binária não triviais. arXiv pré-impressão arXiv:2406.01743](https://arxiv.org/abs/2406.01743).\n",
        "  * Revisão [Loco, D., et al. (2026).  Previsão prática do local de hidratação do bolso proteico para a descoberta de medicamentos em um computador quântico. arXiv pré-impressão arXiv:2512.08390](https://arxiv.org/abs/2512.08390).\n",
        "  * Analise o estudo de caso [da Mazda](https://q-ctrl.com/case-study/tackling-a-costly-bottleneck-in-automotive-design).\n",
        "  * Analise o estudo de caso [da Network Rail](https://q-ctrl.com/case-study/accelerating-the-schedule-for-quantum-enhanced-rail).\n",
        "  * Analise o estudo de caso [do Exército Australiano](https://q-ctrl.com/case-study/improving-army-logistics-with-quantum-computing).\n",
        "  * Analise o estudo de caso [da Transport for New South Wales](https://q-ctrl.com/case-study/delivering-quantum-computing-for-faster-commuting).\n",
        "</Admonition>\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
}