Resolva o problema da divisão do mercado com o Iskay Quantum Optimizer da Kipu Quantum
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.
Estimativa de uso: 20 segundos em um processador Heron r2. (OBSERVAÇÃO: essa é apenas uma estimativa. Seu tempo de execução pode variar)
Segundo plano
Este tutorial demonstra como resolver o problema de divisão de mercado usando o otimizador quântico Iskay do Kipu Quantum [1]. 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.
O desafio da divisão do mercado
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 produtos sendo vendidos em mercados diferentes, onde cada mercado compra um pacote específico de produtos (representado pelas colunas da matriz ). 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.
Formulação matemática:
Buscamos um vetor de atribuição binária , onde:
- atribui o mercado à região A
- atribui o mercado à Região B
- A restrição deve ser satisfeita, em que representa a meta de vendas (normalmente, metade da demanda total por produto)
Função de custo:
Para resolver esse problema, minimizamos a violação da restrição ao quadrado:
em que:
- representa as vendas do produto no mercado
- é a atribuição binária de mercado
- é a meta de vendas do produto em cada região
- O custo é igual a zero exatamente quando todas as restrições são satisfeitas
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:
Como é uma constante, minimizar é equivalente a minimizar a função quadrática , que é exatamente um problema QUBO (Quadratic Unconstrained Binary Optimization).
Complexidade computacional:
Apesar de sua interpretação comercial simples, esse problema apresenta uma notável intratabilidade computacional:
- 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]
- Crescimento exponencial : O espaço de solução cresce exponencialmente ( atribuições possíveis), tornando inviáveis as abordagens de força bruta
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].
O que torna a abordagem de Iskay única?
O otimizador Iskay usa o algoritmo bf-DCQO (bias-field digitized counterdiabatic quantum optimization) [1], que representa um avanço significativo na otimização quântica:
Eficiência do circuito : O algoritmo bf-DCQO alcança uma notável redução de portas [1] :
- Até 10 vezes menos portas de emaranhamento do que o Digital Quantum Annealing (DQA)
- Possibilita circuitos significativamente mais rasos:
- Menor acúmulo de erros durante a execução quântica
- Capacidade de lidar com problemas maiores no hardware quântico atual
- Não há necessidade de técnicas de atenuação de erros
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]. Isso é realizado por meio de:
- Cálculos inteligentes de campo de polarização a partir de distribuições de estados medidos
- Iniciar cada iteração a partir de um estado de energia próximo à solução anterior
- Pós-processamento clássico integrado com pesquisa local
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].
Requisitos
Antes de iniciar este tutorial, verifique se você tem os seguintes itens instalados:
- Qiskit IBM Runtime (
pip install qiskit-ibm-runtime) - Qiskit Functions (
pip install qiskit-ibm-catalog) - NumPy (
pip install numpy) - Solicitações (
pip install requests) - Addon do Opt Mapper Qiskit (
pip install qiskit-addon-opt-mapper)
Você também precisará obter acesso à função Iskay Quantum Optimizer no site Qiskit Functions Catalog.
Instalação
Primeiro, importe todos os pacotes necessários para este tutorial.
import os
import tempfile
import time
from typing import Tuple, Optional
import numpy as np
import requests
from qiskit_ibm_catalog import QiskitFunctionsCatalog
from qiskit_addon_opt_mapper import OptimizationProblem
from qiskit_addon_opt_mapper.converters import OptimizationProblemToQubo
print("All required libraries imported successfully")Configurar credenciais d IBM Quantum
Defina suas IBM Quantum® Platform credenciais. Você precisará de:
- Token de API : Sua chave de API de 44 caracteres de IBM Quantum Platform
- CRN da instância : Seu identificador de instância IBM Cloud®
token = "<YOUR_API_KEY>"
instance = "<YOUR_INSTANCE_CRN>"Passo 1: Mapear entradas clássicas para um problema quântico
Começamos mapeando nosso problema clássico para uma representação compatível com o quantum. Essa etapa envolve:
- Conexão com o Iskay Quantum Optimizer
- Carregamento e formulação do problema de divisão de mercado
- Entendendo o algoritmo bf-DCQO que o resolverá
Conecte-se ao Iskay Quantum Optimizer
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.
catalog = QiskitFunctionsCatalog(token=token, instance=instance)
iskay_solver = catalog.load("kipu-quantum/iskay-quantum-optimizer")
print("Iskay optimizer loaded successfully")
print("Ready to solve optimization problems using bf-DCQO algorithm")Carregue e formule o problema
Entenda o formato dos dados do problema
As instâncias de problemas da QOBLIB (Quantum Optimization Benchmarking Library) [2] 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:
3 20
60 92 161 53 97 2 75 81 6 139 132 45 108 112 181 93 152 200 164 51 1002
176 196 41 143 2 88 0 79 10 71 75 148 82 135 34 187 33 155 58 46 879
68 68 179 173 127 163 48 49 99 78 44 52 173 131 73 198 84 109 180 95 1040Estrutura do formato:
-
Primeira linha:
3 203= número de produtos (restrições/linhas na matriz )20= número de mercados (variáveis/colunas na matriz )
-
Próximas 3 linhas: Matriz de coeficiente e vetor de destino
- Cada linha tem 21 números: os primeiros 20 são coeficientes de linha, o último é o alvo
- Linha 2:
60 92 161 ... 51 | 1002- Primeiros 20 números: Quanto do Produto 1 cada um dos 20 mercados vende
- Último número (1002): Meta de vendas para o Produto 1 em uma região
- Linha 3:
176 196 41 ... 46 | 879- Vendas do produto 2 por mercado e meta (879)
- Linha 4:
68 68 179 ... 95 | 1040- Vendas do produto 3 por mercado e meta (1040)
Interpretação de negócios:
- O Mercado 0 vende: 60 unidades do Produto 1, 176 unidades do Produto 2, 68 unidades do Produto 3
- O Mercado 1 vende: 92 unidades do Produto 1, 196 unidades do Produto 2, 68 unidades do Produto 3
- E assim por diante para todos os 20 mercados...
- 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
Transformação QUBO
Das restrições ao QUBO: a transformação matemática
O poder da otimização quântica está na transformação de problemas com restrições em formas quadráticas sem restrições [4]. Para o problema de Market Split, convertemos as restrições de igualdade
onde , em um QUBO, penalizando as violações de restrições.
O método de penalidade: Como precisamos que se mantenha exatamente, minimizamos a violação ao quadrado:
Isso é igual a zero exatamente quando todas as restrições são satisfeitas. Expandindo algebricamente:
Objetivo do QUBO: Como é constante, nossa otimização se torna:
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]. 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.
Implementar funções de carregamento de dados e conversão QUBO
Agora definimos três funções de utilidade:
parse_marketsplit_dat()- Analisa o formato de arquivo.date extrai as matrizes efetch_marketsplit_data()- Faz o download de instâncias de problemas diretamente do repositório QOBLIB
def parse_marketsplit_dat(filename: str) -> Tuple[np.ndarray, np.ndarray]:
"""
Parse a market split problem from a .dat file format.
Parameters
----------
filename : str
Path to the .dat file containing the market split problem data.
Returns
-------
A : np.ndarray
Coefficient matrix of shape (m, n) where m is the number of products
and n is the number of markets.
b : np.ndarray
Target vector of shape (m,) containing the target sales per product.
"""
with open(filename, "r", encoding="utf-8") as f:
lines = [
line.strip()
for line in f
if line.strip() and not line.startswith("#")
]
if not lines:
raise ValueError("Empty or invalid .dat file")
# First line: m n (number of products and markets)
m, n = map(int, lines[0].split())
# Next m lines: each row of A followed by corresponding element of b
A, b = [], []
for i in range(1, m + 1):
values = list(map(int, lines[i].split()))
A.append(values[:-1]) # First n values: product sales per market
b.append(values[-1]) # Last value: target sales for this product
return np.array(A, dtype=np.int32), np.array(b, dtype=np.int32)
def fetch_marketsplit_data(
instance_name: str = "ms_03_200_177.dat",
) -> Tuple[Optional[np.ndarray], Optional[np.ndarray]]:
"""
Fetch market split data directly from the QOBLIB repository.
Parameters
----------
instance_name : str
Name of the .dat file to fetch (default: "ms_03_200_177.dat").
Returns
-------
A : np.ndarray or None
Coefficient matrix if successful, None if failed.
b : np.ndarray or None
Target vector if successful, None if failed.
"""
url = f"https://git.zib.de/qopt/qoblib-quantum-optimization-benchmarking-library/-/raw/main/01-marketsplit/instances/{instance_name}"
try:
response = requests.get(url, timeout=30)
response.raise_for_status()
with tempfile.NamedTemporaryFile(
mode="w", suffix=".dat", delete=False, encoding="utf-8"
) as f:
f.write(response.text)
temp_path = f.name
try:
return parse_marketsplit_dat(temp_path)
finally:
os.unlink(temp_path)
except Exception as e:
print(f"Error: {e}")
return None, NoneCarregar a instância do problema
Agora carregamos a instância específica do problema ms_03_200_177.dat do QOBLIB [2]. Essa instância tem:
- 3 produtos (restrições)
- 20 mercados (variáveis de decisão binárias)
- Mais de 1 milhão de possíveis atribuições de mercado para explorar ( )
# Load the problem instance
instance_name = "ms_03_200_177.dat"
A, b = fetch_marketsplit_data(instance_name=instance_name)
if A is not None:
print("Successfully loaded problem instance from QOBLIB")
print("\nProblem Instance Analysis:")
print("=" * 50)
print(f"Coefficient Matrix A: {A.shape[0]} × {A.shape[1]}")
print(f" → {A.shape[0]} products (constraints)")
print(f" → {A.shape[1]} markets (decision variables)")
print(f"Target Vector b: {b}")
print(" → Target sales per product for each region")
print(
f"Solution Space: "
f"2^{A.shape[1]} = {2**A.shape[1]:,} possible assignments"
)Converter para o formato QUBO
Agora, transformamos o problema de otimização com restrições no formato QUBO:
# Create optimization problem
ms = OptimizationProblem(instance_name.replace(".dat", ""))
# Add binary variables (one for each market)
ms.binary_var_list(A.shape[1])
# Add equality constraints (one for each product)
for idx, rhs in enumerate(b):
ms.linear_constraint(A[idx, :], sense="==", rhs=rhs)
# Convert to QUBO with penalty parameter
qubo = OptimizationProblemToQubo(penalty=1).convert(ms)
print("QUBO Conversion Complete:")
print("=" * 50)
print(f"Number of variables: {qubo.get_num_vars()}")
print(f"Constant term: {qubo.objective.constant}")
print(f"Linear terms: {len(qubo.objective.linear.to_dict())}")
print(f"Quadratic terms: {len(qubo.objective.quadratic.to_dict())}")Converter QUBO para o formato Iskay
Agora precisamos converter o objeto QUBO no formato de dicionário exigido pelo Iskay Optimizer da Kipu Quantum.
Os argumentos problem e problem_type codificam um problema de otimização da forma
em que
- Ao escolher
problem_type = "binary", você especifica que a função de custo está no formatobinary, o que significa que , como em, a função de custo é escrita na formulação QUBO/HUBO. - Por outro lado, ao escolher
problem_type = "spin", a função de custo é escrita na formulação de Ising, onde .
Os coeficientes do problema devem ser codificados em um dicionário da seguinte forma:
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:
para (já que significa ). Portanto, em sua formulação QUBO, se você tiver contribuições lineares e contribuições quadráticas diagonais , esses termos deverão ser combinados em um único coeficiente linear:
Coeficiente linear total para a variável :
Ou seja:
- Termos lineares como
"(i, )"contêm: coeficiente linear original + coeficiente quadrático diagonal - Termos quadráticos diagonais como
"(i, i)"NÃO devem aparecer no dicionário final - Somente os termos quadráticos fora da diagonal, como
"(i, j)"onde , devem ser incluídos como entradas separadas
Exemplo: Se seu QUBO tiver , o dicionário Iskay deverá conter:
"(0, )":5.0(combinando )"(0, 1)":4.0(termo fora da diagonal)
NÃO há entradas separadas para "(0, )": 3.0 e "(0, 0)": 2.0.
# Convert QUBO to Iskay dictionary format:
# Create empty Iskay input dictionary
iskay_input_problem = {}
# Convert QUBO to Iskay dictionary format
iskay_input_problem = {"()": qubo.objective.constant}
for i in range(qubo.get_num_vars()):
for j in range(i, qubo.get_num_vars()):
if i == j:
# Add linear term (including diagonal quadratic contribution)
iskay_input_problem[f"({i}, )"] = float(
qubo.objective.linear.to_dict().get(i)
) + float(qubo.objective.quadratic.to_dict().get((i, i)))
else:
# Add off-diagonal quadratic term
iskay_input_problem[f"({i}, {j})"] = float(
qubo.objective.quadratic.to_dict().get((i, j))
)
# Display Iskay dictionary summary
print("Iskay Dictionary Format:")
print("=" * 50)
print(f"Total coefficients: {len(iskay_input_problem)}")
print(f" • Constant term: {iskay_input_problem['()']}")
print(
f" • Linear terms: "
f"{sum(1 for k in iskay_input_problem.keys() if k != '()' and ', )' in k)}"
)
print(
f" • Quadratic terms: "
f"{sum(1 for k in iskay_input_problem.keys() if k != '()' and ', )' not in k)}"
)
print("\nSample coefficients:")
# Get first 10 and last 5 items properly
items = list(iskay_input_problem.items())
first_10 = list(enumerate(items[:10]))
last_5 = list(enumerate(items[-5:], start=len(items) - 5))
for i, (key, value) in first_10 + last_5:
coeff_type = (
"constant"
if key == "()"
else "linear"
if ", )" in key
else "quadratic"
)
print(f" {key}: {value} ({coeff_type})")
print(" ...")
print("\n✓ Problem ready for Iskay optimizer!")Entenda o algoritmo bf-DCQO
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].
O que é bf-DCQO?
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]. O algoritmo aborda um desafio fundamental na otimização quântica:
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.
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.
Estrutura matemática
O algoritmo minimiza uma função de custo do tipo:
em que para variáveis binárias e:
Para nosso problema de divisão de mercado, a função de custo é:
O papel dos termos antidiabéticos
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:
Na otimização quântica adiabática, evoluímos o sistema de acordo com um Hamiltoniano dependente do tempo:
em que codifica nosso problema de otimização. Para manter o estado fundamental durante a evolução rápida, adicionamos termos contra-diabáticos:
Esses termos contra-diabáticos fazem o seguinte:
- Suprimir transições indesejadas : Impedir que o estado quântico salte para estados excitados durante a evolução rápida
- Permitir tempos de evolução mais curtos : Permite que alcancemos o estado final muito mais rapidamente sem violar a adiabaticidade
- Reduzir a profundidade do circuito : Uma evolução mais curta leva a menos portas e menos erros
O impacto prático é significativo: o bf-DCQO usa até 10 vezes menos portas de emaranhamento do que o Digital Quantum Annealing [1], o que o torna prático para o hardware quântico ruidoso atual.
Otimização iterativa do campo de viés
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] :
Processo de iteração:
-
Evolução quântica inicial : Comece com um circuito quântico implementando o protocolo de evolução contra-diabática
-
Medição : Medir o estado quântico para obter uma distribuição de probabilidade sobre cadeias de bits
-
Cálculo do campo de polarização : Analise as estatísticas de medição e calcule um campo de polarização ideal para cada qubit:
-
Próxima iteração : O campo de polarização modifica o Hamiltoniano para a próxima iteração:
Isso permite começar perto da boa solução encontrada anteriormente, realizando efetivamente uma forma de "pesquisa local quântica"
-
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
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.
Pós-processamento clássico integrado
Após a convergência da otimização quântica, o Iskay realiza o pós-processamento clássico de pesquisa local :
- Exploração de inversão de bits : Inverter sistemática ou aleatoriamente os bits na melhor solução medida
- Avaliação de energia : Calcular para cada solução modificada
- Seleção inteligente : Aceitar melhorias que reduzam a função de custo
- Múltiplas passagens : Executar várias passagens (controladas por
postprocessing_level)
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.
Por que o bf-DCQO se destaca no hardware atual
O algoritmo bf-DCQO foi projetado especificamente para se destacar nos dispositivos quânticos atuais de escala intermediária e ruidosa (NISQ) [1] :
- Resiliência a erros : Menos portas (redução de 10 vezes) significa muito menos acúmulo de erros
- 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]
- Escalabilidade : Pode lidar com problemas de até 156 qubits (156 variáveis binárias) com mapeamento direto de qubits [1]
- Desempenho comprovado : Atinge taxas de aproximação de 100% nas instâncias de referência MaxCut e HUBO [1]
Agora vamos ver esse poderoso algoritmo em ação em nosso problema de divisão de mercado!
Etapa 2: Otimizar o problema para execução em hardware quântico
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.
Configure a otimização
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:
Parâmetros necessários
Parâmetro | Tipo | Descrição | Exemplo |
|---|---|---|---|
| problema | Dict[str, float] | Coeficientes QUBO em formato de chave de cadeia | {"()": -21.0, "(0,4)": 0.5, "(0,1)": 0.5} |
| problema_tipo | str | Especificação do formato: "binary" para QUBO ou "spin" para Ising | "binary" |
| backend_name | str | Dispositivo quântico alvo | "ibm_fez" |
Conceitos essenciais
- Formato do problema : Usamos o site
"binary", pois nossas variáveis são binárias (0/1), representando atribuições de mercado. - 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. - Estrutura QUBO : Nosso dicionário de problemas contém os coeficientes exatos da transformação matemática.
Opções avançadas (opcional)
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:
Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
| Tentativas | int | 10000 | Medições quânticas por iteração (maior = mais preciso) |
| num_iterações | int | 22 | Iterações do algoritmo (mais iterações podem melhorar a qualidade da solução) |
| usar_sessão | bool | Sim | Use sessões IBM para reduzir o tempo de fila |
| semente_transpilador | int | Nenhum | Conjunto para compilação reproduzível de circuitos quânticos |
| direct_qubit_mapping | bool | Não | Mapear os qubits virtuais diretamente para os qubits físicos |
| trabalho_tags | List[str] | Nenhum | Tags personalizadas para rastreamento de trabalhos |
| pré-processamento\nível | int | 0 | Intensidade de pré-processamento do problema (0-3) - veja detalhes abaixo |
| pós-processamento\nível | int | 2 | Nível de refinamento da solução (0-2) - veja detalhes abaixo |
| transpilação_nível | int | 0 | Testes de otimização do transpilador (0-5) - veja detalhes abaixo |
| transpile_only | bool | Não | Analise a otimização do circuito sem executar a execução completa |
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ível 0 : Circuitos exatos e mais longos
- 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ível 2 : Aproximação um pouco maior, cortando os portões com ângulos no percentil 20 mais baixo e usando
approximation_degree=0.95na transpilação - Nível 3 : Nível máximo de aproximação, cortando os portões no percentil 30 mais baixo e usando
approximation_degree=0.90na transpilação
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ível 0 : otimização do circuito DCQO decomposto (layout, roteamento, programação)
- Nível 1 : Otimização do site
PauliEvolutionGatee, em seguida, do circuito DCQO decomposto ( max_trials=10 ) - Nível 2 : otimização do site
PauliEvolutionGatee, em seguida, do circuito DCQO decomposto ( max_trials=15 ) - Nível 3 : otimização do site
PauliEvolutionGatee, em seguida, do circuito DCQO decomposto ( max_trials=20 ) - Nível 4 : otimização de
PauliEvolutionGatee, em seguida, o circuito DCQO decomposto ( max_trials=25 ) - Nível 5 : Otimização do site
PauliEvolutionGatee, em seguida, do circuito DCQO decomposto ( max_trials=50 )
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ível 0 : 1 passe
- Nível 1 : 2 passes
- Nível 2 : 3 passes
Modo somente transpile : Agora disponível para usuários que desejam analisar a otimização do circuito sem executar o algoritmo quântico completo.
Exemplo de configuração personalizada
Veja como você pode configurar o Iskay com diferentes definições:
custom_options = {
# Higher shot count for better statistics
"shots": 15_000,
# More iterations for solution refinement
"num_iterations": 12,
# Light preprocessing for problem simplification
"preprocessing_level": 1,
# Maximum postprocessing for solution quality
"postprocessing_level": 2,
# Using higher transpilation level for circuit optimization
"transpilation_level": 3,
# Fixed seed for reproducible results
"seed_transpiler": 42,
# Custom tracking tags
"job_tags": ["market_split"]
}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:
# Specify the target backend
backend_name = "ibm_fez"
# Set the number of bias-field iterations and set a tag to identify the jobs
options = {
"num_iterations": 3, # Change number of bias-field iterations
"job_tags": ["market_split_example"], # Tag to identify jobs
}
# Configure Iskay optimizer
iskay_input = {
"problem": iskay_input_problem,
"problem_type": "binary",
"backend_name": backend_name,
"options": options,
}
print("Iskay Optimizer Configuration:")
print("=" * 40)
print(f" Backend: {backend_name}")
print(f" Problem: {len(iskay_input['problem'])} terms")
print(" Algorithm: bf-DCQO")Passo 3: Execute usando Qiskit primitives
Agora enviamos nosso problema para ser executado no hardware IBM Quantum. O algoritmo bf-DCQO irá:
- Construir circuitos quânticos rasos com termos contra-diabáticos
- Execute aproximadamente 10 iterações com otimização de campo de polarização
- Realizar o pós-processamento clássico com pesquisa local
- Retornar a atribuição de mercado ideal
# Submit the optimization job
print("Submitting optimization job to Kipu Quantum...")
print(
f"Problem size: {A.shape[1]} variables, {len(iskay_input['problem'])} terms"
)
print(
"Algorithm: bf-DCQO (bias-field digitized counterdiabatic quantum optimization)"
)
job = iskay_solver.run(**iskay_input)
print("\nJob successfully submitted!")
print(f"Job ID: {job.job_id}")
print("Optimization in progress...")
print(
f"The bf-DCQO algorithm will efficiently explore "
f"{2**A.shape[1]:,} possible assignments"
)Monitorar o status da tarefa
Você pode verificar o status atual do seu trabalho de otimização. Os status possíveis são:
QUEUED: O trabalho está aguardando na filaRUNNING: O trabalho está sendo executado atualmente no hardware quânticoDONE: Trabalho concluído com êxitoCANCELED: O trabalho foi canceladoERROR: O trabalho encontrou um erro
# Check job status
print(f"Job status: {job.status()}")Aguarde a conclusão
Essa célula será bloqueada até que o trabalho seja concluído. O processo de otimização inclui:
- Tempo de fila (aguardando acesso ao hardware quântico)
- Tempo de execução (executando o algoritmo bf-DCQO com aproximadamente 10 iterações)
- Tempo de pós-processamento (pesquisa local clássica)
Os tempos de conclusão típicos variam de alguns minutos a dezenas de minutos, dependendo das condições da fila.
# Wait for job completion
while True:
status = job.status()
print(
f"Waiting for job {job.job_id} to complete... (status: {status})",
end="\r",
flush=True,
)
if status in ["DONE", "CANCELED", "ERROR"]:
print(
f"\nJob {job.job_id} completed with status: {status}" + " " * 20
)
break
time.sleep(30)
# Retrieve the optimization results
result = job.result()
print("\nOptimization complete!")Etapa 4: Pós-processamento e retorno do resultado no formato clássico desejado
Agora, fazemos o pós-processamento dos resultados da execução quântica. Isso inclui:
- Análise da estrutura da solução
- Validação da satisfação das restrições
- Avaliação comparativa com abordagens clássicas
Analisar resultados
Entenda a estrutura do resultado
O Iskay retorna um dicionário de resultados abrangente que contém:
solution: Um dicionário que mapeia os índices de variáveis para seus valores ideais (0 ou 1)solution_info: Informações detalhadas, incluindo:bitstring: A atribuição ideal como uma string bináriacost: O valor da função objetiva (deve ser 0 para satisfação perfeita das restrições)mapping: Como as posições de bitstring são mapeadas para as variáveis do problemaseed_transpiler: Semente usada para reprodutibilidade
prob_type: Se a solução está em formato binário ou spin
Vamos examinar a solução retornada pelo otimizador quântico.
# Display the optimization results
print("Optimization Results")
print("=" * 50)
print(f"Problem Type: {result['prob_type']}")
print("\nSolution Info:")
print(f" Bitstring: {result['solution_info']['bitstring']}")
print(f" Cost: {result['solution_info']['cost']}")
print("\nSolution (first 10 variables):")
for i, (var, val) in enumerate(list(result["solution"].items())[:10]):
print(f" {var}: {val}")
print(" ...")Validação de solução
Agora, validamos se a solução quântica satisfaz as restrições do Market Split. O processo de validação verifica:
O que é uma violação de restrição?
- Para cada produto , calculamos as vendas reais na Região A:
- Comparamos isso com a meta de vendas
- A violação é a diferença absoluta:
- Uma solução viável tem zero violações para todos os produtos
O que esperamos:
- Caso ideal : Violação total = 0 (todas as restrições perfeitamente satisfeitas)
- A região A recebe exatamente 1002 unidades do Produto 1, 879 unidades do Produto 2 e 1040 unidades do Produto 3
- A região B recebe as unidades restantes (também 1002, 879 e 1040, respectivamente)
- Bom caso : A violação total é pequena (solução quase ideal)
- Caso ruim : Grandes violações indicam que a solução não atende aos requisitos comerciais
A função de validação será computada:
- Vendas reais por produto em cada região
- Violações de restrições para cada produto
- Distribuição do mercado entre as regiões
def validate_solution(A, b, solution):
"""Validate market split solution."""
x = np.array(solution)
region_a = A @ x
region_b = A @ (1 - x)
violations = np.abs(region_a - b)
return {
"target": b,
"region_a": region_a,
"region_b": region_b,
"violations": violations,
"total_violation": np.sum(violations),
"is_feasible": np.sum(violations) == 0,
"region_a_markets": int(np.sum(x)),
"region_b_markets": len(x) - int(np.sum(x)),
}
# Convert bitstring to list of integers and validate
optimal_assignment = [
int(bit) for bit in result["solution_info"]["bitstring"]
]
validation = validate_solution(A, b, optimal_assignment)Interprete os resultados da validação
Os resultados da validação mostram se o Quantum Optimizer encontrou uma solução viável. Vamos examinar o seguinte:
Verificação de viabilidade:
is_feasible = Truesignifica que a solução satisfaz perfeitamente todas as restrições (violação total = 0)is_feasible = Falsesignifica que algumas restrições foram violadas
Análise de vendas:
- Comparar as vendas pretendidas com as vendas reais de cada produto
- Para uma solução perfeita: Real = Meta para todos os produtos em ambas as regiões
- A diferença indica o quanto estamos próximos da divisão de mercado desejada
Distribuição de mercado:
- Mostra quantos mercados estão atribuídos a cada região
- Não há exigência de um número igual de mercados, apenas que as metas de vendas sejam atingidas
print("Solution Validation")
print("=" * 50)
print(f"Feasible solution: {validation['is_feasible']}")
print(f"Total constraint violation: {validation['total_violation']}")
print("\nSales Analysis (Target vs Actual):")
for i, (target, actual_a, actual_b) in enumerate(
zip(validation["target"], validation["region_a"], validation["region_b"])
):
violation_a = abs(actual_a - target)
violation_b = abs(actual_b - target)
print(f" Product {i+1}:")
print(f" Target: {target}")
print(f" Region A: {actual_a} (violation: {violation_a})")
print(f" Region B: {actual_b} (violation: {violation_b})")
print("\nMarket Distribution:")
print(f" Region A: {validation['region_a_markets']} markets")
print(f" Region B: {validation['region_b_markets']} markets")Avaliação da qualidade da solução
Com base nos resultados de validação acima, podemos avaliar a qualidade da solução quântica:
Se is_feasible = True (violação total = 0):
- O Quantum Optimizer encontrou com sucesso uma solução ideal
- Todas as restrições comerciais são perfeitamente atendidas
- Isso demonstra a vantagem quântica em um problema em que os solucionadores clássicos têm dificuldades [4]
Se is_feasible = False (Total violation > 0):
- A solução é quase ideal, mas não perfeita
- Pequenas violações podem ser aceitáveis na prática
- Considere o ajuste dos parâmetros do otimizador:
- Aumente o site
num_iterationspara obter mais passes de otimização - Aumente
postprocessing_levelpara um refinamento mais clássico - Aumente o site
shotspara obter melhores estatísticas de medição
- Aumente o site
Interpretação da função de custo:
- O valor
costdesolution_infoé igual a - Custo = 0 indica satisfação perfeita das restrições
- Valores de custo mais altos indicam maiores violações de restrições
Conclusão
O que conseguimos
Neste tutorial, teremos sucesso:
- Carregamento de um problema de otimização real : obteve uma instância desafiadora de Market Split da biblioteca de benchmark QOBLIB [2]
- Transformado para o formato QUBO : Converteu o problema restrito em uma formulação quadrática sem restrições [3]
- Aproveitamento de algoritmos quânticos avançados : Usou o algoritmo bf-DCQO da Kipu Quantum com termos contra-diabáticos [1]
- Obteve soluções ótimas : Encontrou soluções viáveis que satisfazem todas as restrições
Principais conclusões
Inovação do algoritmo : O algoritmo bf-DCQO representa um avanço significativo [1] :
- 10 vezes menos portas do que o recozimento quântico digital
- Aproximadamente 10 iterações em vez de aproximadamente 100 para métodos variacionais
- Resiliência a erros incorporada por meio da eficiência do circuito
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].
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].
Próximas etapas
Para aprofundar seu entendimento e explorar mais:
- Experimente instâncias diferentes : Faça experiências com outras instâncias do QOBLIB de tamanhos variados
- Sintonizar parâmetros : Adjust
num_iterations,preprocessing_level,postprocessing_level - Comparação com o clássico : Benchmark em relação aos solucionadores de otimização clássicos
- Experimente estratégias diferentes : Tente encontrar uma codificação melhor para o problema ou formule-o como HUBO (se possível)
- Aplique em seu domínio : Adaptar as técnicas de formulação QUBO/HUBO a seus próprios problemas de otimização
Referências
[1] IBM Quantum. "Otimização quântica da Kipu " IBM Quantum Documentação.
[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
[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.
[4] Lodi, A., Tramontani, A., & Weninger, K. (2023). "O decatlo intratável: Benchmarking Hard Combinatorial Problems" INFORMS Journal on Computing.