Skip to main content
IBM Quantum Platform

Iskay Quantum Optimizer - Uma função Qiskit da Kipu Quantum

Consulte a referência da API

Nota
  • 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.

Visão geral

Com o Iskay Quantum Optimizer da Kipu Quantum, você pode lidar com problemas complexos de otimização usando computadores quânticos IBM®. Este solucionador aproveita o algoritmo bf-DCQO de ponta da Kipu, exigindo apenas a função objetivo como entrada para fornecer soluções de problemas automaticamente. Ele pode lidar com problemas de otimização que envolvem até 156 qubits, permitindo o uso de todos os qubits dos dispositivos quânticos do IBM. O Otimizador usa um mapeamento 1-to-1 entre variáveis clássicas e qubits, o que permite que você lide com problemas de otimização com até 156 variáveis binárias.

O Optimizer permite a solução de problemas de otimização binária sem restrições. Além da formulação QUBO (Quadratic Unconstrained Binary Optimization) comumente usada, ele também suporta problemas de otimização de ordem superior (HUBO). O solucionador utiliza um algoritmo quântico não-variacional, realizando a maior parte da computação em dispositivos quânticos.

A seguir, há mais detalhes sobre o algoritmo usado e um breve guia sobre como usar a função, além de resultados de benchmarking em várias instâncias de problemas de diferentes tamanhos e complexidades.


Descrição

O Optimizer é uma implementação pronta para uso de algoritmos de otimização quântica de ponta. Ele resolve problemas de otimização executando circuitos quânticos altamente compactados em hardware quântico. Essa compressão é obtida com a introdução de termos contra-diabáticos na evolução do tempo subjacente do sistema quântico. O algoritmo executa várias iterações de execuções de hardware para obter as soluções finais e as combina com o pós-processamento. Essas etapas são perfeitamente integradas ao fluxo de trabalho do Optimizer e são executadas automaticamente.

Como funciona o Otimizador Quântico?

Esta seção descreve os fundamentos do algoritmo bf-DCQO implementado. Uma introdução ao algoritmo também pode ser encontrada no canal Qiskit YouTube.

O algoritmo é baseado na evolução temporal de um sistema quântico que é transformado ao longo do tempo, em que a solução do problema é codificada no estado fundamental do sistema quântico no final da evolução. De acordo com o teorema adiabático, essa evolução deve ser lenta para garantir que o sistema permaneça em seu estado fundamental. A digitalização dessa evolução é a base da computação adiabática quântica digitalizada (DQA) e do famoso algoritmo QAOA. No entanto, a evolução lenta necessária não é viável para problemas de tamanhos cada vez maiores, pois resulta em um aumento da profundidade do circuito. Ao usar protocolos contra-diabáticos, você pode suprimir excitações indesejadas que ocorrem durante tempos curtos de evolução, enquanto permanece no estado fundamental. Aqui, a digitalização desse tempo de evolução mais curto resulta em circuitos quânticos com profundidade mais curta e menos portas de emaranhamento.

Os circuitos dos algoritmos bf-DCQO normalmente usam até dez vezes menos portas de emaranhamento do que o DQA e de três a quatro vezes menos portas de emaranhamento do que as implementações padrão do QAOA. Devido ao menor número de portas, ocorrem menos erros durante a execução do circuito no hardware. Portanto, o otimizador não requer o uso de técnicas como supressão ou atenuação de erros. Implementá-los em versões futuras pode melhorar ainda mais a qualidade da solução.

Embora o algoritmo bf-DCQO use iterações, ele é não-variacional. Após cada iteração do algoritmo, a distribuição dos estados é medida. A distribuição obtida é usada para calcular o chamado campo de polarização. O campo de polarização permite iniciar a próxima iteração a partir de um estado de energia próximo à solução encontrada anteriormente. Dessa forma, o algoritmo se move a cada iteração para soluções de menor energia. Normalmente, cerca de dez iterações são suficientes para convergir para uma solução, exigindo, no total, um número muito menor de iterações do que os algoritmos variacionais, que são da ordem de aproximadamente 100 iterações.

O otimizador combina o algoritmo bf-DCQO com o pós-processamento clássico. Depois de medir a distribuição dos estados, é realizada uma pesquisa local. Durante a pesquisa local, os bits da solução medida são invertidos aleatoriamente. Após a inversão, a energia da nova cadeia de bits é avaliada. Se a energia for menor, a bitstring será mantida como a nova solução. A pesquisa local é escalonada linearmente com o número de qubits; portanto, é computacionalmente barata. Como o pós-processamento corrige os erros de bit-flip locais, ele compensa os erros de bit-flip que geralmente são resultado de imperfeições de hardware e erros de leitura.

Fluxo de trabalho

Segue um esquema do fluxo de trabalho do Quantum Optimizer.

Fluxo de trabalho
Fluxo de trabalho do Quantum Optimizer

Ao usar o Quantum Optimizer, a solução de um problema de otimização em hardware quântico pode ser reduzida a

  • Formule a função objetiva do problema
  • Acesse o Otimizador por meio do Qiskit Functions
  • Execute o Optimizer e colete o resultado

Referências

As métricas de benchmark abaixo mostram que o Otimizador aborda com eficácia problemas que envolvem até 156 qubits e oferecem uma visão geral da precisão e da escalabilidade do otimizador em diferentes tipos de problemas. Observe que as métricas de desempenho reais podem variar dependendo das características específicas do problema, como o número de variáveis, a densidade e a localidade dos termos na função objetiva e a ordem polinomial.

A tabela a seguir inclui a taxa de aproximação (AR), uma métrica definida da seguinte forma:

AR=CCmaxCminCmax,AR = \frac{C^{*} - C_\textrm{max}}{C_{\textrm{min}} - C_{\textrm{max}}},

em que CC é a função objetiva, CminC_{\textrm{min}}, CmaxC_{\textrm{max}} são seus valores mínimo e máximo e CC^{*} é o custo da melhor solução encontrada, respectivamente. Portanto, AR=100% significa que o estado básico do problema foi obtido.

Exemplo
Número de qubits
Índice de aproximação
Tempo Total (s)
Uso do tempo de execução (s)
Número total de disparos
Número de iterações
Não ponderado MaxCut28100%1803030k5
Não ponderado MaxCut30100%1803030k5
Não ponderado MaxCut32100%1803030k5
Não ponderado MaxCut130100%4806090k9
Não ponderado MaxCut100100%3306060k6
Não ponderado MaxCut120100%3706060k6
HUBO 1156100%60065100k22
HUBO 2156100%60065100k22
  • As instâncias do MaxCut com 28, 30 e 32 qubits foram executadas no ibm_sherbrooke. As instâncias com 80, 100 e 120 foram executadas em um processador Heron r2.
  • As instâncias do HUBO também foram executadas em um processador Heron r2.

Todas as instâncias de benchmark podem ser acessadas em GitHub (consulte Instâncias de benchmark do Kipu ). Um exemplo para executar essas instâncias pode ser encontrado em Exemplo 3: Instâncias de benchmark.


Introdução

Nesta documentação, vamos percorrer as etapas de utilização do Iskay Quantum Optimizer. No processo, mostraremos rapidamente como carregar a função do catálogo e como converter seu problema em uma entrada válida, ao mesmo tempo em que mostramos como você pode experimentar diferentes parâmetros opcionais.

Para um exemplo mais detalhado, consulte o tutorial Resolva o problema da divisão de mercado com o Iskay Quantum Optimizer da Kipu Quantum, onde trabalhamos todo o processo de utilização do Iskay Solver para resolver o problema da divisão de mercado, que representa um desafio real de alocação de recursos, em que os mercados devem ser divididos em regiões de vendas equilibradas para atender às metas exatas de demanda.

Autentique-se usando sua chave de API, encontrada no painel da IBM Quantum Platform, e selecione a Qiskit Function da seguinte forma:

Note

O código a seguir pressupõe que você já tenha salvo suas credenciais. Caso ainda não tenha feito isso, siga as instruções na seção “Salvar sua conta do IBM Cloud ” para se autenticar com sua chave de API.

from qiskit_ibm_catalog import QiskitFunctionsCatalog

catalog = QiskitFunctionsCatalog(
    channel="ibm_quantum_platform",
    instance="INSTANCE_CRN",
    # For `token`, use the 44-character API_KEY you created
    # and saved from the IBM Quantum Platform Home dashboard
    token="YOUR_API_KEY",
)

# verify that you have access to the function
catalog.list()

Output:

[QiskitFunction(qunova/hivqe-chemistry),
 QiskitFunction(global-data-quantum/quantum-portfolio-optimizer),
 QiskitFunction(algorithmiq/tem),
 QiskitFunction(qedma/qesem),
 QiskitFunction(multiverse/singularity),
 QiskitFunction(ibm/circuit-function),
 QiskitFunction(q-ctrl/optimization-solver),
 QiskitFunction(colibritd/quick-pde),
 QiskitFunction(q-ctrl/performance-management),
 QiskitFunction(kipu-quantum/iskay-quantum-optimizer)]
# Access Function
optimizer = catalog.load("kipu-quantum/iskay-quantum-optimizer")

Exemplo de configuração personalizada

Veja como você pode configurar o Iskay com diferentes opções:

custom_options = {
    "shots": 15_000,  # Higher shot count for better statistics
    "num_iterations": 12,  # More iterations for solution refinement
    "preprocessing_level": 1,  # Light preprocessing for problem simplification
    "postprocessing_level": 2,  # Maximum postprocessing for solution quality
    "transpilation_level": 3,  # Use higher transpilation level to optimize circuit
    "seed_transpiler": 42,  # Fixed seed for reproducible results
    "job_tags": ["custom_config"],  # Custom tracking tags
}

Otimização da semente : Observe que seed_transpiler é definido como None por padrão. Isso permite o processo de otimização automática do transpiler. Quando None, o sistema iniciará um teste com várias sementes e selecionará aquela que produzir a melhor profundidade de circuito, aproveitando todo o poder do max_trials parâmetro para cada nível de transpilagem.

Desempenho do nível de transpilagem : aumentar o número de max_trials com valores mais altos para inevitavelmente transpilation_level aumentará o tempo de transpilagem, mas nem sempre alterará o circuito final — isso depende muito da estrutura e da complexidade específicas do circuito. Para alguns circuitos/problemas, no entanto, a diferença entre 10 tentativas (nível 1) e 50 tentativas (nível 5) pode ser dramática, portanto, explorar esses parâmetros pode ser a chave para encontrar uma solução com sucesso.


Exemplo 1: Função de custo simples

Considere a função de custo na formulação de spin:

C(x0,x1,x2,x3,x4)=1+1.5x0+2x1+1.3x2+2.5x0x3+3.5x1x4+4x0x1x2C(x_0, x_1, x_2, x_3, x_4) = 1 + 1.5x_0 + 2x_1 + 1.3x_2 + 2.5x_0x_3 + 3.5x_1x_4 + 4x_0x_1x_2

onde (x0,...,x4){1,1}5(x_0, ..., x_4) \in \{-1, 1\}^5.

A solução para essa função de custo simples é

(x0,x1,x2,x3,x4)=(1,1,1,1,1)(x_0, x_1, x_2, x_3, x_4) = (-1, -1, -1, 1, 1)

com valor mínimo C=6C^{*} = -6

1. Crie a função objetivo

Começamos criando um dicionário com os coeficientes da função objetiva da seguinte forma:

objective_func = {
    "()": 1,
    "(0,)": 1.5,
    "(1,)": 2,
    "(2,)": 1.3,
    "(0, 3)": 2.5,
    "(1, 4)": 3.5,
    "(0, 1, 2)": 4,
}

2. Execute o Otimizador

Resolvemos o problema executando o otimizador. Como (x0,...,x4){1,1}5(x_0, ..., x_4) \in \{-1, 1\}^5, devemos definir problem_type=spin.

# Setup options to run the optimizer
options = {"shots": 5000, "num_iterations": 5, "use_session": True}

arguments = {
    "problem": objective_func,
    "problem_type": "spin",
    "backend_name": backend_name,  # such as "ibm_fez"
    "options": options,
}

job = optimizer.run(**arguments)

# Print the ID so you can use it later, if necessary
print(job.job_id)

3. Recuperar o resultado

A solução do problema de otimização é fornecida diretamente pelo otimizador.

print(job.result())

Isso mostrará um dicionário do formulário:

{'solution': {'0': -1, '1': -1, '2': -1, '3': 1, '4': 1},
 'solution_info': {'bitstring': '11100',
  'cost': -13.8,
  'seed_transpiler': 42,
  'mapping': {0: 0, 1: 1, 2: 2, 3: 3, 4: 4}},
 'prob_type': 'spin'}

Observe que o dicionário solution exibe o vetor de resultados (x0,x1,x2,x3,x4)=(1,1,1,1,1)(x_0, x_1, x_2, x_3, x_4) = (-1, -1, -1, 1, 1).


Exemplo 2: MaxCut

Muitos problemas de gráficos, como MaxCut ou Maximum independent set, são problemas NP-hard e candidatos ideais para testar algoritmos e hardware quânticos. Este exemplo demonstra a solução do problema MaxCut de um gráfico 3-regular com o Quantum Optimizer.

Para executar este exemplo, você deve instalar o pacote networkx , além do qiskit-ibm-catalog. Para instalá-lo, execute o seguinte comando:

# %pip install networkx numpy

1. Crie a função objetivo

Comece gerando um gráfico 3-regular aleatório. Para esse gráfico, definimos a função objetiva do problema MaxCut.

import networkx as nx

# Create a random 3-regular graph
G = nx.random_regular_graph(3, 10, seed=42)


# Create the objective function for MaxCut in Ising formulation
def graph_to_ising_maxcut(G):
    """
    Convert a NetworkX graph to an Ising Hamiltonian for the max-cut problem.
    Args:
        G (networkx.Graph): The input graph.
    Returns:
        dict: The objective function of the Ising model
    """
    # Initialize the linear and quadratic coefficients
    objective_func = {}
    # Populate the coefficients
    for i, j in G.edges:
        objective_func[f"({i}, {j})"] = 0.5
    return objective_func


objective_func = graph_to_ising_maxcut(G)

2. Execute o Otimizador

Resolva o problema executando o otimizador.

options = {"shots": 5000, "num_iterations": 5, "use_session": True}

arguments = {
    "problem": objective_func,
    "problem_type": "spin",
    "backend_name": backend_name,  # such as "ibm_fez"
    "options": options,
}

job = optimizer.run(**arguments)

3. Recuperar o resultado

Recuperar o resultado e mapear a bitstring da solução de volta para os nós do gráfico original.

print(job.result())

A solução do problema Maxcut está contida diretamente no subdicionário solution do objeto de resultado

maxcut_solution = job.result()["solution"]

Exemplo 3: Instâncias de referência

As instâncias de referência estão disponíveis em Instâncias de referência do Kipu no GitHub:.

As instâncias podem ser carregadas usando a biblioteca pygithub . Para instalá-lo, execute o seguinte comando:

# %pip install pygithub

Os caminhos para as instâncias de benchmark são:

Maxcut:

  • 'maxcut/maxcut_regular_3_100_nodes_weighted.json'
  • 'maxcut/maxcut_regular_3_140_nodes_weighted.json'
  • 'maxcut/maxcut_regular_3_150_nodes_weighted.json'
  • 'maxcut/maxcut_regular_4_130_nodes_weighted.json'

HUBO:

  • 'HUBO/hubo1_marrakesh.json'
  • 'HUBO/hubo2_marrakesh.json'

Para reproduzir o desempenho do parâmetro de comparação para as instâncias do HUBO, selecione o backend ibm_marrakesh e defina direct_qubit_mapping como True no subdicionário options .

O exemplo a seguir executa a instância do Maxcut com 150 nós.

from github import Github
import urllib
import json
import ast

repo = "Kipu-Quantum-GmbH/benchmark-instances"
path = "maxcut/maxcut_regular_3_150_nodes_weighted.json"
gh = Github()
repo = gh.get_repo(repo)
branch = "main"
file = repo.get_contents(urllib.parse.quote(path), ref=branch)

# load json file with benchmark problem
problem_json = json.loads(file.decoded_content)

# convert objective function to compatible format
objective_func = {
    key: ast.literal_eval(value) for key, value in problem_json.items()
}


# Setup configuration to run the optimizer
options = {
    "shots": 5_000,
    "num_iterations": 5,
    "use_session": True,
    "direct_qubit_mapping": False,
}

arguments = {
    "problem": objective_func,
    "problem_type": "spin",
    "backend_name": "<BACKEND-NAME>",
    "options": options,
}

job = optimizer.run(**arguments)

result = job.result()

Casos de uso

Os casos de uso típicos do solucionador de otimização são problemas de otimização combinatória. Você pode resolver problemas de vários setores, como financeiro, farmacêutico ou de logística. Seguem-se alguns exemplos:

Se você estiver interessado em abordar um caso de uso específico e desenvolver um mapeamento dedicado, podemos ajudá-lo. Entre em contato conosco.


Obtenha suporte

Para obter suporte, entre em contato com [email protected].


Próximas etapas


Informações Adicionais

Iskay, assim como o nome de nossa empresa, Kipu Quantum, é uma palavra peruana. Embora sejamos uma startup da Alemanha, essas palavras vêm do país natal de um de nossos cofundadores, onde o Quipu foi uma das primeiras máquinas de calcular desenvolvidas pela humanidade há 2000 anos a.C.

Esta página foi útil?
Relate um bug, erro de digitação ou solicite conteúdo no GitHub.