Algoritma kuantum: Algoritma kuantum variatif
Takashi Imamichi (24 Mei 2024)
Unduh pdf dari kuliah aslinya. Perlu dicatat bahwa beberapa potongan kode mungkin sudah tidak berlaku karena ini adalah gambar statis.
Perkiraan waktu QPU untuk menjalankan eksperimen ini adalah 9 menit (diuji pada prosesor Eagle).
(notebook ini mungkin tidak dapat dievaluasi dalam waktu yang tersedia di Open Plan. Mohon gunakan sumber daya komputasi kuantum dengan bijak.)
1. Pengenalan
Tutorial ini memberikan gambaran umum tentang algoritma hibrida kuantum-klasik, khususnya berfokus pada variational quantum eigensolver (VQE) dan quantum approximate optimization algorithm (QAOA). Tujuan utama dari algoritma-algoritma ini adalah untuk menangani masalah optimasi dengan menggunakan Circuit kuantum yang memiliki Gate kuantum terparameter.
Meskipun ada kemajuan dalam komputasi kuantum, kehadiran noise pada perangkat kuantum saat ini membuat sulit untuk mengekstrak hasil yang bermakna dari Circuit kuantum yang dalam. Untuk mengatasi tantangan ini, VQE dan QAOA mengadopsi pendekatan hibrida kuantum-klasik, yang melibatkan eksekusi iteratif Circuit kuantum yang relatif pendek menggunakan komputasi kuantum dan mengoptimalkan parameter Circuit kuantum terparameter target menggunakan komputasi klasik.
QAOA berpotensi memberikan solusi optimal untuk masalah target pada skala utilitas, berkat penerapan berbagai teknik mitigasi dan supresi error. VQE memiliki banyak aplikasi (seperti kimia kuantum) di mana skalabilitasnya lebih terbatas. Namun, ada sejumlah pendekatan berbasis nilai eigen yang muncul untuk melengkapi dan meningkatkan VQE, termasuk diagonalisasi subruang Krylov dan sampling-based quantum diagonalization (SQD). Memahami VQE adalah langkah pertama yang penting dalam memahami berbagai algoritma hibrida klasik-kuantum yang telah muncul.
Modul ini menjelaskan konsep dasar dan implementasi VQE dan QAOA. Tutorial lebih lanjut akan mengeksplorasi topik dan teknik lanjutan untuk menskalakan algoritma-algoritma ini. Kamu membutuhkan library berikut di lingkunganmu untuk menjalankan notebook ini. Jika kamu belum menginstalnya, kamu bisa menginstalnya dengan menghapus tanda komentar dan menjalankan sel berikut.
# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit qiskit-ibm-runtime rustworkx scipy
# % pip install 'qiskit[visualization]' qiskit-ibm-runtime
2. Menghitung nilai eigen minimum dari Hamiltonian sederhana
Kita akan mulai dengan menerapkan VQE pada kasus yang sangat sederhana, untuk melihat cara kerjanya. Kita akan menghitung nilai eigen minimum dari matriks Pauli dengan VQE. Kita akan mulai dengan mengimpor beberapa paket umum.
import numpy as np
from qiskit.circuit import ParameterVector, QuantumCircuit
from qiskit.primitives import StatevectorEstimator, StatevectorSampler
from qiskit.quantum_info import SparsePauliOp
from scipy.optimize import minimize
Sekarang kita mendefinisikan operator yang kita minati dan melihatnya dalam bentuk matriks.
op = SparsePauliOp("Z")
op.to_matrix()
array([[ 1.+0.j, 0.+0.j],
[ 0.+0.j, -1.+0.j]])
Cukup mudah untuk mendapatkan nilai eigen secara klasik, sehingga kita bisa memeriksa hasil kita. Ini mungkin menjadi sulit saat kita menskalakan ke skala utilitas. Di sini kita menggunakan numpy.
# compute eigenvalues with numpy
result = np.linalg.eigh(op.to_matrix())
print("Eigenvalues:", result.eigenvalues)
Eigenvalues: [-1. 1.]
Untuk mendapatkan nilai eigen menggunakan algoritma kuantum variatif, kita membangun Circuit dengan Gate yang mengambil parameter variatif:
# define a variational form
param = ParameterVector("a", 3)
qc = QuantumCircuit(1, 1)
qc.u(param[0], param[1], param[2], 0)
qc_estimator = qc.copy()
qc.measure(0, 0)
qc.draw("mpl")
Jika kita ingin memperkirakan nilai ekspektasi dari sebuah operator (seperti ), kita harus menggunakan Estimator. Jika kita ingin melihat keadaan sistem, kita menggunakan Sampler.
sampler = StatevectorSampler()
estimator = StatevectorEstimator()
Kita bisa menghitung jumlah bitstring 0 dan 1 dengan nilai parameter acak [1, 2, 3] menggunakan Sampler.
# compute counts of bitstrings with random parameter values by Sampler
result = sampler.run([(qc, [1, 2, 3])]).result()
counts = result[0].data.c.get_counts()
counts
{'0': 783, '1': 241}
Kita tahu bahwa kita bisa menghitung nilai ekspektasi Z dengan dengan probabilitas .
# compute the expectation value of Z based on the counts
(counts.get("0", 0) - counts.get("1", 0)) / sum(counts.values())
0.529296875
Circuit ini berhasil, tetapi nilai parameter yang dipilih tidak sesuai dengan keadaan berenergi rendah (atau nilai eigen rendah). Nilai eigen yang diperoleh cukup jauh di atas minimum. Hasilnya serupa saat menggunakan estimator.
Perlu dicatat bahwa Estimator mengambil Circuit kuantum tanpa pengukuran.
result = estimator.run([(qc_estimator, op, [1, 2, 3])]).result()
result[0].data.evs
array(0.54030231)
Kita perlu mencari parameter dan menemukan yang menghasilkan nilai eigen terendah. Kita membuat fungsi untuk menerima nilai parameter dari bentuk variatif dan mengembalikan nilai ekspektasi .
# define a cost function to look for the minimum eigenvalue of Z
def cost(x):
result = sampler.run([(qc, x)]).result()
counts = result[0].data.c.get_counts()
expval = (counts.get("0", 0) - counts.get("1", 0)) / sum(counts.values())
# the following line shows the trajectory of the optimization
print(expval, counts)
return expval
Mari kita terapkan fungsi minimize dari SciPy untuk menemukan nilai eigen minimum dari Z.
# minimize the cost function with scipy's minimize
min_result = minimize(cost, [0, 0, 0], method="COBYLA", tol=1e-8)
min_result
1.0 {'0': 1024}
0.494140625 {'0': 765, '1': 259}
0.466796875 {'0': 751, '1': 273}
0.564453125 {'0': 801, '1': 223}
-0.4296875 {'1': 732, '0': 292}
-0.984375 {'1': 1016, '0': 8}
-0.8984375 {'1': 972, '0': 52}
-0.990234375 {'1': 1019, '0': 5}
-0.892578125 {'1': 969, '0': 55}
-0.986328125 {'1': 1017, '0': 7}
-0.861328125 {'1': 953, '0': 71}
-1.0 {'1': 1024}
-0.982421875 {'1': 1015, '0': 9}
-0.99609375 {'1': 1022, '0': 2}
-0.986328125 {'1': 1017, '0': 7}
-1.0 {'1': 1024}
-0.990234375 {'1': 1019, '0': 5}
-0.998046875 {'1': 1023, '0': 1}
-0.99609375 {'1': 1022, '0': 2}
-1.0 {'1': 1024}
-1.0 {'1': 1024}
-1.0 {'1': 1024}
-1.0 {'1': 1024}
-0.998046875 {'1': 1023, '0': 1}
-1.0 {'1': 1024}
-1.0 {'1': 1024}
-0.998046875 {'1': 1023, '0': 1}
-0.998046875 {'1': 1023, '0': 1}
-0.998046875 {'1': 1023, '0': 1}
-1.0 {'1': 1024}
-0.99609375 {'1': 1022, '0': 2}
-1.0 {'1': 1024}
-0.99609375 {'1': 1022, '0': 2}
-0.998046875 {'1': 1023, '0': 1}
-0.998046875 {'1': 1023, '0': 1}
-0.99609375 {'1': 1022, '0': 2}
-0.998046875 {'1': 1023, '0': 1}
-1.0 {'1': 1024}
-0.998046875 {'1': 1023, '0': 1}
-0.998046875 {'1': 1023, '0': 1}
-0.99609375 {'1': 1022, '0': 2}
-1.0 {'1': 1024}
-0.998046875 {'1': 1023, '0': 1}
-1.0 {'1': 1024}
-0.998046875 {'1': 1023, '0': 1}
-0.998046875 {'1': 1023, '0': 1}
-1.0 {'1': 1024}
-0.998046875 {'1': 1023, '0': 1}
-0.998046875 {'1': 1023, '0': 1}
-1.0 {'1': 1024}
-1.0 {'1': 1024}
-1.0 {'1': 1024}
-1.0 {'1': 1024}
-1.0 {'1': 1024}
-1.0 {'1': 1024}
-0.998046875 {'1': 1023, '0': 1}
-0.994140625 {'1': 1021, '0': 3}
-1.0 {'1': 1024}
-1.0 {'1': 1024}
-1.0 {'1': 1024}
-1.0 {'1': 1024}
-1.0 {'1': 1024}
-1.0 {'1': 1024}
message: Optimization terminated successfully.
success: True
status: 1
fun: -1.0
x: [ 3.182e+00 1.338e+00 1.664e-01]
nfev: 63
maxcv: 0.0
# check counts of bitstrings with the optimal parameters
result = sampler.run([(qc, min_result.x)]).result()
result[0].data.c.get_counts()
{'0': 1, '1': 1023}
2.1 Latihan
Hitung nilai eigen minimum dari dengan VQE.
z2 = SparsePauliOp("ZZ")
print(z2)
print(z2.to_matrix())
SparsePauliOp(['ZZ'],
coeffs=[1.+0.j])
[[ 1.+0.j 0.+0.j 0.+0.j 0.+0.j]
[ 0.+0.j -1.+0.j 0.+0.j 0.+0.j]
[ 0.+0.j 0.+0.j -1.+0.j 0.+0.j]
[ 0.+0.j 0.+0.j 0.+0.j 1.+0.j]]
# compute eigenvalues with numpy
# define a variational form
# qc = ...
# compute counts of bitstrings with a random parameter values by Sampler
# result = sampler.run(...)
# result
# compute the expectation value of ZZ based on the counts
# verify the expectation value of ZZ with Estimator
# define a cost function to look for the minimum eigenvalue of ZZ
# def cost(x):
# expval = ...
# return expval
# minimize the cost function with scipy's minimize
# min_result = minimize(cost, [...], method="COBYLA", tol=1e-8)
# min_result
# check counts of bitstrings with the optimal parameter values
# result = sampler.run(qc, min_result.x).result()
# result
Solusi latihan
Kita mendefinisikan operator yang kita minati dan melihatnya dalam bentuk matriks.
z2 = SparsePauliOp("ZZ")
print(z2)
print(z2.to_matrix())
SparsePauliOp(['ZZ'],
coeffs=[1.+0.j])
[[ 1.+0.j 0.+0.j 0.+0.j 0.+0.j]
[ 0.+0.j -1.+0.j 0.+0.j 0.+0.j]
[ 0.+0.j 0.+0.j -1.+0.j 0.+0.j]
[ 0.+0.j 0.+0.j 0.+0.j 1.+0.j]]
Untuk mendapatkan nilai eigen menggunakan algoritma kuantum variatif, kita membangun Circuit dengan Gate yang mengambil parameter variatif:
# define a variational form
param = ParameterVector("a", 6)
qc = QuantumCircuit(2, 2)
qc.u(param[0], param[1], param[2], 0)
qc.u(param[3], param[4], param[5], 1)
qc_estimator = qc.copy()
qc.measure([0, 1], [0, 1])
qc.draw("mpl")
Jika kita ingin memperkirakan nilai ekspektasi dari sebuah operator (seperti ), kita akan menggunakan Estimator. Jika kita ingin melihat keadaan sistem, kita menggunakan Sampler.
sampler = StatevectorSampler()
estimator = StatevectorEstimator()
# compute counts of bitstrings with random parameter values by Sampler
result = sampler.run([(qc, [1, 2, 3, 4, 5, 6])]).result()
counts = result[0].data.c.get_counts()
counts
{'10': 661, '11': 203, '01': 47, '00': 113}
# compute the expectation value of ZZ based on the counts
(
counts.get("00", 0)
- counts.get("01", 0)
- counts.get("10", 0)
+ counts.get("11", 0)
) / sum(counts.values())
-0.3828125
Circuit ini berhasil, tetapi nilai parameter yang dipilih tidak sesuai dengan keadaan berenergi rendah (atau nilai eigen rendah). Nilai eigen yang diperoleh cukup jauh di atas minimum. Hasilnya serupa saat menggunakan estimator.
# verify the expectation value of ZZ with Estimator
result = estimator.run([(qc_estimator, z2, [1, 2, 3, 4, 5, 6])]).result()
result[0].data.evs
array(-0.35316516)
Kita perlu mencari parameter dan menemukan yang menghasilkan nilai eigen terendah.
# define a cost function to look for the minimum eigenvalue of ZZ
def cost(x):
result = sampler.run([(qc, x)]).result()
counts = result[0].data.c.get_counts()
expval = (
counts.get("00", 0)
- counts.get("01", 0)
- counts.get("10", 0)
+ counts.get("11", 0)
) / sum(counts.values())
print(expval, counts)
return expval
# minimize the cost function with scipy's minimize
min_result = minimize(cost, [0, 0, 0, 0, 0, 0], method="COBYLA", tol=1e-8)
min_result
1.0 {'00': 1024}
0.578125 {'00': 808, '01': 216}
0.5234375 {'00': 780, '01': 244}
0.548828125 {'00': 793, '01': 231}
0.3515625 {'00': 637, '10': 164, '11': 55, '01': 168}
0.3359375 {'00': 638, '11': 46, '10': 174, '01': 166}
0.283203125 {'00': 602, '10': 181, '01': 186, '11': 55}
-0.087890625 {'01': 414, '00': 184, '10': 143, '11': 283}
0.236328125 {'10': 27, '11': 623, '01': 364, '00': 10}
-0.0625 {'11': 261, '01': 403, '00': 219, '10': 141}
0.248046875 {'01': 366, '11': 628, '00': 11, '10': 19}
-0.0625 {'10': 145, '11': 254, '01': 399, '00': 226}
0.228515625 {'01': 373, '11': 609, '00': 20, '10': 22}
0.0546875 {'11': 376, '10': 273, '01': 211, '00': 164}
-0.447265625 {'01': 731, '10': 10, '11': 267, '00': 16}
-0.71484375 {'01': 871, '11': 99, '00': 47, '10': 7}
-0.46484375 {'01': 741, '00': 253, '10': 9, '11': 21}
-0.87890625 {'01': 962, '00': 39, '11': 23}
-0.640625 {'00': 176, '01': 837, '11': 8, '10': 3}
-0.88671875 {'01': 966, '00': 41, '11': 17}
-0.994140625 {'01': 1021, '11': 3}
-0.91796875 {'01': 982, '11': 35, '00': 7}
-0.994140625 {'01': 1021, '11': 2, '00': 1}
-0.939453125 {'01': 993, '00': 31}
-0.990234375 {'01': 1019, '11': 5}
-0.90234375 {'01': 974, '00': 21, '11': 29}
-0.98046875 {'01': 1014, '11': 10}
-0.994140625 {'01': 1021, '00': 3}
-0.990234375 {'01': 1019, '11': 4, '00': 1}
-0.98828125 {'01': 1018, '11': 6}
-0.990234375 {'01': 1019, '11': 4, '00': 1}
-0.994140625 {'01': 1021, '11': 2, '00': 1}
-0.99609375 {'01': 1022, '11': 2}
-0.998046875 {'01': 1023, '00': 1}
-0.99609375 {'01': 1022, '00': 2}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-0.998046875 {'01': 1023, '11': 1}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-0.998046875 {'01': 1023, '00': 1}
-0.998046875 {'01': 1023, '11': 1}
-0.998046875 {'01': 1023, '00': 1}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-0.998046875 {'01': 1023, '11': 1}
-0.998046875 {'01': 1023, '11': 1}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-0.998046875 {'01': 1023, '11': 1}
-0.998046875 {'01': 1023, '11': 1}
-0.998046875 {'01': 1023, '00': 1}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-0.998046875 {'01': 1023, '00': 1}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-0.998046875 {'01': 1023, '11': 1}
-0.998046875 {'01': 1023, '11': 1}
-1.0 {'01': 1024}
-0.998046875 {'01': 1023, '11': 1}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-0.998046875 {'01': 1023, '11': 1}
-0.998046875 {'01': 1023, '11': 1}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-0.998046875 {'01': 1023, '11': 1}
-0.998046875 {'01': 1023, '11': 1}
-0.998046875 {'01': 1023, '00': 1}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-0.998046875 {'01': 1023, '11': 1}
-1.0 {'01': 1024}
-0.99609375 {'01': 1022, '00': 1, '11': 1}
-0.998046875 {'01': 1023, '11': 1}
-0.998046875 {'01': 1023, '00': 1}
-0.998046875 {'01': 1023, '11': 1}
-1.0 {'01': 1024}
-0.99609375 {'01': 1022, '11': 1, '00': 1}
-1.0 {'01': 1024}
-0.998046875 {'01': 1023, '00': 1}
-0.994140625 {'01': 1021, '00': 3}
-0.998046875 {'01': 1023, '00': 1}
-0.99609375 {'01': 1022, '11': 2}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-0.998046875 {'01': 1023, '11': 1}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-0.998046875 {'01': 1023, '11': 1}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-0.998046875 {'01': 1023, '11': 1}
-0.998046875 {'01': 1023, '11': 1}
-1.0 {'01': 1024}
-0.998046875 {'01': 1023, '00': 1}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-1.0 {'01': 1024}
-0.998046875 {'01': 1023, '11': 1}
-0.998046875 {'01': 1023, '11': 1}
-0.998046875 {'01': 1023, '11': 1}
-0.99609375 {'01': 1022, '11': 2}
-1.0 {'01': 1024}
-0.998046875 {'01': 1023, '11': 1}
message: Optimization terminated successfully.
success: True
status: 1
fun: -0.998046875
x: [ 3.167e+00 6.940e-01 1.033e+00 -2.894e-02 8.933e-01
1.885e+00]
nfev: 128
maxcv: 0.0
message: Optimization terminated successfully.
success: True
status: 1
fun: -0.99609375
x: [ 3.098e+00 -5.402e-01 1.091e+00 -1.004e-02 3.615e-01
6.913e-01]
nfev: 115
maxcv: 0.0
Kita mendapatkan nilai eigen yang sangat dekat dengan minimum yang diberikan numpy kepada kita.
# check counts of bitstrings with the optimal parameters
result = sampler.run([(qc, min_result.x)]).result()
result[0].data.c.get_counts()
{'01': 1024}
3. Quantum Optimization dengan Qiskit patterns
Dalam bagian ini kita akan belajar tentang Qiskit patterns dan quantum approximate optimization. Qiskit pattern adalah serangkaian langkah yang intuitif dan berulang untuk mengimplementasikan alur kerja komputasi kuantum:
Kita akan menerapkan patterns tersebut dalam konteks optimisasi kombinatorial dan menunjukkan cara menyelesaikan masalah Max-Cut menggunakan Quantum Approximate Optimization Algorithm (QAOA), sebuah metode iteratif hibrida (kuantum-klasik).
Perlu dicatat bahwa bagian QAOA ini didasarkan pada "Part 1: Small-scale QAOA" dari tutorial Quantum approximate optimization algorithm. Lihat tutorial tersebut untuk belajar cara mengembangkannya ke skala yang lebih besar.
3.1 Qiskit pattern untuk optimisasi (skala kecil)
Bagian ini akan menggunakan masalah Max-Cut skala kecil untuk mengilustrasikan langkah-langkah yang diperlukan untuk menyelesaikan masalah optimisasi menggunakan komputer kuantum.
Masalah Max-Cut adalah masalah optimisasi yang sulit diselesaikan (lebih tepatnya, ini adalah masalah NP-hard) dengan berbagai aplikasi dalam clustering, ilmu jaringan, dan fisika statistik. Tutorial ini mempertimbangkan sebuah graf berisi node yang terhubung oleh edge, dan bertujuan untuk membagi node-node tersebut menjadi dua himpunan dengan "memotong" edge, sehingga jumlah edge yang dipotong dimaksimalkan.
Untuk memberi konteks sebelum memetakan masalah ini ke algoritma kuantum, kamu bisa lebih memahami bagaimana masalah Max-Cut menjadi masalah optimisasi kombinatorial klasik dengan terlebih dahulu mempertimbangkan minimisasi fungsi
di mana input adalah vektor yang komponennya berkorespondensi dengan setiap node dari graf. Kemudian, batasi setiap komponen tersebut agar bernilai atau (yang merepresentasikan apakah node tersebut masuk dalam potongan atau tidak). Contoh skala kecil ini menggunakan graf dengan node.
Kamu bisa membuat fungsi dari sepasang node yang menunjukkan apakah edge yang bersesuaian ada dalam potongan. Misalnya, fungsi bernilai 1 hanya jika salah satu dari atau bernilai 1 (yang berarti edge tersebut ada dalam potongan) dan nol dalam kasus lain. Masalah memaksimalkan edge dalam potongan dapat diformulasikan sebagai
yang dapat ditulis ulang sebagai minimisasi dalam bentuk
Minimum dari dalam kasus ini adalah ketika jumlah edge yang dilintasi potongan maksimal. Seperti yang bisa kamu lihat, belum ada kaitannya dengan komputasi kuantum sama sekali. Kamu perlu memformulasikan ulang masalah ini menjadi sesuatu yang bisa dipahami oleh komputer kuantum. Inisialisasi masalah dengan membuat graf dengan node.
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import rustworkx as rx
from rustworkx.visualization import mpl_draw
n = 5
graph = rx.PyGraph()
graph.add_nodes_from(range(1, n + 1))
edge_list = [
(0, 1, 1.0),
(0, 2, 1.0),
(1, 2, 1.0),
(1, 3, 1.0),
(2, 4, 1.0),
(3, 4, 1.0),
]
graph.add_edges_from(edge_list)
pos = rx.spring_layout(graph, seed=2)
mpl_draw(graph, node_size=600, pos=pos, with_labels=True, labels=str)
3.2 Langkah 1. Petakan input klasik ke masalah kuantum
Langkah pertama dari pattern adalah memetakan masalah klasik (graf) ke dalam Circuit dan operator kuantum. Untuk melakukan ini, ada tiga langkah utama:
- Gunakan serangkaian reformulasi matematis untuk merepresentasikan masalah ini menggunakan notasi masalah Quadratic Unconstrained Binary Optimization (QUBO).
- Tulis ulang masalah optimisasi sebagai Hamiltonian yang keadaan dasarnya berkorespondensi dengan solusi yang meminimalkan fungsi biaya.
- Buat Circuit kuantum yang akan mempersiapkan keadaan dasar Hamiltonian ini melalui proses yang mirip dengan quantum annealing.
Catatan: Dalam metodologi QAOA, pada akhirnya kamu ingin memiliki operator (Hamiltonian) yang merepresentasikan fungsi biaya dari algoritma hibrida kita, serta sebuah Circuit berparameter (Ansatz) yang merepresentasikan keadaan kuantum dengan kandidat solusi masalah. Kamu bisa mengambil sampel dari keadaan kandidat ini dan kemudian mengevaluasinya menggunakan fungsi biaya.
Graf → masalah optimisasi
Langkah pertama dari pemetaan adalah perubahan notasi. Berikut ini mengekspresikan masalah dalam notasi QUBO:
di mana adalah matriks berukuran berisi bilangan real, berkorespondensi dengan jumlah node dalam graf, adalah vektor variabel biner yang diperkenalkan sebelumnya, dan menunjukkan transpose dari vektor .
Problem name: maxcut
Minimize
2*x_1*x_2 + 2*x_1*x_3 + 2*x_2*x_3 + 2*x_2*x_4 + 2*x_3*x_5 + 2*x_4*x_5 - 2*x_1
- 3*x_2 - 3*x_3 - 2*x_4 - 2*x_5
Subject to
No constraints
Binary variables (5)
x_1 x_2 x_3 x_4 x_5
Masalah optimisasi → Hamiltonian
Kamu kemudian bisa memformulasikan ulang masalah QUBO sebagai Hamiltonian (di sini, sebuah matriks yang merepresentasikan energi suatu sistem):
Langkah-langkah reformulasi dari masalah QAOA ke Hamiltonian
Untuk menunjukkan bagaimana masalah QAOA dapat ditulis ulang dengan cara ini, pertama-tama ganti variabel biner dengan sekumpulan variabel baru melalui
Di sini kamu bisa melihat bahwa jika bernilai , maka harus bernilai . Ketika disubstitusi dengan dalam masalah optimisasi (), formulasi yang ekuivalen dapat diperoleh.
Sekarang jika kita mendefinisikan , menghapus faktor awal, dan suku konstanta , kita tiba pada dua formulasi yang ekuivalen dari masalah optimisasi yang sama.