Przejdź do głównej treści
Ten projekt jest w wersji beta. Znalazłeś błąd? Otwórz zgłoszenie na GitHub. Masz pytanie lub pomysł? Zapytaj w Discussions — chętnie poznamy Twoją opinię!
Jak oceniasz jakość tłumaczenia tej strony?

Algorytm Simona

Algorytm Simona to kwantowy algorytm zapytań rozwiązujący problem znany jako problem Simona. Jest to problem z obietnicą o podobnym charakterze do problemów Deutscha-Jozsy i Bernsteina-Vaziranego, jednak różniący się szczegółami.

Algorytm Simona jest istotny, ponieważ zapewnia wykładniczą przewagę algorytmów kwantowych nad klasycznymi (w tym probabilistycznymi), a zastosowana w nim technika zainspirowała Petera Shora do odkrycia efektywnego algorytmu kwantowego dla rozkładu liczb na czynniki pierwsze.

Problem Simona​

Funkcja wejściowa dla problemu Simona ma postać

f:Σn→Σmf:\Sigma^n \rightarrow \Sigma^m

dla dodatnich liczb całkowitych nn i mm. Moglibyśmy dla prostoty ograniczyć się do przypadku m=nm = n, ale niewiele zyskujemy na tym założeniu — algorytm Simona i jego analiza są zasadniczo takie same w obu przypadkach.

Problem Simona

Wejście: funkcja f:Σn→Σmf:\Sigma^n \rightarrow \Sigma^m
Obietnica: istnieje ciąg s∈Σns\in\Sigma^n taki, że [f(x)=f(y)]⇔[(x=y)∨(x⊕s=y)][f(x) = f(y)] \Leftrightarrow [(x = y) \vee (x \oplus s = y)] dla wszystkich x,y∈Σnx,y\in\Sigma^n
Wyjście: ciąg ss

Za chwilę dokładniej przeanalizujemy obietnicę, żeby lepiej zrozumieć, co mówi — najpierw jednak zaznaczmy wyraźnie, że wymaga ona od ff bardzo szczególnej struktury, więc większość funkcji tej obietnicy nie spełni. Warto też przyznać, że ten problem nie ma na celu praktycznego zastosowania. Jest to raczej nieco sztuczny problem, skrojony na miarę tak, by był łatwy dla komputerów kwantowych i trudny dla klasycznych.

Istnieją dwa główne przypadki: pierwszy to taki, w którym ss jest ciągiem samych zer 0n0^n, a drugi — gdy ss nie jest ciągiem samych zer.

  • Przypadek 1: s=0n.s=0^n. Jeśli ss jest ciągiem samych zer, możemy uprościć warunek „wtedy i tylko wtedy" w obietnicy do postaci [f(x)=f(y)]⇔[x=y].[f(x) = f(y)] \Leftrightarrow [x = y]. Jest to równoważne temu, że ff jest funkcją różnowartościową.

  • Przypadek 2: s≠0n.s\neq 0^n. Jeśli ss nie jest ciągiem samych zer, to spełnienie obietnicy dla tego ciągu oznacza, że ff jest dwu-do-jednego (ang. two-to-one), tzn. dla każdego możliwego ciągu wyjściowego ff istnieją dokładnie dwa ciągi wejściowe, które powodują, że ff zwraca ten ciąg. Co więcej, te dwa ciągi wejściowe muszą mieć postać ww i w⊕sw \oplus s dla pewnego ciągu w.w.

Ważne jest, by zauważyć, że jeśli obietnica jest spełniona, to może istnieć tylko jeden ciąg s,s, który działa — zatem dla funkcji spełniających obietnicę zawsze istnieje dokładnie jedna poprawna odpowiedź.

Oto przykład funkcji postaci f:Σ3→Σ5f:\Sigma^3 \rightarrow \Sigma^5 spełniającej obietnicę dla ciągu s=011s = 011.

f(000)=10011f(001)=00101f(010)=00101f(011)=10011f(100)=11010f(101)=00001f(110)=00001f(111)=11010\begin{aligned} f(000) & = 10011 \\ f(001) & = 00101 \\ f(010) & = 00101 \\ f(011) & = 10011 \\ f(100) & = 11010 \\ f(101) & = 00001 \\ f(110) & = 00001 \\ f(111) & = 11010 \end{aligned}

Istnieje 88 różnych ciągów wejściowych i 44 różne ciągi wyjściowe, z których każdy pojawia się dwukrotnie — mamy więc funkcję dwu-do-jednego. Co więcej, dla dowolnych dwóch różnych ciągów wejściowych dających ten sam ciąg wyjściowy, bitowy XOR tych dwóch ciągów wejściowych jest równy 011011, co jest równoważne temu, że każdy z nich jest równy drugiemu po XOR-owaniu z ss.

Zauważmy, że jedyne, co ma znaczenie w przypadku faktycznych ciągów wyjściowych, to czy są one takie same, czy różne dla różnych wyborów ciągów wejściowych. Na przykład w powyższym przykładzie cztery ciągi (10011,(10011, 00101,00101, 0000100001 i 11010)11010) pojawiają się jako wyjścia f.f. Moglibyśmy zastąpić te cztery ciągi innymi, o ile byłyby wszystkie różne, a poprawne rozwiązanie s=011s = 011 nie uległoby zmianie.

Opis algorytmu​

Oto diagram obwodu kwantowego reprezentującego algorytm Simona.

Simon's algorithm

Dla jasności: na górze znajduje się nn qubitów, na które działają bramki Hadamarda, a na dole mm qubitów wchodzących bezpośrednio do bramki zapytania (query gate). Wygląda to bardzo podobnie do algorytmów omawianych już w tej lekcji, ale tym razem nie ma phase kickback; dolne mm qubitów wchodzi do bramki zapytania w stanie ∣0⟩\vert 0\rangle.

Rozwiązanie problemu Simona przy użyciu tego obwodu wymaga w praktyce kilku niezależnych jego uruchomień, a następnie etapu klasycznego przetwarzania końcowego, który zostanie opisany później, po przeanalizowaniu zachowania obwodu.

Analiza​

Analiza algorytmu Simona przebiega początkowo podobnie jak w przypadku algorytmu Deutscha-Jozsy. Po wykonaniu pierwszej warstwy bramek Hadamarda na górnych nn qubitach stan przyjmuje postać

12n∑x∈Σn∣0m⟩∣x⟩.\frac{1}{\sqrt{2^n}} \sum_{x\in\Sigma^n} \vert 0^m \rangle \vert x\rangle.

Po wykonaniu UfU_f wyjście funkcji ff jest XORowane na stan zerowy dolnych mm qubitów, więc stan staje się

12n∑x∈Σn∣f(x)⟩∣x⟩.\frac{1}{\sqrt{2^n}} \sum_{x\in\Sigma^n} \vert f(x) \rangle \vert x\rangle.

Po wykonaniu drugiej warstwy bramek Hadamarda, korzystając z tego samego wzoru na działanie warstwy bramek Hadamarda co poprzednio, otrzymujemy następujący stan.

12n∑x∈Σn∑y∈Σn(−1)x⋅y∣f(x)⟩∣y⟩\frac{1}{2^n} \sum_{x\in\Sigma^n} \sum_{y\in\Sigma^n} (-1)^{x\cdot y} \vert f(x) \rangle \vert y\rangle

W tym momencie analiza rozchodzi się z analizami poprzednich algorytmów z tej lekcji.

Interesuje nas prawdopodobieństwo, że pomiary dadzą każdy możliwy ciąg y∈Σny\in\Sigma^n. Korzystając z reguł analizowania pomiarów opisanych w lekcji Układy złożone kursu Podstawy informacji kwantowej, stwierdzamy, że prawdopodobieństwo p(y)p(y) uzyskania ciągu yy wynosi

p(y)=∥12n∑x∈Σn(−1)x⋅y∣f(x)⟩∥2.p(y) = \left\|\frac{1}{2^n} \sum_{x\in\Sigma^n} (-1)^{x\cdot y} \vert f(x) \rangle \right\|^2.

Aby lepiej zrozumieć te prawdopodobieństwa, potrzebujemy odrobiny dodatkowej notacji i terminologii. Po pierwsze, zbiór wartości (obraz) funkcji ff to zbiór zawierający wszystkie jej ciągi wyjściowe.

range⁡(f)={f(x):x∈Σn}\operatorname{range}(f) = \{ f(x) : x\in \Sigma^n \}

Po drugie, dla każdego ciągu z∈range⁡(f)z\in\operatorname{range}(f) możemy wyrazić zbiór wszystkich ciągów wejściowych, dla których funkcja przyjmuje wartość zz, jako f−1({z})f^{-1}(\{z\}).

f−1({z})={x∈Σn:f(x)=z}f^{-1}(\{z\}) = \{ x\in\Sigma^n : f(x) = z \}

Zbiór f−1({z})f^{-1}(\{z\}) jest nazywany przeciwobrazem zbioru {z}\{z\} względem ff (przy odwzorowaniu ff). Analogicznie możemy zdefiniować przeciwobraz względem ff dowolnego zbioru zamiast {z}\{z\} — jest to zbiór wszystkich elementów, które ff odwzorowuje na ten zbiór. (Tej notacji nie należy mylić z odwrotnością funkcji ff, która może nie istnieć. Fakt, że argument po lewej stronie to zbiór {z}\{z\}, a nie element zz, pozwala uniknąć tej pomyłki.)

Korzystając z tej notacji, możemy rozdzielić sumę w powyższym wyrażeniu na prawdopodobieństwa i uzyskać

p(y)=∥12n∑z∈range⁡(f)(∑x∈f−1({z})(−1)x⋅y)∣z⟩∥2.p(y) = \left\| \frac{1}{2^n} \sum_{z\in\operatorname{range}(f)} \Biggl(\sum_{x\in f^{-1}(\{z\})} (-1)^{x\cdot y}\Biggr) \vert z \rangle \right\|^2.

Każdy ciąg x∈Σnx\in\Sigma^n jest reprezentowany dokładnie raz przez obie sumy — zasadniczo umieszczamy te ciągi w oddzielnych „koszyczkach" zależnie od tego, który ciąg wyjściowy z=f(x)z = f(x) produkują po obliczeniu funkcji ff, a następnie sumujemy osobno po wszystkich koszyczkach.

Możemy teraz obliczyć kwadrat normy euklidesowej i otrzymać

p(y)=122n∑z∈range⁡(f)∣∑x∈f−1({z})(−1)x⋅y∣2.p(y) = \frac{1}{2^{2n}} \sum_{z\in\operatorname{range}(f)} \left\vert \sum_{x\in f^{-1}(\{z\})} (-1)^{x\cdot y} \right\vert^2.

Aby jeszcze bardziej uprościć te prawdopodobieństwa, przyjrzyjmy się wartości

∣∑x∈f−1({z})(−1)x⋅y∣2(1)\left\vert \sum_{x\in f^{-1}(\{z\})} (-1)^{x\cdot y} \right\vert^2 \tag{1}

dla dowolnie wybranego z∈range⁡(f)z\in\operatorname{range}(f).

Jeśli s=0ns = 0^n, to ff jest funkcją różnowartościową i dla każdego z∈range⁡(f)z\in\operatorname{range}(f) istnieje dokładnie jeden element x∈f−1({z})x\in f^{-1}(\{z\}). Wartość wyrażenia (1)(1) wynosi wtedy 11.

Jeśli natomiast s≠0n,s\neq 0^n, to w zbiorze f−1({z})f^{-1}(\{z\}) są dokładnie dwa ciągi. Dokładniej: jeśli wybierzemy w∈f−1({z})w\in f^{-1}(\{z\}) jako jeden z tych dwóch ciągów, to drugim ciągiem musi być w⊕sw \oplus s zgodnie z obietnicą problemu Simona. Korzystając z tej obserwacji, możemy uprościć (1)(1) w następujący sposób.

∣∑x∈f−1({z})(−1)x⋅y∣2=∣(−1)w⋅y+(−1)(w⊕s)⋅y∣2=∣(−1)w⋅y(1+(−1)s⋅y)∣2=∣1+(−1)y⋅s∣2={4y⋅s=00y⋅s=1\begin{aligned} \left\vert \sum_{x\in f^{-1}(\{z\})} (-1)^{x\cdot y} \right\vert^2 & = \Bigl\vert (-1)^{w\cdot y} + (-1)^{(w\oplus s)\cdot y} \Bigr\vert^2 \\ & = \Bigl\vert (-1)^{w\cdot y} \Bigl(1 + (-1)^{s\cdot y}\Bigr) \Bigr\vert^2 \\ & = \Bigl\vert 1 + (-1)^{y\cdot s} \Bigr\vert^2 \\ & = \begin{cases} 4 & y \cdot s = 0\\[1mm] 0 & y \cdot s = 1 \end{cases} \end{aligned}

Okazuje się zatem, że wartość (1)(1) jest niezależna od konkretnego wyboru z∈range⁡(f)z\in\operatorname{range}(f) w obu przypadkach.

Możemy teraz dokończyć analizę, rozpatrując osobno te same dwa przypadki co poprzednio.

  • Przypadek 1: s=0n.s = 0^n. W tym przypadku funkcja ff jest różnowartościowa, więc istnieje 2n2^n ciągów z∈range⁡(f)z\in\operatorname{range}(f) i otrzymujemy

    p(y)=122n⋅2n=12n.p(y) = \frac{1}{2^{2n}} \cdot 2^n = \frac{1}{2^n}.

    Innymi słowy, pomiary dają ciąg y∈Σny\in\Sigma^n wybrany jednostajnie losowo.

  • Przypadek 2: s≠0n.s \neq 0^n. W tym przypadku ff jest funkcją dwu-do-jednego, więc range⁡(f)\operatorname{range}(f) zawiera 2n−12^{n-1} elementów. Korzystając z powyższego wzoru, wnioskujemy, że prawdopodobieństwo zmierzenia każdego y∈Σny\in\Sigma^n wynosi

    p(y)=122n∑z∈range⁡(f)∣∑x∈f−1({z})(−1)x⋅y∣2={12n−1y⋅s=00y⋅s=1p(y) = \frac{1}{2^{2n}} \sum_{z\in\operatorname{range}(f)} \Biggl\vert \sum_{x\in f^{-1}(\{z\})} (-1)^{x\cdot y} \Biggr\vert^2 = \begin{cases} \frac{1}{2^{n-1}} & y \cdot s = 0\\[1mm] 0 & y \cdot s = 1 \end{cases}

    Innymi słowy, otrzymujemy ciąg wybrany jednostajnie losowo ze zbioru {y∈Σn:y⋅s=0}\{y\in\Sigma^n : y \cdot s = 0\}, który zawiera 2n−12^{n-1} ciągów. (Ponieważ s≠0ns\neq 0^n, dokładnie połowa ciągów binarnych długości nn ma binarny iloczyn skalarny 11 z ss, a pozostałe mają binarny iloczyn skalarny 00 z ss, co już zaobserwowaliśmy w analizie algorytmu Deutscha-Jozsy dla problemu Bernsteina-Vaziraniego.)

Klasyczne przetwarzanie końcowe​

Wiemy już, jakie są prawdopodobieństwa możliwych wyników pomiarów podczas uruchamiania układu kwantowego dla algorytmu Simona. Czy to wystarczy, aby wyznaczyć ss?

Odpowiedź brzmi: tak, pod warunkiem że jesteśmy gotowi kilkukrotnie powtórzyć proces i zaakceptować, że może on zakończyć się niepowodzeniem z pewnym prawdopodobieństwem, które możemy uczynić bardzo małym, uruchamiając obwód wystarczająco wiele razy. Podstawowy pomysł polega na tym, że każde wykonanie obwodu dostarcza nam statystycznych dowodów dotyczących ss, a na ich podstawie możemy znaleźć ss z bardzo dużym prawdopodobieństwem, jeśli uruchomimy obwód odpowiednio wiele razy.

Załóżmy, że uruchamiamy obwód niezależnie kk razy, gdzie k=n+10k = n + 10. Ta konkretna liczba iteracji nie ma nic szczególnego — możemy wybrać większe (lub mniejsze) kk w zależności od tego, jakie prawdopodobieństwo błędu jesteśmy w stanie zaakceptować, co zobaczymy dalej. Wybór k=n+10k = n + 10 zapewni nam ponad 99,999{,}9% szansę na odzyskanie ss.

Uruchamiając obwód kk razy, otrzymujemy ciągi y1,...,yk∈Σny^1,...,y^{k} \in \Sigma^n. Dla jasności: indeksy górne są tutaj częścią nazw tych ciągów, a nie wykładnikami ani indeksami bitów, więc mamy

y1=yn−11⋯y01y2=yn−12⋯y02    ⋮yk=yn−1k⋯y0k\begin{aligned} y^1 & = y^1_{n-1} \cdots y^1_{0}\\[1mm] y^2 & = y^2_{n-1} \cdots y^2_{0}\\[1mm] & \;\; \vdots\\[1mm] y^{k} & = y^{k}_{n-1} \cdots y^{k}_{0} \end{aligned}

Tworzymy teraz macierz MM o kk wierszach i nn kolumnach, przyjmując bity tych ciągów jako wartości binarne wpisów.

M=(yn−11⋯y01yn−12⋯y02⋮⋱⋮yn−1k⋯y0k)M = \begin{pmatrix} y^1_{n-1} & \cdots & y^1_{0}\\[1mm] y^2_{n-1} & \cdots & y^2_{0}\\[1mm] \vdots & \ddots & \vdots \\[1mm] y^{k}_{n-1} & \cdots & y^{k}_{0} \end{pmatrix}

W tym momencie nie znamy jeszcze ss — naszym celem jest właśnie znalezienie tego ciągu. Wyobraź sobie jednak na chwilę, że znamy ciąg ss i tworzymy wektor kolumnowy vv z bitów ciągu s=sn−1⋯s0s = s_{n-1} \cdots s_0 w następujący sposób.

v=(sn−1⋮s0)v = \begin{pmatrix} s_{n-1}\\ \vdots\\ s_0 \end{pmatrix}

Jeśli wykonamy mnożenie macierzy przez wektor MvM v modulo 22 — tzn. wykonamy mnożenie w zwykły sposób, a następnie weźmiemy reszty z dzielenia przez 22 dla każdego wpisu wyniku — otrzymamy wektor zerowy.

Mv=(y1⋅sy2⋅s⋮yk⋅s)=(00⋮0)M v = \begin{pmatrix} y^1 \cdot s\\ y^2 \cdot s\\ \vdots\\[1mm] y^{k} \cdot s \end{pmatrix} = \begin{pmatrix} 0\\ 0\\ \vdots\\[1mm] 0 \end{pmatrix}

Innymi słowy, potraktowany jako wektor kolumnowy vv w sposób opisany powyżej, ciąg ss zawsze będzie elementem jądra macierzy MM, pod warunkiem że wykonujemy arytmetykę modulo 22. Jest to prawdziwe zarówno w przypadku s=0ns = 0^n, jak i s≠0ns\neq 0^n. Mówiąc precyzyjniej, wektor zerowy zawsze należy do jądra MM, a w przypadku s≠0ns\neq 0^n dołącza do niego wektor, którego wpisy są bitami ss.

Pozostaje pytanie, czy w jądrze MM pojawią się jakieś inne wektory oprócz tych odpowiadających 0n0^n i ss. Odpowiedź jest taka, że staje się to coraz mniej prawdopodobne wraz ze wzrostem kk — a jeśli wybierzemy k=n+10k = n + 10, jądro macierzy MM nie będzie zawierać żadnych innych wektorów poza tymi odpowiadającymi 0n0^n i ss z prawdopodobieństwem większym niż 99,999{,}9%. Mówiąc ogólniej, jeśli zastąpimy k=n+10k = n + 10 przez k=n+rk = n + r dla dowolnie wybranej dodatniej liczby całkowitej rr, prawdopodobieństwo, że wektory odpowiadające 0n0^n i ss są jedynymi elementami jądra MM, wynosi co najmniej 1−2−r1 - 2^{-r}.

Używając algebry liniowej, można efektywnie obliczyć opis jądra macierzy MM modulo 22. Konkretnie, można to zrobić za pomocą eliminacji Gaussa, która działa tak samo, gdy arytmetyka jest wykonywana modulo 22, jak w przypadku liczb rzeczywistych lub zespolonych. Dopóki wektory odpowiadające 0n0^n i ss są jedynymi elementami jądra MM — co zachodzi z dużym prawdopodobieństwem — możemy na podstawie wyników tego obliczenia wyznaczyć ss.

Klasyczna trudność​

Ile zapytań potrzebuje klasyczny algorytm zapytań, aby rozwiązać problem Simona? Odpowiedź brzmi: generalnie bardzo dużo.

Istnieje kilka precyzyjnych sformułowań dotyczących klasycznej trudności tego problemu — oto jedno z nich. Jeśli mamy dowolny probabilistyczny algorytm zapytań, który wykonuje mniej niż 2n/2−1−12^{n/2 - 1} - 1 zapytań — czyli liczbę zapytań wykładniczą względem nn — to z prawdopodobieństwem co najmniej 1/21/2 algorytm ten nie rozwiąże problemu Simona.

Udowodnienie takich twierdzeń o niemożności bywa niekiedy bardzo trudne, ale to konkretne można wykazać stosunkowo prosto za pomocą elementarnej analizy probabilistycznej. Tutaj jednak tylko pokrótce zarysujemy podstawową intuicję stojącą za tym wynikiem.

Staramy się znaleźć ukryty ciąg ss, ale dopóki nie zapytamy wyroczni o dwa ciągi dające tę samą wartość funkcji, będziemy mieć bardzo ograniczone informacje na temat ss. Intuicyjnie mówiąc, dowiemy się jedynie, że ukryty ciąg ss nie jest XOR-em żadnej pary różnych ciągów, o które zapytaliśmy. A jeśli zapytamy o mniej niż 2n/2−1−12^{n/2 - 1} - 1 ciągów, nadal pozostanie wiele możliwych wartości ss, których nie wykluczyliśmy, bo nie ma wystarczająco wielu par ciągów, by to zrobić. To nie jest formalny dowód — to tylko podstawowy pomysł.

Podsumowując, algorytm Simona daje nam uderzającą przewagę algorytmów kwantowych nad klasycznymi w modelu zapytań. W szczególności algorytm Simona rozwiązuje problem Simona przy liczbie zapytań liniowej względem liczby bitów wejściowych nn naszej funkcji, podczas gdy dowolny algorytm klasyczny, nawet probabilistyczny, musi wykonać liczbę zapytań wykładniczą względem nn, aby rozwiązać problem Simona z rozsądnym prawdopodobieństwem sukcesu.