Jedna równość za milion dolarów
Transkrypt
Jedna równość za milion dolarów
Bartłomiej Przybylski Jedna równość za milion dolarów Świat pełen problemów Wbrew temu, co można wywnioskować patrząc na dzisiejsze zastosowanie komputerów, nie zostały one pierwotnie stworzone do zapewniania rozrywek ich użytkownikom. Komputer (z ang. computer – maszyna licząca) powstał z myślą o wykonywaniu złożonych obliczeń związanych z poszukiwaniem rozwiązań pewnych ściśle zdefiniowanych problemów. Te problemy możemy sklasyfikować ze względu na rodzaj rozwiązania, którego oczekujemy. Wyobraźmy sobie, że musimy zmierzyć się z zadaniem rozkładu liczby k na czynniki pierwsze. Taki problem nazywamy problemem funkcyjnym – jego rozwiązaniem jest wartość lub zbiór/ciąg pewnych wartości. Jeśli liczba k jest mała, możemy dość szybko znaleźć rozwiązanie ręcznie. Dla kilkucyfrowej liczby, np. 4790077, musielibyśmy na to poświęcić już co najmniej kilka zimowych wieczorów. Mimo to, nawet przeciętny komputer potrzebuje nie więcej niż pięć tysięcznych sekundy, żeby stwierdzić, że 4790077 = 2089 · 2293. Z większymi liczbami radzi sobie już jednak gorzej. Problem rozkładu liczby na czynniki pierwsze jest jednym z najważniejszych problemów współczesnej informatyki teoretycznej. Na założeniu, że dla pewnych (bardzo dużych) liczb pierwszych p i q, obliczenie iloczynu k = pq zajmuje komputerowi moment, ale na rozłożenie liczby k na czynniki pierwsze potrzebuje on już kilku lat, opiera się wiele współczesnych algorytmów wykorzystywanych do szyfrowania danych (np. RSA). Czy jednak założenie to może być tak silne, że potrafimy bez mrugnięcia okiem oprzeć na nim tak istotne aspekty naszego życia jak zlecenia przelewów w banku internetowym czy choćby przesyłanie pocztą elektroniczną poufnych danych? I tak, i nie. Okazuje się, że mimo wielu starań nie udało się odnaleźć dotąd sposobu na szybkie rozłożenie dużej liczby na czynniki pierwsze, ale też nie pokazano, że (przy pewnym założeniu) nie da się tego zrobić. Są jednak pewne problemy, o których możemy śmiało powiedzieć, że małe są szanse na to, że da się je rozwiązać szybko. Dlaczego? O tym jest właśnie ten artykuł. Podstawową grupę problemów rozważanych w świecie informatyki stanowią problemy decyzyjne. Mają one postać pytania, na które odpowiedź brzmi tak lub nie. Gdybyśmy chcieli sformułować problem rozkładu liczby na czynniki pierwsze w postaci decyzyjnej, moglibyśmy zapytać: czy dana liczba k jest pierwsza (lub: czy dana liczba k jest złożona)? Problemy decyzyjne są łatwiejsze w rozważaniach, a jednak przydatne — jeśli uda się pokazać, że problem decyzyjny jest trudny, to związany z nim problem funkcyjny nie może być łatwiejszy (gdybyśmy umieli rozłożyć liczbę łatwo na czynniki pierwsze, to równie szybko dowiedzielibyśmy się, czy jest pierwsza, czy nie). Wśród innych problemów decyzyjnych moglibyśmy wymienić choćby następujące: — Czy w danym multizbiorze A liczb wymiernych istnieje podzbiór A0 taki, Artykuł powstał na zlecenie Poznańskiej Fundacji Matematycznej. 1 że suma elementów ze zbioru A0 jest równa sumie elementów ze zbioru A − A0 ? (problem podziału zbioru) — Czy w danym multizbiorze A liczb wymiernych istnieje podzbiór A0 taki, że suma jego elementów jest równa b? (problem sumy podzbioru) — Czy dane liczby naturalne n i m są względnie pierwsze? Zauważmy, że każdy z nich ma charakter ogólny. Problemy opisujemy bowiem pewnymi parametrami, które mogą przyjmować dowolne wartości. Jeśli je im przyporządkujemy (pytając np. czy konkretna liczba 4790077 jest pierwsza), to mówimy, że mamy do czynienia z pewną instancją tego problemu. Jak mierzymy algorytmy? W poprzednim paragrafie użyliśmy określeń szybko i wolno w kontekście tego, jak komputery radzą sobie z problemami. Ale co to znaczy, że komputer rozwiązuje problem szybko? Gdzie jest granica między szybko a wolno? Czy szybko na jednym komputerze oznacza też szybko na każdym innym? To ciekawe pytania, na które spróbujemy teraz odpowiedzieć. Komputer jest tylko maszyną — nie jest istotą inteligentną, choć rozwój sztucznej inteligencji mógłby napawać nas strachem. Nie należy jednak brać dosłownie wizji przedstawianych przez pisarzy fantastycznych. Ustalmy więc, że komputer jest maszyną wykonującą jedynie polecenia człowieka. Tę własność wykorzystujemy do rozwiązywania trapiących nas problemów, konstruując algorytmy. Algorytmy rozwiązujące problemy to procedury, które zastosowane do jego dowolnej instancji, wskażą jej rozwiązanie po wykonaniu skończonej liczby kroków. W naszym przypadku rozwiązanie to jest pozytywną lub negatywną odpowiedzią na postawione pytanie. Algorytmy są różne – rozwiązać dany problem można przecież na wiele sposobów, stosując wiele podejść i różnych metod. Każdy algorytm wymaga jednak wykonania pewnej liczby operacji, zanim się zakończy. W większości przypadków nie liczymy jednak absolutnie wszystkich operacji, a jedynie te, które częstością swojego występowania dominują nad innymi. Te operacje, które bierzemy pod uwagę, nazywamy operacjami elementarnymi. Mimo wszystko, ich liczba zależy jednak od instancji problemu — intuicja podpowiada nam, że odpowiedź na pytanie, czy 817504253 jest liczbą pierwszą wymaga więcej operacji niż odpowiedź na pytanie, czy taką liczbą jest 13. Jak zatem określić, jaka jest szybkość algorytmu, skoro dla każdej instancji wymaga on różnej liczby operacji? Rozważania dotyczące tych zagadnień rozpoczęły się na dobre w latach sześćdziesiątych dwudziestego wieku, kiedy zaczęto konstruować pierwsze, powolne komputery. Już (a może dopiero) wówczas zauważono, że względnie łatwo jest skonstruować algorytm, który rozwiązuje dany problem decyzyjny, ale wymyślenie takiego, który potrzebuje na to małej liczby operacji może być wyzwaniem. Teoria złożoności obliczeniowej, bo tak nazywa się dziedzina informatyki zajmująca się badaniem czasu działania algorytmów, do dziś dzień opiera się na próbach konstrukcji coraz to szybszych algorytmów. Jednym z najczęściej spotykanych podejść jest próba określenia górnej granicy liczby operacji, których algorytm potrzebuje do rozwiązania danej instancji problemu, przez rząd funkcji zależnej od długości zakodowanej instancji. Wow, brzmi skomplikowanie, dlatego spójrzmy na przykład: Artykuł powstał na zlecenie Poznańskiej Fundacji Matematycznej. 2 Przykład Niech dana będzie liczba k. Chcemy sprawdzić, czy jest ona liczbą pierwszą. W tym celu zastosujemy następujący, prymitywny algorytm: dla i ze zbioru {2, 3, ..., k-1} jeśli (k mod i) = 0 wtedy zwróć nie zwróć tak Powyższy algorytm wykona, dla dowolnej liczby k, co najwyżej k − 2 operacji dzielenia modulo. Operacje porównania możemy pominąć jako nieistotne. Nasz algorytm wykona zatem co najwyżej k − 2 operacji. Jeśli jednak weźmiemy pod uwagę, że instancja problemu jest opisana liczbą k zapisaną w systemie binarnym (a zwykle tak zakładamy), to długość tego opisu jest równa n = blog2 kc + 1, a zatem górną granicę liczby operacji niezbędnych do zakończenia działania algorytmu da się opisać funkcją f (n) = 2n − 2, choć nie zawsze ta granica musi być osiągana (Czytelnikowi pozostawiam wykazanie tego faktu). W praktyce nie interesuje nas jednak, czy liczbę operacji elementarnych zależnych od długości n opisu instancji problemu, da się ograniczyć od góry funkcją f (n) = 2n − 2, czy f (n) = 3 · 2n − 12. Najistotniejsze z punktu widzenia naszych rozważań jest to, jakiego rzędu jest ta funkcja. Jeśli istnieje taka funkcja t(n), że |f (n)| ¬ c · t(n) dla pewnej stałej c i wszystkich n większych od pewnej wartości n0 , to mówimy, że funkcja f (n) jest rzędu t(n) i zapisujemy to jako f (n) = O(t(n)) (czyt. f jest rzędu duże o od t(n)). W rzeczywistości obie wskazane funkcje: 2n − 2 oraz 3 · 2n − 12 są rzędu O(2n ). Nie jest zaskoczeniem, że staramy się znaleźć jak najlepsze ograniczenie danej funkcji f . Przecież każda funkcja, która jest O(2n ) jest też O(10n ), ale drugie ograniczenie nie jest dla niej zbyt dobre. Pewnym rozwiązaniem tego problemu jest stosowanie notacji Θ, ale dla naszych rozważań nie ma ona istotnych zastosowań. Warto jednak wiedzieć, że istnieje. Ćwiczenie Zanim przejdziemy dalej, sprawdź jak sobie radzisz z określaniem rzędu funkcji. W każdym podpunkcie zebrano dwie funkcje, które mają taki sam rząd (w sensie notacji O). Jaki on jest? Wskaż najlepszy. 1. f (n) = 14n3 − 12x2 + 7x − 3, g(n) = n3 + 1928x2 , 2. h(n) = 12n log n + 13n, i(n) = 148n log n + log n, 3. j(n) = 7 · 3n + 12 · 2n + n, k(n) = 3n+12 + 1. Pokaż, że każda funkcja rzędu O(n3 + 12n2 ) jest też rzędu O(n3 ). Jeśli liczba operacji wykonywanych przez algorytm da się ograniczyć z góry przez wielomian, to znaczy jest rzędu O(p(n)), gdzie p(n) jest pewnym wielomianem, np. n12 , n7 itp., to mówimy, że algorytm jest wielomianowy lub że algorytm działa w czasie wielomianowym. W innym przypadku mówimy, że algorytm jest wykładniczy. Ten podział jest bardzo istotny i powszechny — przyjmuje się, że algorytmy wielomianowe są szybkie, a te wykładnicze wolne. Dlaczego? Niech to zaprezentuje poniższa tabela. Załóżmy, że nasz procesor jest w stanie wykonać miliard operacji elementarnych w ciągu sekundy. W poniższej tabeli zaprezentowano zestawienie, które pokazuje, ile czasu wymagałaby realizacja algorytmów o pewnej określonej od góry liczbie operacji dla instancji wybranej długości: Artykuł powstał na zlecenie Poznańskiej Fundacji Matematycznej. 3 Tabela 1: Porównanie czasu działania algorytmów na procesorze wykonującym miliard operacji elementarnych w ciągu sekundy Długość wejścia (n) Czas wykonania danej liczby operacji n2 n3 n5 2n 10 100 1000 0,0000001s 0,00001s 0,001s 0,000001s 0,001s 1s 0,0001s 10s ok. 12 dni 0,000001024s ok. 4·1013 lat ok. 3·10299 lat Okazuje się więc, że algorytmy wielomianowe istotnie działają o wiele szybciej niż te wykładnicze. Wróćmy na chwilę do problemu weryfikacji pierwszości liczby. Dopiero w 2002 roku trzech hinduskich badaczy — Manindra Agrawal, Neeraj Kayal oraz Nitin Saxena — zaprezentowało algorytm wielomianowy, który to robi. Do tamtego momentu stosowano jedynie algorytmy wykładnicze. Źródło: http://xkcd.com. Jeśli chcesz się dowiedzieć więcej o problemie, którego dotyczy ten komiks, poszukaj informacji o problemie komiwojażera. Pytanie, które można zadać brzmi, czy każdy algorytm wielomianowy jest rzeczywiście wielomianowy zawsze? I na odwrót — czy nie jest tak, że na jednej maszynie algorytm będzie wykładniczy, a na drugiej wielomianowy (na przykład gdy zmodyfikujemy zbiór operacji elementarnych)? Okazuje się, że wielomianowość algorytmów zachowuje się przy ich przenoszeniu między maszynami, choć rząd funkcji może się zmienić. Jeśli jednak trzymamy się pewnych reguł gry, nasz algorytm wielomianowy nie stanie się nagle algorytmem wykładniczym. Jedna równość za milion dolarów Wcześniejsze wprowadzenie było nam niezbędne do tego, abyśmy mogli w końcu zacząć mówić o pieniądzach. I to nie byle jakich, bo o równym milionie dolarów. 24 maja 2000 roku Instytut Matematyczny Claya ogłosił listę siedmiu zagadnień matematycznych, za których rozwiązanie wyznaczono nagrody gotówkowe o wartości miliona dolarów. Zagadnienia te nazywamy milenijnymi, choć najnowsze z nich powstało w 1971 roku. To właśnie ono jest przedmiotem naszych rozważań, a przyjmuje postać pytania: czy P=NP ? Artykuł powstał na zlecenie Poznańskiej Fundacji Matematycznej. 4 Często jednak określa się go po prostu mianem problemu P = N P lub P vs. N P . Pytanie to samo w sobie nie jest łatwe, wymaga więc pewnych wyjaśnień. Problemy decyzyjne możemy podzielić ze względu na ich własności związane ze złożonością obliczeniową: — jeśli da się skonstruować algorytm wielomianowy, który rozwiązuje dany problem, to problem ten należy do zbioru (klasy) P problemów, — jeśli da się skonstruować algorytm, który w wielomianowej liczbie operacji potrafi potwierdzić, że na postawione pytanie odpowiedź brzmi tak, jeśli otrzyma dodatkowo rozwiązanie, dla którego tak właśnie jest (świadka), to problem taki należy do zbioru (klasy) N P . Przykład Rozważmy problem plecakowy. Mamy plecak o pojemności B i zbiór N przedmiotów X = {x1 , x2 , . . . , xN }, każdy z nich o określonej objętości (wj ) oraz wartości (cj ). Pytanie brzmi: czy istnieje taki podzbiór X 0 ⊆ X przedmiotów, że ich łączna objętość jest mniejsza niż B, a ich łączna wartość przekracza wskazaną wartość C? Inaczej możemy spytać, czy istnieje taki podzbiór X 0 ⊆ X, że X X0 cj > C oraz X wj < B. X0 Nie ulega wątpliwości, że jeśli wskażemy podzbiór X 0 , który spełnia wszystkie założenia, to będziemy w stanie to potwierdzić w wielomianowym czasie, dodając odpowiednie wartości i porównując sumy z wartościami granicznymi. Zatem problem plecakowy należy do klasy N P problemów decyzyjnych. Do dziś jednak nie wiadomo, czy należy do klasy P . Łatwo pokazać (no, może nie tak łatwo, ale jednak jest to możliwe), że każdy problem z klasy P należy też do klasy N P . To oznacza, że P ⊆ N P . Aby zdobyć milion dolarów, wystarczy pokazać, że jest lub nie jest odwrotnie, to znaczy, że N P ⊆ P lub nie. Istnieje pewien specjalny podzbiór problemów z klasy N P . Problemy te nazywamy N P -zupełnymi (określenie zupełny zostało zaczerpnięte z logiki) i mają one pewną bardzo ciekawą własność: jeśli uda się stworzyć wielomianowy algorytm rozwiązujący którykolwiek z problemów N P -zupełnych, to będzie oznaczać, że każdy problem z klasy N P da się rozwiązać w wielomianowym czasie i w konsekwencji, że P = N P . Na stronie internetowej http://www.win.tue.nl/~gwoegi/P-versus-NP. htm zebrane są artykuły naukowe, których autorzy utrzymywali, że udało im się rozwiązać problem P = N P . Wszystko wskazuje jednak na to, że żaden z dowodów nie był poprawny. Zaskakujące jest to, że liczba prac, które miałyby potwierdzać, że P = N P jest bardzo zbliżona do liczby tych, które miałyby pokazywać coś zupełnie odwrotnego. Wiele osób zaangażowanych w badania związane ze złożonością obliczeniową zakłada, że mimo wszystko P 6= N P i na tym założeniu opiera mniejszą lub większą część swoich wyników. Dopóki jednak nie dowiemy się, jak jest naprawdę, nie możemy być pewni niczego. Gdyby rzeczywistość była taka, że każdy problem z klasy N P da się rozwiązać w wielomianowym czasie, światowe bezpieczeństwo runęłoby bardzo szybko. Okazałoby się bowiem, Artykuł powstał na zlecenie Poznańskiej Fundacji Matematycznej. 5 Źródło: http://xkcd.com że większość szyfrowanych danych przesyłanych w internecie da się bardzo szybko odszyfrować nawet bez znajomości jakiegokolwiek klucza. I, co gorsza, oznaczałoby to, że bohater powyższego komiksu musiałby zmienić swoje hobby. Artykuł powstał na zlecenie Poznańskiej Fundacji Matematycznej. 6