Algoritma optimasi perkiraan kuantum
Perkiraan penggunaan: 22 menit pada prosesor Heron r3 (CATATAN: Ini hanya perkiraan. Waktu aktual kamu bisa berbeda.)
Hasil pembelajaran
Setelah menyelesaikan tutorial ini, kamu diharapkan memahami informasi berikut:
- Cara memetakan masalah optimasi kombinatorial klasik (max-cut) ke sebuah Hamiltonian kuantum
- Cara mengimplementasikan dan menjalankan Quantum Approximate Optimization Algorithm (QAOA) menggunakan session Qiskit Runtime
- Cara menskalakan alur kerja QAOA dari contoh simulator kecil ke eksekusi perangkat keras skala utilitas
Prasyarat
Disarankan kamu membiasakan diri dengan topik-topik ini:
- Dasar-dasar circuit kuantum
- Algoritma variasional
- QAOA secara mendalam — untuk pembahasan menyeluruh tentang algoritma QAOA dan penerapannya pada skala utilitas
Latar belakang
Quantum Approximate Optimization Algorithm (QAOA) adalah metode iteratif hibrida kuantum-klasik untuk memecahkan masalah optimasi kombinatorial. Dalam tutorial ini, kamu akan menggunakan QAOA untuk memecahkan masalah maximum-cut (max-cut) — sebuah masalah optimasi NP-hard dengan aplikasi dalam klasterisasi, ilmu jaringan, dan fisika statistik. Diberikan sebuah graf berisi simpul-simpul yang terhubung oleh sisi, tujuannya adalah membagi simpul-simpul ke dalam dua himpunan sedemikian rupa sehingga jumlah sisi yang melintasi partisi dimaksimalkan.

Dari optimasi klasik ke circuit kuantum
Max-cut dapat dinyatakan sebagai masalah optimasi biner klasik. Setiap simpul diberi sebuah variabel biner yang menunjukkan himpunan mana ia berada. Tujuannya adalah memaksimalkan jumlah sisi di mana titik-titik ujungnya berada dalam himpunan yang berbeda:
Ini secara ekuivalen merupakan masalah Quadratic Unconstrained Binary Optimization (QUBO) berbentuk . Melalui substitusi variabel standar (), QUBO dapat ditulis ulang sebagai sebuah Hamiltonian biaya yang keadaan dasarnya mengkodekan solusi optimal. Secara umum, Hamiltonian ini memiliki suku kuadratik maupun linier:
Untuk masalah max-cut tak berbobot yang dipertimbangkan di sini, koefisien linier menghilang () dan untuk setiap sisi, sehingga tersisa bentuk yang lebih sederhana yang akan kamu bangun dalam kode di bawah. Bentuk yang lebih umum di atas adalah apa yang kamu butuhkan untuk mengadaptasi alur kerja ini ke graf berbobot atau masalah lain yang dapat dinyatakan sebagai QUBO.
Cara kerja QAOA
QAOA menyiapkan solusi kandidat dengan menerapkan lapisan-lapisan berselang-seling dari dua operator pada sebuah keadaan superposisi awal : operator biaya dan sebuah operator mixer . Sudut-sudut dan dioptimalkan dalam loop umpan balik klasik; komputer kuantum mengevaluasi fungsi biaya, dan sebuah pengoptimal klasik memperbarui parameter sampai konvergen. Loop iteratif ini berjalan di dalam sebuah session Qiskit Runtime, yang menjaga perangkat kuantum tetap dipesan sepanjang iterasi untuk latensi yang lebih rendah.
Untuk pembahasan teori QAOA yang lebih mendalam, termasuk penurunan QUBO-ke-Hamiltonian lengkap, lihat modul kursus QAOA.
Dalam tutorial ini kamu pertama-tama akan memecahkan max-cut pada sebuah graf kecil lima-simpul, lalu menskalakan alur kerja yang sama ke masalah skala utilitas 100-simpul pada perangkat keras nyata. Catatan tentang akses paket: Tutorial ini menggunakan session Qiskit Runtime, yang hanya tersedia pada Premium Plan. Jika kamu menggunakan Open Plan, kamu tidak dapat menjalankan tutorial ini sebagaimana ditulis; sebagai gantinya, kamu perlu menukar Session dengan job mode (yaitu, kirim setiap iterasi sebagai job independen alih-alih membungkus loop optimasi dengan Session(...)). Alur kerja tetap berjalan, tetapi setiap iterasi menanggung latensi antrean penuh alih-alih menggunakan kembali perangkat yang dipesan. Lihat Gambaran umum paket yang tersedia untuk informasi lebih lanjut.
Persyaratan
Sebelum memulai tutorial ini, pastikan kamu telah menginstal hal-hal berikut:
- Qiskit SDK v2.0 atau lebih baru, dengan dukungan visualisasi
- Qiskit Runtime v0.22 atau lebih baru (
pip install qiskit-ibm-runtime)
Selain itu, kamu memerlukan akses ke sebuah instance di IBM Quantum® Platform.
Setup
# 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
Contoh skala kecil
Bagian ini memandu kamu melalui setiap langkah alur kerja QAOA pada sebuah instance max-cut kecil lima-simpul. Meskipun berlabel "skala kecil", contoh ini tetap berjalan pada perangkat keras IBM Quantum nyata — kode memilih sebuah backend dengan 127 qubit atau lebih dan mengeksekusi circuit di sana. Inisialisasi masalahmu dengan membuat sebuah graf berisi simpul.
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)
Langkah 1: Petakan input klasik ke masalah kuantum
Petakan graf klasik ke dalam circuit dan operator kuantum. Seperti dijelaskan dalam Latar belakang, untuk max-cut tak berbobot Hamiltonian biaya tereduksi menjadi , dan QAOA menggunakan sebuah circuit ansatz terparametrasi untuk menyiapkan keadaan dasar kandidat dari .
Bangun Hamiltonian biaya
Konversikan sisi-sisi graf menjadi suku Pauli untuk membangun (lihat Latar belakang untuk penurunannya).
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])
Bangun circuit ansatz QAOA
Gunakan QAOAAnsatz untuk membangun circuit QAOA terparametrasi dari Hamiltonian biaya. Di sini kita menggunakan reps=2 (dua lapisan QAOA, empat parameter: ).
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])])
Langkah 2: Optimalkan masalah untuk eksekusi perangkat keras kuantum
Transpilasikan circuit abstrak menjadi instruksi native perangkat keras. Langkah ini menangani pemetaan qubit, dekomposisi gate, perutean, dan penekanan kesalahan. Lihat dokumentasi transpilasi untuk informasi lebih lanjut.
service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=127
)
print(backend)
# Create pass manager for transpilation. Level 3 is the most aggressive
# preset: slower to transpile, but produces shorter circuits that are
# more robust to hardware noise.
pm = generate_preset_pass_manager(optimization_level=3, backend=backend)
candidate_circuit = pm.run(circuit)
candidate_circuit.draw("mpl", fold=False, idle_wires=False)
<IBMBackend('ibm_pittsburgh')>

Langkah 3: Eksekusi menggunakan primitif Qiskit
Loop optimasi QAOA berjalan di dalam sebuah session Qiskit Runtime untuk menjaga perangkat tetap dipesan sepanjang iterasi. Sebuah Estimator mengevaluasi pada setiap langkah, dan sebuah pengoptimal klasik (COBYLA) memperbarui parameter sampai konvergen.
Tentukan parameter awal dan jalankan loop optimasi:
# QAOA doesn't prescribe principled default angles — any bounded choice
# works as a warm start for problems this small. beta and gamma are
# periodic (beta in [0, pi] and gamma in [0, 2*pi] modulo the underlying
# Pauli-rotation periods), and pi/2 and pi are just midpoints of those
# ranges. For harder problems you would typically warm start from known
# good angles or transfer parameters from smaller instances.
initial_gamma = np.pi
initial_beta = np.pi / 2
init_params = [initial_beta, initial_beta, initial_gamma, initial_gamma]
def cost_func_estimator(params, ansatz, hamiltonian, estimator):
# transform the observable defined on virtual qubits to
# an observable defined on all physical qubits
isa_hamiltonian = hamiltonian.apply_layout(ansatz.layout)
pub = (ansatz, isa_hamiltonian, params)
job = estimator.run([pub])
results = job.result()[0]
cost = results.data.evs
objective_func_vals.append(cost)
return cost
objective_func_vals = [] # Global variable
with Session(backend=backend) as session:
# If using qiskit-ibm-runtime<0.24.0, change `mode=` to `session=`
estimator = Estimator(mode=session)
estimator.options.default_shots = 1000
# Set simple error suppression/mitigation options
estimator.options.dynamical_decoupling.enable = True
estimator.options.dynamical_decoupling.sequence_type = "XY4"
estimator.options.twirling.enable_gates = True
estimator.options.twirling.num_randomizations = "auto"
estimator.options.environment.job_tags = ["TUT_QAOA"]
result = minimize(
cost_func_estimator,
init_params,
args=(candidate_circuit, cost_hamiltonian, estimator),
method="COBYLA",
tol=1e-2,
)
print(result)
message: Return from COBYLA because the trust region radius reaches its lower bound.
success: True
status: 0
fun: -2.0402211719947774
x: [ 3.041e+00 1.212e+00 2.081e+00 4.471e+00]
nfev: 36
maxcv: 0.0
Pengoptimal berhasil mengurangi biaya dan menemukan parameter yang lebih baik untuk circuit.
Kurva yang menurun secara mulus dan kemudian mendatar adalah ciri khas konvergensi. Kurva yang berisik dan tidak monoton biasanya menunjukkan bahwa ada sesuatu di hulu yang perlu diperhatikan; penyebab umumnya adalah terlalu sedikit shot per evaluasi (varians estimator tinggi), parameter awal yang buruk, atau circuit yang kedalamannya didominasi oleh noise perangkat keras. COBYLA bebas turunan dan cukup tahan terhadap noise sedang, tetapi ketika noise menenggelamkan peningkatan biaya yang sebenarnya per langkah, model aproksimasi liniernya tidak lagi dapat membedakan penurunan nyata dari jitter acak dan pengoptimal pun mengembara.
plt.figure(figsize=(12, 6))
plt.plot(objective_func_vals)
plt.xlabel("Iteration")
plt.ylabel("Cost")
plt.show()
Tetapkan parameter yang telah dioptimalkan dan ambil sampel distribusi akhir menggunakan primitif Sampler.
optimized_circuit = candidate_circuit.assign_parameters(result.x)
optimized_circuit.draw("mpl", fold=False, idle_wires=False)

# If using qiskit-ibm-runtime<0.24.0, change `mode=` to `backend=`
sampler = Sampler(mode=backend)
sampler.options.default_shots = 10000
# Set simple error suppression/mitigation options
sampler.options.dynamical_decoupling.enable = True
sampler.options.dynamical_decoupling.sequence_type = "XY4"
sampler.options.twirling.enable_gates = True
sampler.options.twirling.num_randomizations = "auto"
sampler.options.environment.job_tags = ["TUT_QAOA"]
pub = (optimized_circuit,)
job = sampler.run([pub], shots=int(1e4))
counts_int = job.result()[0].data.meas.get_int_counts()
counts_bin = job.result()[0].data.meas.get_counts()
shots = sum(counts_int.values())
final_distribution_int = {key: val / shots for key, val in counts_int.items()}
final_distribution_bin = {key: val / shots for key, val in counts_bin.items()}
print(final_distribution_int)
{18: 0.039, 5: 0.0665, 20: 0.0973, 29: 0.0063, 9: 0.0899, 13: 0.0379, 2: 0.0047, 1: 0.0153, 11: 0.0932, 14: 0.0327, 12: 0.0314, 25: 0.0193, 21: 0.0398, 6: 0.0224, 4: 0.0197, 10: 0.0387, 3: 0.0181, 26: 0.07, 17: 0.0327, 19: 0.0332, 22: 0.0914, 24: 0.007, 0: 0.0033, 8: 0.0066, 30: 0.0158, 28: 0.0169, 27: 0.0222, 16: 0.0073, 7: 0.0057, 23: 0.0062, 15: 0.0054, 31: 0.0041}
Langkah 4: Pasca-proses dan kembalikan hasil dalam format klasik yang diinginkan
Ekstrak bitstring yang paling mungkin dari distribusi yang telah diambil sampelnya. Ini merepresentasikan potongan terbaik yang ditemukan oleh QAOA.
# auxiliary functions to sample most likely bitstring
def to_bitstring(integer, num_bits):
result = np.binary_repr(integer, width=num_bits)
return [int(digit) for digit in result]
keys = list(final_distribution_int.keys())
values = list(final_distribution_int.values())
most_likely = keys[np.argmax(np.abs(values))]
most_likely_bitstring = to_bitstring(most_likely, len(graph))
most_likely_bitstring.reverse()
print("Result bitstring:", most_likely_bitstring)
Result bitstring: [0, 0, 1, 0, 1]
plt.rcParams.update({"font.size": 10})
final_bits = final_distribution_bin
values = np.abs(list(final_bits.values()))
top_4_values = sorted(values, reverse=True)[:4]
positions = []
for value in top_4_values:
positions.append(np.where(values == value)[0])
fig = plt.figure(figsize=(11, 6))
ax = fig.add_subplot(1, 1, 1)
plt.xticks(rotation=45)
plt.title("Result Distribution")
plt.xlabel("Bitstrings (reversed)")
plt.ylabel("Probability")
ax.bar(list(final_bits.keys()), list(final_bits.values()), color="tab:grey")
for p in positions:
ax.get_children()[int(p[0])].set_color("tab:purple")
plt.show()
Visualisasikan potongan terbaik
Dari bitstring optimal, kamu kemudian dapat memvisualisasikan potongan ini pada graf asli.
# auxiliary function to plot graphs
def plot_result(G, x):
colors = ["tab:grey" if i == 0 else "tab:purple" for i in x]
pos, _default_axes = rx.spring_layout(G), plt.axes(frameon=True)
rx.visualization.mpl_draw(
G, node_color=colors, node_size=100, alpha=0.8, pos=pos
)
plot_result(graph, most_likely_bitstring)
Sekarang, hitung nilai potongannya:
def evaluate_sample(x: Sequence[int], graph: rx.PyGraph) -> float:
assert len(x) == len(
list(graph.nodes())
), "The length of x must coincide with the number of nodes in the graph."
return sum(
x[u] * (1 - x[v]) + x[v] * (1 - x[u])
for u, v in list(graph.edge_list())
)
cut_value = evaluate_sample(most_likely_bitstring, graph)
print("The value of the cut is:", cut_value)
The value of the cut is: 5
Untuk graf sekecil ini, optimum sebenarnya mudah dicari dengan brute-force, sehingga kamu dapat memeriksa ulang hasilnya dengan membandingkan hasil QAOA terhadap jawaban eksak.
# Classical baseline: enumerate all 2**n_small bitstrings and take the best cut.
def brute_force_max_cut(graph: rx.PyGraph) -> tuple[int, list[int]]:
n = len(list(graph.nodes()))
best_cut = -1
best_x: list[int] = []
for i in range(2**n):
x = [(i >> k) & 1 for k in range(n)]
cut = evaluate_sample(x, graph)
if cut > best_cut:
best_cut = int(cut)
best_x = x
return best_cut, best_x
classical_best, classical_x = brute_force_max_cut(graph)
print(f"Classical optimum (brute force): {classical_best}")
print(f"QAOA cut value: {cut_value}")
Classical optimum (brute force): 5
QAOA cut value: 5
Contoh perangkat keras skala besar
Kamu memiliki akses ke banyak perangkat dengan lebih dari 100 qubit di IBM Quantum Platform. Pilih salah satu untuk memecahkan max-cut pada sebuah graf berbobot 100-simpul. Ini adalah masalah "skala utilitas". Alur kerjanya mengikuti langkah-langkah yang sama seperti di atas, diterapkan pada graf yang jauh lebih besar.
Alur kerja menyeluruh pada skala utilitas
Keempat langkah ditunjukkan di bawah, diterapkan pada graf 100-simpul. Strukturnya sama dengan panduan skala kecil: petakan, transpilasi, eksekusi, pasca-proses — tetapi dengan masalah yang lebih besar dan dibagi ke dalam empat sel di bawah agar lebih jelas.
# Precomputed parity lookup table: _PARITY[b] = +1 if popcount(b) is even, else -1.
# We use this to vectorize expectation-value evaluation across all Pauli terms.
_PARITY = np.array(
[-1 if bin(i).count("1") % 2 else 1 for i in range(256)],
dtype=np.complex128,
)
def evaluate_sparse_pauli(state: int, observable: SparsePauliOp) -> complex:
"""Expectation value of a SparsePauliOp on a single computational-basis state.
For a Z-only observable (which QAOA cost Hamiltonians are, after the
QUBO-to-Hamiltonian mapping), the eigenvalue of each Pauli term on a
computational-basis state is simply (-1)**popcount(z_mask AND state),
i.e., the parity of the bitwise-AND of the term's Z-support and the
measured bitstring.
This routine packs the Z-support of every Pauli term into bytes, ANDs
them against the measured state in a single vectorized op, and looks up
the parity in _PARITY. For a 100-qubit / ~hundreds-of-terms Hamiltonian
over 10_000 samples, this is dramatically faster than calling
SparsePauliOp.expectation_value per sample.
"""
packed_uint8 = np.packbits(observable.paulis.z, axis=1, bitorder="little")
state_bytes = np.frombuffer(
state.to_bytes(packed_uint8.shape[1], "little"), dtype=np.uint8
)
reduced = np.bitwise_xor.reduce(packed_uint8 & state_bytes, axis=1)
return np.sum(observable.coeffs * _PARITY[reduced])
def best_solution(samples, hamiltonian):
"""Return the sampled bitstring (as int) with the lowest Hamiltonian cost."""
min_cost = float("inf")
min_sol = None
for bit_str in samples.keys():
candidate_sol = int(bit_str)
fval = evaluate_sparse_pauli(candidate_sol, hamiltonian).real
if fval <= min_cost:
min_cost = fval
min_sol = candidate_sol
return min_sol
def _plot_cdf(objective_values: dict, ax, color):
x_vals = sorted(objective_values.keys(), reverse=True)
y_vals = np.cumsum([objective_values[x] for x in x_vals])
ax.plot(x_vals, y_vals, color=color)
def plot_cdf(dist, ax, title):
_plot_cdf(dist, ax, "C1")
ax.vlines(min(list(dist.keys())), 0, 1, "C1", linestyle="--")
ax.set_title(title)
ax.set_xlabel("Objective function value")
ax.set_ylabel("Cumulative distribution function")
ax.grid(alpha=0.3)
def samples_to_objective_values(samples, hamiltonian):
"""Convert the samples to values of the objective function."""
objective_values = defaultdict(float)
for bit_str, prob in samples.items():
candidate_sol = int(bit_str)
fval = evaluate_sparse_pauli(candidate_sol, hamiltonian).real
objective_values[fval] += prob
return objective_values
Langkah 1: Bangun graf, Hamiltonian biaya, dan ansatz.
# Step 1: build the 100-node graph, cost Hamiltonian, and QAOA ansatz.
n_large = 100
graph_100 = rx.PyGraph()
graph_100.add_nodes_from(np.arange(0, n_large, 1))
elist = []
for edge in backend.coupling_map:
if edge[0] < n_large and edge[1] < n_large:
elist.append((edge[0], edge[1], 1.0))
graph_100.add_edges_from(elist)
max_cut_paulis_100 = build_max_cut_paulis(graph_100)
cost_hamiltonian_100 = SparsePauliOp.from_sparse_list(
max_cut_paulis_100, n_large
)
circuit_100 = QAOAAnsatz(cost_operator=cost_hamiltonian_100, reps=1)
circuit_100.measure_all()
Langkah 2: Transpilasikan untuk backend perangkat keras yang dipilih.
# Step 2: transpile for hardware.
pm = generate_preset_pass_manager(optimization_level=3, backend=backend)
candidate_circuit_100 = pm.run(circuit_100)
Langkah 3: Jalankan loop optimasi QAOA di dalam sebuah session, lalu ambil sampelnya.
# Step 3: run the QAOA optimization loop on the device, then sample the
# final distribution with the optimized parameters.
initial_gamma = np.pi
initial_beta = np.pi / 2
init_params = [initial_beta, initial_gamma]
objective_func_vals = [] # Global variable
with Session(backend=backend) as session:
estimator = Estimator(mode=session)
estimator.options.default_shots = 1000
# Set simple error suppression/mitigation options
estimator.options.dynamical_decoupling.enable = True
estimator.options.dynamical_decoupling.sequence_type = "XY4"
estimator.options.twirling.enable_gates = True
estimator.options.twirling.num_randomizations = "auto"
estimator.options.environment.job_tags = ["TUT_QAOA"]
result = minimize(
cost_func_estimator,
init_params,
args=(candidate_circuit_100, cost_hamiltonian_100, estimator),
method="COBYLA",
)
print(result)
# Assign optimal parameters and sample the final distribution.
optimized_circuit_100 = candidate_circuit_100.assign_parameters(result.x)
sampler = Sampler(mode=backend)
sampler.options.default_shots = 10000
# Set simple error suppression/mitigation options
sampler.options.dynamical_decoupling.enable = True
sampler.options.dynamical_decoupling.sequence_type = "XY4"
sampler.options.twirling.enable_gates = True
sampler.options.twirling.num_randomizations = "auto"
# Add a unique tag to the job execution
sampler.options.environment.job_tags = ["TUT_QAOA"]
pub = (optimized_circuit_100,)
job = sampler.run([pub], shots=int(1e4))
counts_int = job.result()[0].data.meas.get_int_counts()
shots = sum(counts_int.values())
final_distribution_100_int = {
key: val / shots for key, val in counts_int.items()
}
message: Return from COBYLA because the trust region radius reaches its lower bound.
success: True
status: 0
fun: -17.172689238986344
x: [ 2.574e+00 4.166e+00]
nfev: 28
maxcv: 0.0
Langkah 4: Pasca-proses distribusi yang diambil sampelnya untuk mengekstrak potongan terbaik.
# Step 4: find the best-cost sample and evaluate its cut value.
best_sol_100 = best_solution(final_distribution_100_int, cost_hamiltonian_100)
best_sol_bitstring_100 = to_bitstring(int(best_sol_100), len(graph_100))
best_sol_bitstring_100.reverse()
print("Result bitstring:", best_sol_bitstring_100)
cut_value_100 = evaluate_sample(best_sol_bitstring_100, graph_100)
print("The value of the cut is:", cut_value_100)
Result bitstring: [1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0]
The value of the cut is: 156
Periksa bahwa biaya yang diminimalkan dalam loop optimasi telah konvergen, dan visualisasikan hasilnya.
# Plot convergence
plt.figure(figsize=(12, 6))
plt.plot(objective_func_vals)
plt.xlabel("Iteration")
plt.ylabel("Cost")
plt.show()
# Visualize the cut
plot_result(graph_100, best_sol_bitstring_100)
# Plot cumulative distribution function
result_dist = samples_to_objective_values(
final_distribution_100_int, cost_hamiltonian_100
)
fig, ax = plt.subplots(1, 1, figsize=(8, 6))
plot_cdf(result_dist, ax, backend.name)

Langkah selanjutnya
Jika kamu merasa karya ini menarik, kamu mungkin tertarik dengan materi berikut:
- Teknik lanjutan untuk QAOA — mengeksplorasi strategi lanjutan untuk meningkatkan performa QAOA
- Tantangan optimasi multi-objektif — uji kemampuanmu dengan tantangan komunitas tentang optimasi kuantum multi-objektif ini
- Dokumentasi transpilasi untuk penyetelan halus optimasi circuit
- Penekanan dan mitigasi kesalahan untuk meningkatkan hasil perangkat keras