2012-03-20 19 views
8

lokalne maksimum w 2D tablicy może być zdefiniowana jako wartość taka, że ​​wszystko to 4 sąsiedzi są mniejsze lub równe do niego, czyli do a[i][j] być lokalne maksimum,Znalezienie lokalne maksima w tablicy 2D

a[i+1][j] <= a[i][j] 
&& a[i-1][j] <= a[i][j] 
&& a[i][j+1] <= a[i][j] 
&& a[i+1][j-1] <= a[i][j] 

Zostałem poproszony o znalezienie wszystkich lokalnych maksimów w danej tablicy 2D.

Naiwnym sposobem wykonania tego byłoby przejrzenie wszystkich elementów i sprawdzenie, czy każdy element jest lokalnym maksimum. To byłby O (n^2). Uważam, że nie można zrobić nic lepszego, chociaż mój przyjaciel twierdzi, że powinien istnieć asymptotycznie lepszy algorytm. Jakieś wskazówki?

Miałem na myśli podział Divide i Conquer, ale uważam, że niemożliwe byłoby wykrycie wszystkich lokalnych maksimów bez przechodzenia przez wszystkie liczby, które musiałyby być O (n^2). Czy mam rację, czy też czegoś brakuje?

+1

Jeśli chcesz tylko jednej z lokalnych maksimów, można je znaleźć w mniej niż n^2 czasie. –

+0

@Habisoft dał najlepszą odpowiedź –

Odpowiedz

-1

Jestem prawie pewien, że nie da się tego rozwiązać w mniej niż porównań O (n^2). Załóżmy macierz 2d na planszy szachowej, w której wszystkie białe kwadraty mają 1, a czarne 0. Będziemy mieli rozwiązania O (n^2), a każde rozwiązanie wymaga co najmniej jednego porównania.

+0

Dziękuję, twój przykład naprawdę wszystko ładnie wyjaśnia :) – arya

+0

Jak wspomniano w mojej odpowiedzi, ponieważ tablica nie jest określona jako "kwadratowa", to tak naprawdę jest to tylko 'O (n)' gdzie 'n' to całkowita liczba elementów tak, że 'n = i * j'. To zrozumienie jest czymś, czego bym się spodziewał, gdybym był przesłuchującym. – Seph

+0

@arya Ta odpowiedź jest niepoprawna. rozważ odpowiedź, którą zapewniam. – kasavbere

0

Uważam, że na to pytanie można odpowiedzieć za pomocą tak zwanych argumentów przeciwników, co daje niższą granicę liczby porównań.

I według mnie masz rację ... wymagałoby to co najmniej dwóch porównań.

+0

Masz na myśli co najwyżej n^2. – kasavbere

+0

@ kasavbere- Miałem co najmniej na przykład n^2 .. mówimy tutaj o niższych granicach. – vidit

2

Jeśli twoja macierz nie jest kwadratowa, twoje rozwiązanie jest w rzeczywistości O(I * J), a nie O(n^2). Ściśle mówiąc masz tylko elementy N w twojej tablicy 2d, więc to rozwiązanie to O(N). Jedynym sposobem, jaki może to być O(n^2), jest sytuacja, gdy tablica jest kwadratowa, tak że I = J = N.

Ponieważ porównanie to jest <=, a nie <, musisz jeszcze sprawdzić następny element, a wszelkie skróty, które wypróbujesz, będą prawdopodobnie zależne od procesora.

Najgorszym przypadkiem jest, że cała tablica jest lokalne maksima, ponieważ cała tablica jest równa tej samej wartości.

Zatem należy odwiedzić każdy element raz, dzięki czemu O(N)

Aby poprawić wydajność osiągana w ten trzeba by użyć wskaźników do dostępu, którego tablicę, jak w większości języków 2d tablice wykonują znacznie gorzej niż 1d tablic .

+1

@down voter proszę skomentować .. – Seph

0

NIE musiał odwiedzić każdy element:

Wszystko co musisz zrobić, to wizualizować siatkę i widać, że to może być rozwiązane w znacznie mniej niż płaskiej n^2 (lub I * J) . Oto optymalizacje według poziomu:

1] dla macierzy I * J, potrzebujesz tylko wyszukiwania (I-2) * (J-2). Czemu? granice nie mogą być maxima powodu niezdefiniowanych elementów:

e.g. grid[0][J] or grid[I][0] could never be maxima. because of the -1 neighbor. 

więc na 10 przez 12 sieci, zamiast wizyty wszystkie 120 elementów, patrzymy na 80 elementów.

2] jeśli siatka [I] [J] jest maksimum, wówczas możemy pominąć wszystkie komórki sąsiadujące z [I] [J], gdy będziemy kontynuować wyszukiwanie. Spowoduje to dalszą redukcję liczby elementów do porównania.

Dlatego odpowiedź brzmi: nie, nie musisz odwiedzać każdego elementu.

+1

Podczas gdy twoje optymalizacje są poprawne, twój algorytm nadal będzie miał postać O (i * j). Po pierwsze, zmniejszenie liczby kontroli poprzez wyeliminowanie granicy jest skuteczne w przypadku stosunkowo małych sieci (33% za 10 x 12), ale niewiele w przypadku większych. Na siatce 100x120 przechodzisz z 12000 kwadratów do 11564, czyli <4%. Twoja druga optymalizacja nie robi nic w przypadku, gdy nie ma lokalnych maksimów. – dlev

+0

Zgadza się. Chodzi o to, że wniosek jest równie ważny, jak sam wniosek. Używanie fałszywych argumentów w celu wyciągnięcia prawidłowych wniosków nie powinno być wystarczająco dobre. – kasavbere

+0

Co jest nie tak z uzasadnieniem? ElKamino po prostu podsumowuje, na dobrym przykładzie, i pokazuje, jak to jest O (n^2). I tak, pokazujesz optymalizacje i myślę, że możemy stwierdzić, że wymagany optymalny i kompletny algorytm musi być Θ (n^2). – rafalio

12

Po prostu heads up, lokalne maksima lub minima siatki 2D mogą być obliczane w czasie O (nlgn) za pomocą strategii dziel i rządź. Jest to nieco lepszy czas związany niż algorytm brute force zawarty w klasie złożoności O (n^2). Ponadto można wprowadzić ulepszenia do algorytmu dziel i podbij, aby uzyskać algorytm O (n) do wyszukiwania ekstremów w sieci 2D.

Sprawdź te notatki na temat teorii za taki szczyt zbieranie algorytmów (jestem pewien ich są więcej materiałów tam):

http://courses.csail.mit.edu/6.006/spring11/lectures/lec02.pdf

+1

Twoje rozwiązanie nie znajduje wszystkich lokalnych maksimów, tylko lokalne maksima. Rozważmy macierz I * J zawierającą tylko wartość 5 w każdej komórce, musisz odwiedzić wszystkie komórki I * J, aby upewnić się, że nie ma gdzieś 4 lub 6 w macierzy. – Seph

+0

to jest lepsze podejście do pracy z –

+0

@HabiSoft Twoje rozwiązanie wydaje się działać dobrze i rozwiązuje tablicę 1D w O (log n), czy możesz również opublikować pseudo kod do znajdowania lokalnych maksimów w macierzy 2D, mam problem z zaniżeniem tego po prostu czytając treść. –