Przykłady algorytmów i dowodów, które wydają się poprawne, ale nie są

15

W moim wstępie do kursu programowania dowiadujemy się o metodzie inicjalizacji, konserwacji i terminacji, aby udowodnić, że algorytm działa zgodnie z oczekiwaniami. Musieliśmy jednak tylko udowodnić, że algorytm, o którym wiadomo, że jest poprawny, jest poprawny. Nigdy nie byliśmy proszeni o wykazanie, że algorytm jest nieprawidłowy.

Czy są jakieś klasyczne przykłady algorytmów, które wyglądają poprawnie, ale nie są? Szukam przypadków, w których podejście inicjalizacji-konserwacji-zakończenia wychwytuje coś, czego intuicja na pierwszy rzut oka nie ma.

Marin
źródło
5
Prawdopodobnie interesujące: cs.stackexchange.com/q/29475/755
DW
5
Głosowanie, ponieważ uważam, że jest to bardzo ważne pytanie pedagogiczne. Jest nieco poza zakresem cstheory, ale nie znam lepszej platformy do tego, i istnieje wiele instruktorów algorytmów w społeczności cstheory. Większość kursów projektowania algorytmów naraża studentów tylko na poprawianie istniejących algorytmów oraz na problemy, które można łatwo rozwiązać za pomocą znanych technik. To wzmacnia wrażenie, tak atrakcyjne dla studentów, że można bezpiecznie zaufać intuicyjnemu odczuciu, że pozornie prawdopodobny algorytm ma rację. Dobry kurs projektowania algorytmów powinien być odwrotny!
Neal Young
3
Chciałbym mieć taką kolekcję.
Chandra Chekuri

Odpowiedzi:

20

Lokalne maksimum 2D

wejście: 2-wymiarowa tablica An×nZA

wyjście: lokalne maksimum - para taka, że A [ i , j ] nie ma sąsiedniej komórki w tablicy, która zawiera ściśle większą wartość. (i,j)A[i,j]

(Sąsiednie komórki to te spośród które są obecne w tablicy.) Na przykład, jeśli A jestA[i,j+1],A[i,j1],A[i1,j],A[i+1,j]ZA

0134323125014013

następnie każda pogrubiona komórka jest lokalnym maksimum. Każda niepusta tablica ma co najmniej jedno maksimum lokalne.

Algorytm. Istnieje algorytm czasu : wystarczy sprawdzić każdą komórkę. Oto pomysł na szybszy, rekurencyjny algorytm.O(n2)

Biorąc pod uwagę , zdefiniuj krzyż X, aby składał się z komórek w środkowej kolumnie i komórek w środkowym rzędzie. Najpierw sprawdź każdą komórkę w X , aby zobaczyć, czy komórka jest lokalnym maksimum w A . Jeśli tak, zwróć taką komórkę. W przeciwnym razie niech ( i , j ) będzie komórką w X o maksymalnej wartości. Ponieważ ( i , j ) nie jest lokalnym maksimum, musi mieć sąsiednią komórkę ( i , j ) o większej wartości.AXXA(i,j)X(i,j)(i,j)

Partycja X (tablica minus komórki w X ) na cztery ćwiartki - górny lewy, prawy górny, dolny lewy i dolny prawy ćwiartki - w sposób naturalny. Sąsiednia komórka ( i , j ) o większej wartości musi znajdować się w jednej z tych ćwiartek. Nazwij ten kwadrant A . AXAX(i,j)A

Lemat. Quadrant " zawiera lokalne maksimum A .AA

Dowód. Rozważ rozpoczęcie od komórki . Jeśli nie jest to lokalne maksimum, przejdź do sąsiada o większej wartości. Można to powtarzać do momentu dotarcia do komórki, która jest lokalnym maksimum. Ta ostatnia komórka musi znajdować się w A , ponieważ A jest ze wszystkich stron ograniczona przez komórki, których wartości są mniejsze niż wartość komórki ( i , j ) . To dowodzi lematu. (i,j)AA(i,j)

Algorytm nazywa się rekurencyjnie na podgrupaA′,aby znaleźć lokalne maksimum(i,j), a następnie zwraca tę komórkę.n2×n2A(i,j)

Czas przebiegu dla macierzy n × n spełnia T ( n ) = T ( n / 2 ) + O ( n ) , więc T ( n ) = O ( n ) . T(n)n×nT(n)=T(n/2)+O(n)T(n)=O(n)

W ten sposób udowodniliśmy następujące twierdzenie:

Twierdzenie. Istnieje algorytm czasu do znajdowania maksimum lokalnego w tablicy n × n .O(n)n×n

A może my?

Neal Young
źródło
W pierwszym czytaniu jedynym błędem, jaki zauważyłem, było rozwiązanie problemu powtarzalności. Czy to jedyny błąd?
Radu GRIGore
1
Nawrót jest prawidłowy. Algorytm nie jest!
Neal Young
1
Ach, tak, popełniłem głupi błąd z nawrotem. Widzę problem: maksimum, które udowodniłeś, nie jest (koniecznie) tym, co znajdziesz. A to, co znajdziesz, ignoruje X.
Radu GRIGore
3
(2143300101230001023002222222333233300323000032300)
2
AA