Dynamische Programmierung gibt Ihnen die Möglichkeit, über das Algorithmus-Design nachzudenken. Das ist oft sehr hilfreich.
Memo- und Bottom-Up-Methoden bieten eine Regel / Methode, mit der Sie Wiederholungsrelationen in Code umwandeln können. Memoization ist eine relativ einfache Idee, aber die besten Ideen sind oft!
Die dynamische Programmierung gibt Ihnen eine strukturierte Möglichkeit, über die Laufzeit Ihres Algorithmus nachzudenken. Die Laufzeit wird im Wesentlichen durch zwei Zahlen bestimmt: die Anzahl der zu lösenden Teilprobleme und die Zeit, die zur Lösung jedes Teilproblems benötigt wird. Dies bietet eine bequeme und einfache Möglichkeit, über das Algorithmus-Design-Problem nachzudenken. Wenn Sie eine Kandidaten - Wiederholungsbeziehung haben, können Sie sich diese ansehen und sehr schnell ein Bild von der Laufzeit machen (z. B. können Sie oft sehr schnell feststellen, wie viele Unterprobleme es geben wird, was eine Untergrenze für das ist Laufzeit; wenn es exponentiell viele zu lösende Teilprobleme gibt, ist die Wiederholung wahrscheinlich kein guter Ansatz). Dies hilft Ihnen auch dabei, mögliche Zerlegungen von Teilproblemen auszuschließen. Zum Beispiel, wenn wir eine Zeichenfolge haben , wobei ein Unterproblem durch ein Präfix S [ 1 .. i ] oder ein Suffix S [ j] definiert wird . . n ] oder Teilzeichenfolge S [ i . . j ] mag vernünftig sein (die Anzahl der Teilprobleme ist in n polynomisch), aber die Definition eines Teilproblems durch eine Teilsequenz von S ist wahrscheinlich kein guter Ansatz (die Anzahl der Teilprobleme ist in n exponentiell). Auf diese Weise können Sie den "Suchbereich" für mögliche Wiederholungen beschneiden.S[ 1 .. n ]S[ 1 .. i ]S[ j . . n ]S[ i . . j ]nSn
Dynamische Programmierung bietet Ihnen einen strukturierten Ansatz für die Suche nach Kandidaten-Wiederholungsrelationen. Empirisch ist dieser Ansatz oft effektiv. Insbesondere gibt es einige Heuristiken / allgemeine Muster, die Sie je nach Art der Eingabe für allgemeine Methoden zum Definieren von Unterproblemen erkennen können. Zum Beispiel:
Wenn die Eingabe eine positive ganze Zahl , besteht ein möglicher Weg zum Definieren eines Unterproblems darin, n durch eine kleinere ganze Zahl n 'zu ersetzen (st 0 ≤ n ' ≤ n ).nnn′0 ≤ n′≤ n
Wenn es sich bei der Eingabe um eine Zeichenfolge , gibt es folgende Möglichkeiten, ein Unterproblem zu definieren: Ersetzen Sie S [ 1 .. n ] durch ein Präfix S [ 1 .. i ] ; Ersetzen Sie S [ 1 .. n ] durch ein Suffix S [ j . . n ] ; Ersetzen Sie S [ 1 .. n ] durch eine Teilzeichenfolge S [ i . . j ]S[ 1 .. n ]S[ 1 .. n ]S[ 1 .. i ]S[ 1 .. n ]S[ j . . n ]S[ 1 .. n ]S[ i . . j ]. (Hier wird das Teilproblem durch die Wahl von .)ich , j
Wenn es sich bei der Eingabe um eine Liste handelt , verfahren Sie genauso wie bei einer Zeichenfolge.
Wenn die Eingabe ein Baum , besteht ein möglicher Weg zum Definieren eines Unterproblems darin, T durch einen beliebigen Teilbaum von T zu ersetzen (dh einen Knoten x auszuwählen und T durch den Teilbaum zu ersetzen, der bei x verwurzelt ist ; das Unterproblem wird durch die Wahl von x bestimmt ).TTTxTxx
Wenn die Eingabe ein Paar , überprüfen Sie rekursiv den Typ von x und den Typ von y , um einen Weg zu finden, für jedes ein Unterproblem auszuwählen. Mit anderen Worten, ein möglicher Weg, ein Unterproblem zu definieren, besteht darin, ( x , y ) durch ( x ' , y ' ) zu ersetzen , wobei x ' ein Unterproblem für x ist und y ' ein Unterproblem für y ist . (Sie können auch Teilprobleme der Form ( x , y( x , y)xy( x , y)( x′, y′)x′xy′y Oder ( x ' , y ) .)( x , y′)( x′, y)
Und so weiter. Dies gibt Ihnen eine sehr nützliche Heuristik: Wenn Sie sich nur die Typensignatur der Methode ansehen, können Sie eine Liste von Kandidaten für die Definition von Teilproblemen erstellen. Mit anderen Worten, wenn Sie sich nur die Problemstellung ansehen - nur die Arten der Eingaben -, können Sie eine Handvoll von Kandidaten für die Definition eines Teilproblems finden.
Das ist oft sehr hilfreich. Es sagt Ihnen nichts über die Wiederholungsrelation aus, aber wenn Sie eine bestimmte Wahl zur Definition des Unterproblems haben, ist es oft nicht allzu schwierig, eine entsprechende Wiederholungsrelation zu erarbeiten. Daher wird das Design eines dynamischen Programmieralgorithmus häufig zu einer strukturierten Erfahrung. Sie notieren sich auf dem Altpapier eine Liste der möglichen Möglichkeiten, um Unterprobleme zu definieren (unter Verwendung der obigen Heuristik). Anschließend versuchen Sie, für jeden Kandidaten eine Wiederholungsrelation aufzuschreiben und ihre Laufzeit durch Zählen der Anzahl der Teilprobleme und der pro Teilproblem aufgewendeten Zeit zu bewerten. Nachdem Sie jeden Kandidaten ausprobiert haben, behalten Sie den besten, den Sie finden konnten. Das Bereitstellen einer Struktur für den Algorithmusentwurf ist eine wichtige Hilfe, da der Algorithmusentwurf ansonsten einschüchternd sein kann (da '