Deutsch-Jozsův algoritmus
Deutschův algoritmus překonává všechny klasické algoritmy pro problém dotazování, ale tato výhoda je poměrně skromná: jeden dotaz oproti dvěma. Deutsch-Jozsův algoritmus tuto výhodu rozšiřuje — a ve skutečnosti ho lze použít k řešení několika různých problémů dotazování.
Zde je popis Deutsch-Jozsova algoritmu pomocí kvantového Circuit. Další krok klasického post-processingu, který není na obrázku znázorněn, může být také potřeba v závislosti na konkrétním řešeném problému.
Samozřejmě jsme zatím neprobrali, jaké problémy tento algoritmus řeší; to je obsahem následujících dvou sekcí.
Deutsch-Jozsův problém
Začneme problémem dotazování, pro který byl Deutsch-Jozsův algoritmus původně navržen, a který je známý jako Deutsch-Jozsův problém.
Vstupní funkce tohoto problému má tvar pro libovolné kladné celé číslo Podobně jako u Deutschova problému je úkolem vypsat , pokud je konstantní, a , pokud je vyvážená, což opět znamená, že počet vstupních řetězců, pro které funkce nabývá hodnoty , je roven počtu vstupních řetězců, pro které funkce nabývá hodnoty .
Všimni si, že pokud je větší než existují funkce tvaru , které nejsou ani konstantní, ani vyvážené. Například funkce definovaná jako
nespadá do žádné z těchto dvou kategorií. U Deutsch-Jozsova problému se o takové funkce jednoduše nestaráme — považují se za vstupy typu „nezáleží na nich". To znamená, že u tohoto problému máme příslib, že je buď konstantní, nebo vyvážená.
Deutsch-Jozsův algoritmus se svým jediným dotazem řeší tento problém následovně: pokud jsou všechny výsledky měření rovny pak je funkce konstantní; a jinak, pokud je alespoň jeden z výsledků měření roven pak je funkce vyvážená. Jinak řečeno, za Circuit popsaným výše následuje krok klasického post-processingu, ve kterém se z výsledků měření vypočítá operace OR a vytvoří se výstup.
Analýza algoritmu
Pro analýzu výkonu Deutsch-Jozsova algoritmu pro Deutsch-Jozsův problém je užitečné začít úvahou o působení jedné vrstvy Hadamardových Gate. Hadamardovu operaci lze vyjádřit jako matici obvyklým způsobem,
ale tuto operaci můžeme také vyjádřit pomocí jejího působení na stavy standardní báze:
Tyto dvě rovnice lze spojit do jednoho vzorce,
který platí pro obě volby
Nyní předpokládejme, že místo jednoho Qubit máme Qubitů a na každém se provede Hadamardova operace. Kombinovaná operace na Qubitech je popsána tenzorovým součinem (-krát), který pro stručnost a přehlednost zapisujeme jako . Pomocí výše uvedeného vzorce, po rozepsání a následném zjednodušení, můžeme vyjádřit působení této kombinované operace na stavy standardní báze Qubitů takto:
Mimochodem, binární řetězce délky zde zapisujeme jako a podle konvence indexování v Qiskitu.
Tento vzorec nám poskytuje užitečný nástroj pro analýzu výše uvedeného kvantového Circuit. Po provedení první vrstvy Hadamardových Gate je stav Qubitů (včetně nejlevějšího/spodního Qubit, který je ošetřen odděleně od ostatních)
Když se provede operace , tento stav se transformuje na
prostřednictvím p řesně stejného jevu fázového zpětného rázu, který jsme viděli v analýze Deutschova algoritmu.
Poté se provede druhá vrstva Hadamardových Gate, která (podle výše uvedeného vzorce) transformuje tento stav na
Tento výraz vypadá poněkud komplikovaně a bez dalších znalostí o funkci nelze o pravděpodobnostech získání různých výsledků měření příliš mnoho usoudit.
Naštěstí vše, co potřebujeme znát, je pravděpodobnost, že každý z výsledků měření bude — protože to je pravděpodobnost, že algoritmus určí, že je konstantní. Tato pravděpodobnost má jednoduchý vzorec.
Podrobněji, pokud je konstantní, pak buď pro každý řetězec v tom případě je hodnota součtu nebo pro každý řetězec v tom případě je hodnota součtu Vydělením a umocněním absolutní hodnoty na druhou získáme
Pokud je naopak vyvážená, pak nabývá hodnoty na polovině řetězců a hodnoty na druhé polovině, takže se členy a v součtu vzájemně vyruší a zbude nám hodnota
Docházíme k závěru, že algoritmus funguje správně za předpokladu, že je splněn příslib.
Obtížnost pro klasické algoritmy
Deutsch-Jozsův algoritmus funguje pokaždé, vždy dává správnou odpověď, když je příslib splněn, a vyžaduje jediný dotaz. Jak je to ve srovnání s klasickými dotazovacími algoritmy pro Deutsch-Jozsův problém?
Za prvé, jakýkoli deterministický klasický algoritmus, který správně řeší Deutsch-Jozsův problém, musí provést exponenciálně mnoho dotazů: v nejhorším případě je potřeba dotazů. Důvod je ten, že pokud deterministický algoritmus dotazuje na nebo méně různých řetězcích a pokaždé získá stejnou hodnotu funkce, pak jsou stále možné obě odpovědi. Funkce může být konstantní, nebo může být vyvážená, ale smůlou se stalo, že dotazy všechny vrátily stejnou hodnotu funkce.
Druhá možnost se může zdát nepravděpodobná — ale u deterministických algoritmů neexistuje žádná náhodnost ani nejistota, takže systematicky selžou na určitých funkcích. Máme tedy v tomto ohledu významnou výhodu kvantových algoritmů oproti klasickým.
Je tu však háček, a to ten, že pravděpodobnostní klasické algoritmy dokáží vyřešit Deutsch-Jozsův problém s velmi vysokou pravděpodobností pomocí pouhých několika dotazů. Konkrétně, pokud jednoduše náhodně zvolíme několik různých řetězců délky a dotážeme se na tyto řetězce, je nepravděpodobné, že pro všechny získáme stejnou hodnotu funkce, když je vyvážená.
Přesněji řečeno, pokud zvolíme vstupních řetězců rovnoměrně náhodně, vyhodnotíme a odpovíme , pokud jsou všechny hodnoty funkce stejné, a , pokud ne, pak budeme vždy správně, když je konstantní, a v případě, že je vyvážená, se zmýlíme s pravděpodobností pouhých Pokud vezmeme například tento algoritmus odpoví správně s pravděpodobností větší než %.
Z tohoto důvodu máme stále poměrně skromnou výhodu kvantových algoritmů oproti klasickým — ale přesto jde o kvantifikovatelnou výhodu představující zlepšení oproti Deutschovu algoritmu.
Deutsch-Jozsův algoritmus s Qiskit
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-aer
from qiskit import QuantumCircuit
from qiskit_aer import AerSimulator
import numpy as np
Pro implementaci Deutsch-Jozsova algoritmu v Qiskit začneme definováním funkce dj_query, která generuje kvantový Circuit implementující dotazovací Gate pro náhodně zvolenou funkci splňující příslib Deutsch-Jozsova problému.
S 50% pravděpodobností je funkce konstantní a s 50% pravděpodobností je funkce vyvážená.
Pro každou z těchto dvou možností je funkce zvolena rovnoměrně z funkcí daného typu.
Argumentem je počet vstupních bitů funkce.
def dj_query(num_qubits):
# Create a circuit implementing for a query gate for a random function
# satisfying the promise for the Deutsch-Jozsa problem.
qc = QuantumCircuit(num_qubits + 1)
if np.random.randint(0, 2):
# Flip output qubit with 50% chance
qc.x(num_qubits)
if np.random.randint(0, 2):
# return constant circuit with 50% chance
return qc
# Choose half the possible input strings
on_states = np.random.choice(
range(2**num_qubits), # numbers to sample from
2**num_qubits // 2, # number of samples
replace=False, # makes sure states are only sampled once
)
def add_cx(qc, bit_string):
for qubit, bit in enumerate(reversed(bit_string)):
if bit == "1":
qc.x(qubit)
return qc
for state in on_states:
qc.barrier() # Barriers are added to help visualize how the functions are created.
qc = add_cx(qc, f"{state:0b}")
qc.mcx(list(range(num_qubits)), num_qubits)
qc = add_cx(qc, f"{state:0b}")
qc.barrier()
return qc
Implementaci dotazovací Gate jako kvantového Circuit si můžeme zobrazit pomocí metody draw, jak je obvyklé.
display(dj_query(3).draw(output="mpl"))
Dále definujeme funkci, která vytvoří Deutsch-Jozsův Circuit a jako argument přijímá implementaci dotazovací Gate jako kvantový Circuit.
def compile_circuit(function: QuantumCircuit):
# Compiles a circuit for use in the Deutsch-Jozsa algorithm.
n = function.num_qubits - 1
qc = QuantumCircuit(n + 1, n)
qc.x(n)
qc.h(range(n + 1))
qc.compose(function, inplace=True)
qc.h(range(n))
qc.measure(range(n), range(n))
return qc
Nakonec je definována funkce, která jednou spustí Deutsch-Jozsův Circuit.
def dj_algorithm(function: QuantumCircuit):
# Determine if a function is constant or balanced.
qc = compile_circuit(function)
result = AerSimulator().run(qc, shots=1, memory=True).result()
measurements = result.get_memory()
if "1" in measurements[0]:
return "balanced"
return "constant"
Naši implementaci si můžeme otestovat tak, že náhodně zvolíme funkci, zobrazíme kvantovou Circuit implementaci query Gate pro tuto funkci a poté na ni spustíme Deutsch-Jozsův algoritmus.
f = dj_query(3)
display(f.draw("mpl"))
display(dj_algorithm(f))

'balanced'
Bernstein-Vaziraniho problém
Dále si probereme problém známý jako Bernstein-Vaziraniho problém. Říká se mu také problém Fourierova vzorkování, i když existují obecnější formulace tohoto problému, které se také tak nazývají.
Nejprve si zaveďme notaci. Pro libovolné dva binární řetězce a délky definujeme
Tuto operaci budeme nazývat binární skalární součin. Alternativně ji lze definovat takto.
Všimni si, že jde o symetrickou operaci, což znamená, že výsledek se nezmění, pokud prohodíme a takže to můžeme kdykoli udělat, když se nám to hodí. Někdy je užitečné přemýšlet o binárním skalárním součinu jako o paritě bitů na pozicích, kde má řetězec hodnotu nebo ekvivalentně o paritě bitů na pozicích, kde má řetězec hodnotu
S touto notací nyní můžeme definovat Bernstein-Vaziraniho problém.
Pro tento problém vlastně nepotřebujeme nový kvantový algoritmus; řeší ho Deutsch-Jozsův algoritmus. Pro přehlednost budeme kvantový Circuit shora, který nezahrnuje klasický post-processing krok výpočtu OR, nazývat Deutsch-Jozsův Circuit.
Analýza algoritmu
Abychom analyzovali, jak Deutsch-Jozsův Circuit funguje pro funkci splňující příslib Bernstein-Vaziraniho problému, začneme krátkým pozorováním. Pomocí binárního skalárního součinu můžeme alternativně popsat působení Hadamardových Gate na standardní bázové stavy Qubitů takto.
Podobně jako při analýze Deutschova algoritmu je to proto, že hodnota pro libovolné celé číslo závisí pouze na tom, zda je sudé nebo liché.
Přejděme k Deutsch-Jozsovu Circuit. Po první vrstvě Hadamardových Gate je stav Qubitů
Poté se provede query Gate, která (prostřednictvím jevu fázového zpětného rázu) transformuje stav na
Pomocí našeho vzorce pro působení vrstvy Hadamardových Gate vidíme, že druhá vrstva Hadamardových Gate poté transformuje tento stav na
Nyní můžeme provést zjednodušení v exponentu uvnitř sumy. Máme příslib, že pro nějaký řetězec takže stav můžeme vyjádřit jako
Protože a jsou binární hodnoty, můžeme sčítání nahradit exkluzivním OR -- opět proto, že jediné, na čem u celého čísla v exponentu záleží, je to, zda je sudé nebo liché. S využitím symetrie binárního skalárního součinu získáme tento výraz pro stav:
(Závorky byly přidány pro přehlednost, i když nejsou nezbytně nutné, protože se konvenčně předpokládá, že binární skalární součin má vyšší prioritu než exkluzivní OR.) V tomto bodě využijeme následující vzorec.
Tento vzorec můžeme odvodit z podobného vzorce pro bity,
spolu s rozpisem binárního skalárního součinu a bitového exkluzivního OR:
To nám umožňuje vyjádřit stav Circuit těsně před měřením takto:
Posledním krokem je využití ještě dalšího vzorce, který platí pro každý binární řetězec
Zde používáme jednoduchou notaci pro řetězce, kterou v této lekci použijeme ještě několikrát: je samý-nulový řetězec délky
Jednoduchý způsob, jak zdůvodnit platnost tohoto vzorce, je zvážit oba případy zvlášť. Pokud pak pro každý řetězec takže hodnota každého členu sumy je a po sečtení a vydělení dostaneme Na druhou stranu, pokud je jakýkoli bit roven pak binární skalární součin je roven pro přesně polovinu možných voleb a pro druhou polovinu -- protože hodnota binárního skalárního součinu se překlopí (z na nebo z na ), pokud překlopíme jakýkoli bit na pozici, kde má hodnotu
Pokud nyní tento vzorec aplikujeme na zjednodušení stavu Circuit před měřením, získáme
díky tomu, že právě tehdy, když Měření tedy odhalí přesně řetězec který hledáme.
Klasická obtížnost
Zatímco Deutsch-Jozsův Circuit řeší Bernstein-Vaziraniho problém jedním dotazem, jakýkoli klasický dotazovací algoritmus musí k vyřešení tohoto problému provést alespoň dotazů.
To lze zdůvodnit takzvaným informačně-teoretickým argumentem, který je v tomto případě velmi jednoduchý. Každý klasický dotaz odhalí jeden bit informace o řešení a je třeba odhalit bitů informace -- takže je potřeba alespoň dotazů.
Ve skutečnosti je možné vyřešit Bernstein-Vaziraniho problém klasicky dotazováním funkce na každý z řetězců, které mají jedinou na každé možné pozici a na všech ostatních bitech, čímž se bity odhalují jeden po druhém. Výhoda kvantových algoritmů oproti klasickým je tedy pro tento problém dotaz versus dotazů.
Bernstein-Vazirani s Qiskit
Deutsch-Jozsův Circuit jsme již implementovali výše a zde ho využijeme k řešení Bernstein-Vaziraniho problému. Nejprve definujeme funkci, která implementuje query Gate pro Bernstein-Vaziraniho problém pro libovolný binární řetězec
def bv_query(s):
# Create a quantum circuit implementing a query gate for the
# Bernstein-Vazirani problem.
qc = QuantumCircuit(len(s) + 1)
for index, bit in enumerate(reversed(s)):
if bit == "1":
qc.cx(index, len(s))
return qc
display(bv_query("1011").draw(output="mpl"))
Nyní můžeme vytvořit funkci, která spustí Deutsch-Jozsův Circuit na funkci pomocí dříve definované funkce compile_circuit.
def bv_algorithm(function: QuantumCircuit):
qc = compile_circuit(function)
result = AerSimulator().run(qc, shots=1, memory=True).result()
return result.get_memory()[0]
display(bv_algorithm(bv_query("1011")))
'1011'
Poznámka k názvosloví
V kontextu Bernstein-Vaziraniho problému se Deutsch-Jozsův algoritmus běžně označuje jako "Bernstein-Vaziraniho algoritmus." To je mírně zavádějící, protože tento algoritmus je Deutsch-Jozsův algoritmus, jak Bernstein a Vazirani ve své práci jasně uvedli.
Co Bernstein a Vazirani udělali poté, co ukázali, že Deutsch-Jozsův algoritmus řeší Bernstein-Vaziraniho problém (jak je formulován výše), bylo definování mnohem složitějšího problému známého jako problém rekurzivního Fourierova vzorkování. Jde o vysoce umělý problém, kde řešení různých instancí problému efektivně odemykají nové úrovně problému uspořádané do stromové struktury. Bernstein-Vaziraniho problém je v podstatě jen základní případ tohoto složitějšího problému.
Problém rekurzivního Fourierova vzorkování byl prvním známým příkladem dotazovacího problému, kde kvantové algoritmy mají takzvanou super-polynomiální výhodu oproti pravděpodobnostním algoritmům, čímž překonávají výhodu kvantového nad klasickým přístupem, kterou nabízí Deutsch-Jozsův algoritmus. Intuitivně řečeno, rekurzivní verze problému zesiluje výhodu versus kvantových algoritmů na něco mnohem většího.
Nejnáročnějším aspektem matematické analýzy prokazující tuto výhodu je ukázat, že klasické dotazovací algoritmy nemohou problém vyřešit bez velkého počtu dotazů. To je dost typické; u mnoha problémů může být velmi obtížné vyloučit kreativní klasické přístupy, které je efektivně řeší.
Simonův problém a algoritmus pro něj popsan ý v další sekci však poskytují mnohem jednodušší příklad super-polynomiální (a ve skutečnosti exponenciální) výhody kvantových algoritmů oproti klasickým, a proto se problém rekurzivního Fourierova vzorkování diskutuje méně často. Přesto je to sám o sobě zajímavý výpočetní problém.