Квантовий алгоритм наближеної оптимізації
Оцінка використання: 22 хвилини на процесорі Heron r3 (ПРИМІТКА: Це лише оцінка. Твій час виконання може відрізнятися.)
Результати навчання
Після завершення цього посібника ти зможеш зрозуміти таку інформацію:
- Як відобразити класичну задачу комбінаторної оптимізації (max-cut) на квантовий гамільтоніан
- Як реалізувати та запустити Квантовий алгоритм наближеної оптимізації (QAOA) з використанням сесій Qiskit Runtime
- Як масштабувати робочий процес QAOA від невеликого прикладу на симуляторі до виконання на обладнанні утилітарного масштабу
Передумови
Рекомендується ознайомитися з такими темами:
- Основи квантових контурів
- Варіаційні алгоритми
- QAOA поглиблено — для всебічного розгляду алгоритму QAOA та його застосування на утилітарному масштабі
Передумови
Квантовий алгоритм наближеної оптимізації (QAOA) — це гібридний квантово-класичний ітеративний метод для розв'язання задач комбінаторної оптимізації. У цьому посібнику ти використаєш QAOA для розв'язання задачі максимального розрізу (max-cut) — NP-важкої задачі оптимізації із застосуваннями в кластеризації, мережевій науці та статистичній фізиці. Маючи граф вузлів, з'єднаних ребрами, мета полягає в тому, щоб розбити вузли на два набори так, щоб кількість ребер, що перетинають розбиття, була максимальною.

Від класичної оптимізації до квантових контурів
Max-cut можна виразити як класичну задачу бінарної оптимізації. Кожному вузлу присвоюється бінарна змінна , що вказує, до якого набору він належить. Мета полягає в максимізації кількості ребер, кінці яких знаходяться в різних наборах:
Це еквівалентно задачі квадратичної необмеженої бінарної оптимізації (QUBO) вигляду . Через стандартну заміну змінних () QUBO можна переписати як гамільтоніан вартості, основний стан якого кодує оптимальний розв'язок. Загалом цей гамільтоніан має як квадратичні, так і лінійні члени:
Для незваженої задачі max-cut, яка тут розглядається, лінійні коефіцієнти зникають (), а для кожного ребра, що залишає простішу форму , яку ти побудуєш у коді нижче. Більш загальна форма вище — це те, що тобі знадобиться, щоб адаптувати цей робочий процес до зважених графів чи інших задач, виразних через QUBO.
Як працює QAOA
QAOA готує розв'язки-кандидати, застосовуючи почергові шари двох операторів до початкового стану суперпозиції : оператора вартості та оператора-змішувача . Кути і оптимізуються в класичному циклі зворотного зв'язку; квантовий комп'ютер обчислює функцію вартості, а класичний оптимізатор оновлює параметри до збіжності. Цей ітеративний цикл виконується в межах сесії Qiskit Runtime, яка тримає квантовий пристрій зарезервованим протягом ітерацій для нижчої затримки.
Для глибшого розгляду теорії QAOA, включно з повним виведенням від QUBO до гамільтоніана, дивись модуль курсу QAOA.
У цьому посібнику ти спочатку розв'яжеш max-cut на невеликому графі з п'яти вузлів, а потім масштабуєш той самий робочий процес до задачі утилітарного масштабу зі 100 вузлами на реальному обладнанні. Примітка щодо доступу за планом: Цей посібник використовує сесії Qiskit Runtime, які доступні лише на Преміум плані. Якщо ти на Відкритому плані, ти не можеш виконати цей посібник у такому вигляді; натомість тобі потрібно буде замінити Session на режим завдань (тобто надсилати кожну ітерацію як незалежне завдання, а не загортати цикл оптимізації в with Session(...)). Робочий процес усе одно виконується, але кожна ітерація зазнає повної затримки черги замість повторного використання зарезервованого пристрою. Дивись Огляд доступних планів для додаткової інформації.
Вимоги
Перед початком цього посібника переконайся, що в тебе встановлено таке:
- Qiskit SDK v2.0 або пізніше, з підтримкою візуалізації
- Qiskit Runtime v0.22 або пізніше (
pip install qiskit-ibm-runtime)
Крім того, тобі знадобиться доступ до екземпляра на IBM Quantum® Platform.
Налаштування
# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit qiskit-ibm-runtime rustworkx scipy
import matplotlib.pyplot as plt
import rustworkx as rx
from rustworkx.visualization import mpl_draw as draw_graph
import numpy as np
from scipy.optimize import minimize
from collections import defaultdict
from typing import Sequence
from qiskit.quantum_info import SparsePauliOp
from qiskit.circuit.library import QAOAAnsatz
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import Session, EstimatorV2 as Estimator
from qiskit_ibm_runtime import SamplerV2 as Sampler
Приклад малого масштабу
Цей розділ проходить через кожен крок робочого процесу QAOA на невеликому екземплярі max-cut з п'яти вузлів. Попри позначку «малий масштаб», цей приклад усе одно виконується на реальному обладнанні IBM Quantum — код обирає Backend зі 127 або більше Qubit і виконує там Circuit. Ініціалізуй свою задачу, створивши граф з вузлами.
n_small = 5
graph = rx.PyGraph()
graph.add_nodes_from(np.arange(0, n_small, 1))
edge_list = [
(0, 1, 1.0),
(0, 2, 1.0),
(0, 4, 1.0),
(1, 2, 1.0),
(2, 3, 1.0),
(3, 4, 1.0),
]
graph.add_edges_from(edge_list)
draw_graph(graph, node_size=600, with_labels=True)
Крок 1: Відображення класичних входів на квантову задачу
Відобрази класичний граф у квантові Circuit та оператори. Як описано в розділі Передумови, для незваженого max-cut гамільтоніан вартості зводиться до , а QAOA використовує параметризований контур-ансац для підготовки основних станів-кандидатів .
Побудова гамільтоніана вартості
Перетвори ребра графа на члени Паулі , щоб побудувати (дивись Передумови для виведення).
def build_max_cut_paulis(
graph: rx.PyGraph,
) -> list[tuple[str, list[int], float]]:
"""Convert graph edges to a list of ZZ Pauli terms.
The returned list is in the sparse format expected by
``SparsePauliOp.from_sparse_list``: each element is
``(pauli_string, qubit_indices, coefficient)``.
"""
pauli_list = []
for edge in list(graph.edge_list()):
weight = graph.get_edge_data(edge[0], edge[1])
pauli_list.append(("ZZ", [edge[0], edge[1]], weight))
return pauli_list
max_cut_paulis = build_max_cut_paulis(graph)
cost_hamiltonian = SparsePauliOp.from_sparse_list(max_cut_paulis, n_small)
print("Cost Function Hamiltonian:", cost_hamiltonian)
Cost Function Hamiltonian: SparsePauliOp(['IIIZZ', 'IIZIZ', 'ZIIIZ', 'IIZZI', 'IZZII', 'ZZIII'],
coeffs=[1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j])
Побудова контуру-ансацу QAOA
Використовуй QAOAAnsatz, щоб побудувати параметризований Circuit QAOA з гамільтоніана вартості. Тут ми використовуємо reps=2 (два шари QAOA, чотири параметри: ).
circuit = QAOAAnsatz(cost_operator=cost_hamiltonian, reps=2)
circuit.measure_all()
circuit.draw("mpl")
circuit.parameters
ParameterView([ParameterVectorElement(β[0]), ParameterVectorElement(β[1]), ParameterVectorElement(γ[0]), ParameterVectorElement(γ[1])])