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.
ds.algorithms
proofs
Marin
źródło
źródło
Odpowiedzi:
Lokalne maksimum 2D
wejście: 2-wymiarowa tablica An×n A
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,j−1],A[i−1,j],A[i+1,j] A
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.A X X A (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 ′ .A∖X A X (i′,j′) A′
Lemat. Quadrant " zawiera lokalne maksimum A .A′ A
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′) A′ A′ (i′,j′) ⋄
Algorytm nazywa się rekurencyjnie na podgrupaA′,aby znaleźć lokalne maksimum(i,j), a następnie zwraca tę komórkę.n2×n2 A′ (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×n T(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?
źródło