Rozróżnienie przypadków w programowaniu dynamicznym: potrzebny przykład!


19

Od jakiegoś czasu pracuję nad programowaniem dynamicznym. Kanonicznym sposobem oceny dynamicznej rekurencji programowania jest utworzenie tabeli wszystkich niezbędnych wartości i wypełnienie jej wiersz po wierszu. Zobacz na przykład Cormen, Leiserson i in .: „Wprowadzenie do algorytmów” .

Skupiam się na opartym na tabeli schemacie obliczeń w dwóch wymiarach (wypełnianie wiersz po rzędzie) i badam strukturę zależności między komórkami, tj. Które komórki należy wykonać, zanim można obliczyć inny. Oznaczamy za pomocą zestaw wskaźników komórek, od których zależy komórka . Pamiętaj, że musi być wolna od cyklu.Γ(ja)jaΓ

Abstrahuję od obliczonej faktycznej funkcji i koncentruję się na jej strukturze rekurencyjnej. Formalnie uważam, że nawrót jest programowaniem dynamicznym, jeśli ma taką formęre

re(ja)=fa(ja,Γ~re(ja))

z , i niektóre (obliczalne) funkcje, które nie używają inne niż przez .ja[0m]×[0n]Γ~d(i)={(j,d(j))jΓd(i)}fdΓ~d

Ograniczając ziarnistość do szorstkich obszarów (po lewej, u góry po lewej, u góry, u góry po prawej, ... w bieżącej komórce) należy zauważyć, że istnieją zasadniczo trzy przypadki (do symetrii i obrotu) dynamiczne rekurencje programowania, które informują o sposobie wypełnienia tabeli:Γd

Trzy przypadki dynamicznych zależności programowania komórek

Czerwone obszary oznaczają (nadmierne przybliżenia) . Przypadki pierwszy i drugi dopuszczają podzbiory, przypadek trzeci to najgorszy przypadek (do transformacji indeksu). Pamiętaj, że nie jest bezwzględnie wymagane, aby całe czerwone obszary były objęte ; niektóre komórki w każdej czerwonej części tabeli są wystarczające, aby pomalować ją na czerwono. Białe obszary są wyraźnie wymagane, aby nie zawierały wymaganych komórek.ΓΓ

Przykładami przypadku pierwszego są odległość edycji i najdłuższy wspólny podciąg , przypadek drugi dotyczy Bellman i Forda oraz CYK . Mniej oczywiste przykłady obejmują takie, które działają na przekątnych, a nie na rzędach (lub kolumnach), ponieważ można je obracać w celu dopasowania do proponowanych przypadków; zobacz odpowiedź Joe na przykład.

Jednak nie mam (naturalnego) przykładu dla przypadku trzeciego! Więc moje pytanie brzmi: jakie są przykłady przypadków / problemów z dynamicznym programowaniem w przypadku trzecim?


2
Przypadek 3 obejmuje przypadki 1 i 2.
JeffE

Nie, nie wygląda to pomimo wyglądu. Na przykład instancja przypadku 1 nie może mieć wymaganej komórki w lewym górnym obszarze, podczas gdy instancja przypadku 3 musi mieć wymaganą komórkę w lewym górnym obszarze. Zredagowałem wyjaśnienie, aby wyjaśnić.
Raphael

Odpowiedzi:


15

Istnieje wiele innych przykładów algorytmów programowania dynamicznego, które w ogóle nie pasują do Twojego wzorca.

  • Najdłużej rosnący problem z podsekwencją wymaga tylko jednowymiarowej tabeli.

  • Istnieje kilka naturalnych algorytmów programowania dynamicznego, których tabele wymagają trzech lub nawet więcej wymiarów. Na przykład: Znajdź biały prostokąt o maksymalnej powierzchni na mapie bitowej. Naturalny algorytm programowania dynamicznego wykorzystuje tabelę trójwymiarową.

  • Ale co najważniejsze, programowanie dynamiczne nie dotyczy tabel ; chodzi o odwijanie rekurencji. Istnieje wiele naturalnych algorytmów programowania dynamicznego, w których struktura danych używana do przechowywania wyników pośrednich nie jest tablicą, ponieważ rozwijana rekurencja nie przekracza zakresu liczb całkowitych. Dwa proste przykłady to znalezienie największego niezależnego zestawu wierzchołków w drzewie i znalezienie największego wspólnego poddrzewa dwóch drzew. Bardziej złożonym przykładem jest algorytm aproksymacji dla problemu podróżnego sprzedawcy euklidesowego autorstwa Arory i Mitchella.(1+ϵ)


Dziękuję za odpowiedź, ale wyraźnie ograniczyłem pytanie do dwuwymiarowych problemów i kanonicznego, opartego na tabelach schematu obliczeniowego (zredagowanego, aby uczynić ten punkt jeszcze wyraźniejszym). Zdaję sobie sprawę z bardziej ogólnych ram, ale nie jestem nimi zainteresowany w tym momencie.
Raphael

9
Okej, ale myślę, że naprawdę nie rozumiesz.
JeffE

Ponieważ istnieje wiele pozytywnych opinii, pomyślałem, że powinienem to wyjaśnić: ten post nie odpowiada na pytanie i w rzeczywistości nawet nie próbuje.
Raphael

2
@ Rafael ma rację. Moja „odpowiedź” nie jest odpowiedzią, ale krytyką pytania, ale na komentarz był za długi.
JeffE

3

Obliczanie funkcji Ackermanna jest w tym duchu. Aby obliczyć , musisz znać A ( m , n - 1 ) i A ( m - 1 , k ) dla niektórych dużych k . Druga współrzędna maleje lub pierwsza maleje, a druga potencjalnie wzrasta.A(m,n)A(m,n1)A(m1,k)k

Nie idealnie pasuje to do wymagań, ponieważ liczba kolumn jest nieskończona, a obliczenia zwykle wykonuje się z góry na dół z zapamiętywaniem, ale myślę, że warto o tym wspomnieć.


1
Nie, zagnieżdżanie jak w tak naprawdę nie nadaje się do programowania dynamicznego. Hehe, to takie dziwne, że muszę sprawdzić, czy moje definicje jakoś wykluczają takie przypadki. Nieprymitywno-rekurencyjny DP, o mój ...A(m1,A(m,n1))
Raphael

1
Nie jestem pewien, dlaczego ta odpowiedź została odrzucona, ponieważ jest to dobra odpowiedź. Funkcja Ackermann doskonale nadaje się do programowania dynamicznego. Zasadniczo każda rekurencyjnie zdefiniowana funkcja, która jest wielokrotnie obliczana dla tych samych argumentów, nadaje się do programowania dynamicznego. Aby to zobaczyć, wystarczy go zaimplementować i porównać czasy działania. Obliczenia za pomocą zwykłej funkcji Ackermanna zajmują lata, a programowanie dynamiczne może zająć kilka sekund.
Jules

@Jules: Problemem w kanonicznym schemacie tabel jest to, że nie znasz (prymitywnej rekurencyjnej) powiązanej z rozmiarem tabeli z góry. Oczywiście możesz robić notatki, ale nie do końca w zwykły sposób. Tak, może to być opłacalne dla DP, ale nie pasuje do klasy problemów, których dotyczy moje pytanie.
Raphael

1
Nie sądzę, aby wymagało to od DP, abyś miał a priori ograniczony rozmiar stołu? W rzeczywistości, jak wspomina JeffE, pamięć podręczna wcale nie musi być tabelą. Może to być dowolna asocjacyjna struktura danych. DP jest naprawdę bardzo bardzo prostym pomysłem: chcesz obliczyć rekurencyjnie zdefiniowaną funkcję, ale funkcja ta jest wielokrotnie wywoływana z tymi samymi argumentami. DP to optymalizacja, w której wprowadzasz pamięć podręczną, aby upewnić się, że obliczasz każdy przypadek tylko raz. Istnieje wiele funkcji, które nie mieszczą się w żadnym z twoich przypadków, nawet jeśli są funkcjami dwóch liczb całkowitych z ograniczeniami.
Jules

2

To nie pasuje dokładnie do przypadku 3, ale nie wiem, czy któryś z twoich przypadków wychwytuje bardzo częsty problem używany do nauczania programowania dynamicznego: mnożenie łańcucha macierzy . Aby rozwiązać ten problem (i wiele innych, to tylko kanoniczny), wypełniamy macierz diagonalnie po przekątnej zamiast rzęd po rzędzie.

Więc zasada jest taka:

diagMatrix


1
Tak napisane, że tak naprawdę nie pasuje do żadnego przypadku. Jeśli jednak obrócisz w prawo o 45 stopni, otrzymasz przypadek 2 (i wszystkie implikowane właściwości). Odnosi się to również do innych przykładów, które działają od ukośnego do narożników. Ale dziękuję, że o tym wspomniałeś!
Raphael

@ Rafael, nie jest od razu oczywiste, że są one równoważne, możesz wspomnieć o tym w swoim pytaniu.
Joe

0

Wiem, że to głupi przykład, ale myślę, że to prosty iteracyjny problem

Znajdź sumę liczb w macierzy kwadratowej

może się zakwalifikować. Tradycyjne „dla każdego wiersza dla każdej kolumny” wygląda jak twój przypadek 3.


-1

To nie jest dokładnie to, czego szukasz, ale mam pomysł na czubek głowy, który może być pomocny.

Problem:

n×nMxM

Odpowiedź

Można to rozwiązać w następujący sposób rekurencyjny:

k=1+n2xmk,kx<mk,kmi,jkinkjn1/4x>mk,k1/434n2x(34)3n2


1
To nie jest przypadek programowania dynamicznego, prawda?
Raphael
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.