Mga quantum algorithm: Mga variational quantum algorithm
Takashi Imamichi (24 May 2024)
I-download ang pdf ng orihinal na lektura. Tandaan na ang ilang mga code snippet ay maaaring maging deprecated dahil static na mga larawan ang mga ito.
Ang tinatayang oras ng QPU para patakbuhin ang eksperimentong ito ay 9 minuto (nasubok sa isang Eagle processor).
(Maaaring hindi matatapos ang notebook na ito sa loob ng oras na pinahihintulutan ng Open Plan. Pakigamit nang maingat ang mga mapagkukunan ng quantum computing.)
1. Panimula
Ang tutorial na ito ay nagbibigay ng pangkalahatang-ideya ng isang hybrid quantum-classical na algorithm, na nakatuon lalo na sa variational quantum eigensolver (VQE) at sa quantum approximate optimization algorithm (QAOA). Ang pangunahing layunin ng mga algorithm na ito ay harapin ang mga optimization problem sa pamamagitan ng paggamit ng mga quantum circuit na may mga parameterized quantum gate.
Sa kabila ng mga pagsulong sa quantum computing, ang presensya ng ingay sa mga kasalukuyang quantum device ay nagpapahirap na makakuha ng makabuluhang mga resulta mula sa malalim na mga quantum circuit. Upang malampasan ang hamong ito, ang VQE at QAOA ay gumagamit ng hybrid quantum-classical na diskarte, na kinabibilangan ng paulit-ulit na pagpapatakbo ng medyo maiikling quantum circuit gamit ang quantum computation at pag-optimize ng mga parameter ng target na parameterized quantum circuit gamit ang classical computation.
Ang QAOA ay may potensyal na magbigay ng mga pinakamainam na solusyon sa mga target na problema sa antas ng utility, salamat sa paggamit ng iba't ibang teknik ng error mitigation at suppression. Ang VQE naman ay may maraming aplikasyon (tulad ng quantum chemistry) kung saan ito ay hindi gaanong scalable. Ngunit lumabas na ang ilang mga diskarte na nauugnay sa eigenvalue upang umakma at palakasin ang VQE, kabilang ang Krylov subspace diagonalization at sampling-based quantum diagonalization (SQD). Ang pag-unawa sa VQE ay isang mahalagang unang hakbang sa pag-unawa sa malawak na hanay ng mga classical-quantum hybrid algorithm na lumabas na.
Inilalarawan ng modyul na ito ang mga pundamental na konsepto at implementasyon ng VQE at QAOA. Ang mga karagdagang tutorial ay magsasaliksik ng mga advanced na paksa at teknik para sa pag-scale up ng mga algorithm na ito. Kailangan mo ang sumusunod na library sa iyong environment para patakbuhin ang notebook na ito. Kung hindi mo pa ito na-install, maaari mo itong i-install sa pamamagitan ng pag-uncomment at pagpapatakbo ng sumusunod na cell.
# 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. Pagkuha ng pinakamababang eigenvalue ng isang simpleng Hamiltonian
Magsisimula tayo sa pamamagitan ng pag-apply ng VQE sa isang napaka-simpleng kaso, para makita kung paano ito gumagana. Kukuha tayo ng pinakamababang eigenvalue ng Pauli matrix gamit ang VQE. Magsisimula tayo sa pag-import ng ilang pangkalahatang pakete.
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
Ngayon ay tinutukuyin natin ang operator na interesado tayo at tinitingnan ito sa matrix form.
op = SparsePauliOp("Z")
op.to_matrix()
array([[ 1.+0.j, 0.+0.j],
[ 0.+0.j, -1.+0.j]])
Madali itong makuha ang mga eigenvalue nang klasikal, kaya maaari nating suriin ang ating gawa. Maaaring mahirap ito habang nagsc-scale tayo patungo sa utility. Dito ginagamit natin ang numpy.
# compute eigenvalues with numpy
result = np.linalg.eigh(op.to_matrix())
print("Eigenvalues:", result.eigenvalues)
Eigenvalues: [-1. 1.]
Para makuha ang mga eigenvalue gamit ang isang variational quantum algorithm, nagtatayo tayo ng Circuit na may mga gate na tumatanggap ng mga variational parameter:
# 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")
Kung gusto nating tantiyahin ang expected value ng isang operator (tulad ng ), dapat gumamit tayo ng Estimator. Kung gusto nating tingnan ang mga estado ng sistema, gumagamit tayo ng Sampler.
sampler = StatevectorSampler()
estimator = StatevectorEstimator()
Maaari tayong makakuha ng mga bilang ng mga bitstring na 0 at 1 na may mga random na parameter value na [1, 2, 3] gamit ang 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}
Alam natin na maaari nating kalkulahin ang expected value ng Z sa pamamagitan ng na may mga probabilidad na .
# compute the expectation value of Z based on the counts
(counts.get("0", 0) - counts.get("1", 0)) / sum(counts.values())
0.529296875
Gumana ang Circuit na ito, ngunit ang mga piniling parameter value ay hindi naaayon sa isang estado na may napakababang enerhiya (o mababang eigenvalue). Ang nakuhang eigenvalue ay medyo mas mataas kaysa sa pinakamababa. Katulad ang resulta kapag ginagamit ang estimator.
Tandaan na ang Estimator ay tumatanggap ng mga quantum circuit na walang mga measurement.
result = estimator.run([(qc_estimator, op, [1, 2, 3])]).result()
result[0].data.evs
array(0.54030231)
Kakailanganin nating maghanap sa mga parameter at hanapin ang mga nagbibigay ng pinakamababang eigenvalue. Gumagawa tayo ng function upang makatanggap ng mga parameter value ng variational form at ibalik ang expected value na .
# 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
Gamitin natin ang minimize function ng SciPy para hanapin ang pinakamababang eigenvalue ng 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 Ehersisyo
Kalkulahin ang pinakamababang eigenvalue ng gamit ang 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
Mga solusyon sa ehersisyo
Tinutukuyin natin ang operator na interesado tayo at tinitingnan ito sa matrix form.
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]]
Para makuha ang mga eigenvalue gamit ang isang variational quantum algorithm, nagtatayo tayo ng Circuit na may mga gate na tumatanggap ng mga variational parameter:
# 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")
Kung gusto nating tantiyahin ang expected value ng isang operator (tulad ng ), gagamit tayo ng Estimator. Kung gusto nating tingnan ang mga estado ng sistema, gumagamit tayo ng 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
Gumana ang Circuit na ito, ngunit ang mga piniling parameter value ay hindi naaayon sa isang estado na may napakababang enerhiya (o mababang eigenvalue). Ang nakuhang eigenvalue ay medyo mas mataas kaysa sa pinakamababa. Katulad ang resulta kapag ginagamit ang 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)
Kakailanganin nating maghanap sa mga parameter at hanapin ang mga nagbibigay ng pinakamababang eigenvalue.
# 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
Nakakuha tayo ng eigenvalue na napakalapit sa pinakamababa na ibinigay sa atin ng numpy.
# 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 gamit ang Qiskit Patterns
Sa how-to na ito, matututunan natin ang tungkol sa Qiskit patterns at quantum approximate optimization. Ang Qiskit pattern ay isang intuitive at paulit-ulit na hanay ng mga hakbang para sa pagpapatupad ng quantum computing workflow:
Ilalapat natin ang mga pattern sa konteksto ng combinatorial optimization at ipapakita kung paano solusyunan ang problemang Max-Cut gamit ang Quantum Approximate Optimization Algorithm (QAOA), isang hybrid (quantum-classical) na iterative na pamamaraan.
Tandaan na ang bahaging QAOA na ito ay batay sa "Part 1: Small-scale QAOA" ng tutorial na Quantum approximate optimization algorithm. Tingnan ang tutorial para matutunan kung paano ito palawakin.
3.1 (Small-scale) Qiskit Pattern para sa Optimization
Gagamitin ng bahaging ito ang isang maliit na Max-Cut na problema para ilarawan ang mga hakbang na kailangan para malutas ang isang optimization problem gamit ang quantum computer.
Ang Max-Cut na problema ay isang optimization problem na mahirap solusyunan (mas tiyak, isa itong NP-hard na problema) na may iba't ibang aplikasyon sa clustering, network science, at statistical physics. Isinasaalang-alang ng tutorial na ito ang isang graph ng mga node na konektado ng mga edge at layunin nitong hatiin ang mga node sa dalawang grupo sa pamamagitan ng "pagputol" ng mga edge, upang mapakinabangan ang bilang ng mga edge na naaputol.
Para magbigay ng konteksto bago i-map ang problemang ito sa isang quantum algorithm, mas mauunawaan mo kung paano nagiging classical combinatorial optimization problem ang Max-Cut sa pamamagitan ng pagsasaalang-alang muna ng minimization ng isang function na
kung saan ang input na ay isang vector na ang mga bahagi ay naaayon sa bawat node ng isang graph. Pagkatapos, pigilan ang bawat bahagi na maging alinman sa o (na kumakatawan sa pagiging kasama o hindi kasama sa cut). Ang maliit na halimbawang ito ay gumagamit ng graph na may na node.
Maaari kang sumulat ng function para sa isang pares ng mga node na na nagpapahiwatig kung ang kaukulang edge na ay nasa cut. Halimbawa, ang function na ay 1 lamang kung isa sa o ay 1 (na nangangahulugang ang edge ay nasa cut) at zero kung hindi. Ang problema ng pagpapakinabang ng mga edge sa cut ay maaaring buuin bilang
na maaaring isulat muli bilang isang minimization na may anyo
Ang minimum ng sa kasong ito ay kapag ang bilang ng mga edge na tinatagos ng cut ay pinakamataas. Tulad ng nakikita mo, wala pang kaugnayan sa quantum computing. Kailangan mong baguhin ang formulasyon ng problemang ito sa isang bagay na mauunawaan ng quantum computer. Simulan ang iyong problema sa pamamagitan ng paglikha ng graph na may na 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 Hakbang 1. I-map ang mga Classical Input sa isang Quantum Problem
Ang unang hakbang ng pattern ay ang pag-map ng classical na problema (graph) sa mga quantum circuit at operator. Para magawa ito, may tatlong pangunahing hakbang na dapat sundin:
- Gumamit ng serye ng mga mathematical reformulation para katawanin ang problemang ito gamit ang notasyon ng Quadratic Unconstrained Binary Optimization (QUBO).
- Isulat muli ang optimization problem bilang isang Hamiltonian na ang ground state ay naaayon sa solusyon na nagpapababa ng cost function.
- Lumikha ng quantum circuit na maghahanda ng ground state ng Hamiltoniang ito sa pamamagitan ng isang prosesong katulad ng quantum annealing.
Tandaan: Sa metodolohiya ng QAOA, ang layunin mo sa huli ay magkaroon ng isang operator (Hamiltonian) na kumakatawan sa cost function ng ating hybrid algorithm, pati na rin ang isang parametrized circuit (Ansatz) na kumakatawan sa mga quantum state na may mga candidate na solusyon sa problema. Maaari kang mag-sample mula sa mga candidate na state na ito at pagkatapos ay suriin ang mga ito gamit ang cost function.