Bei einer amortisierten Analyse wird die zur Durchführung einer Folge von Datenstrukturoperationen erforderliche Zeit über alle durchgeführten Operationen gemittelt ... Die amortisierte Analyse unterscheidet sich von der Durchschnittsfallanalyse darin, dass die Wahrscheinlichkeit nicht beteiligt ist. Eine amortisierte Analyse garantiert im schlimmsten Fall die durchschnittliche Leistung jeder Operation.
(von Cormen et al., "Introduction to Algorithms")
Das könnte etwas verwirrend sein, da es sowohl besagt, dass die Zeit gemittelt wird, als auch, dass es sich nicht um eine Durchschnittsfallanalyse handelt. Lassen Sie mich versuchen, dies mit einer finanziellen Analogie zu erklären (in der Tat ist "amortisiert" ein Wort, das am häufigsten mit Bank- und Rechnungswesen in Verbindung gebracht wird.)
Angenommen, Sie betreiben eine Lotterie. (Sie kaufen keinen Lottoschein, auf den wir gleich noch eingehen, sondern betreiben die Lotterie selbst.) Sie drucken 100.000 Tickets, die Sie für jeweils 1 Währungseinheit verkaufen. Eines dieser Tickets berechtigt den Käufer zu 40.000 Währungseinheiten.
Angenommen, Sie können alle Tickets verkaufen, verdienen Sie 60.000 Währungseinheiten: 100.000 Währungseinheiten im Verkauf abzüglich des Preises von 40.000 Währungseinheiten. Für Sie beträgt der Wert jedes Tickets 0,60 Währungseinheiten, die über alle Tickets abgeschrieben werden. Dies ist ein zuverlässiger Wert. Darauf können Sie sich verlassen. Wenn Sie es leid sind, die Tickets selbst zu verkaufen, und jemand kommt und anbietet, sie für jeweils 0,30 Währungseinheiten zu verkaufen, wissen Sie genau, wo Sie stehen.
Für den Lotteriekäufer ist die Situation anders. Der Käufer hat beim Kauf eines Lottoscheins einen erwarteten Verlust von 0,60 Währungseinheiten. Aber das ist wahrscheinlich: Der Käufer kann 30 Jahre lang jeden Tag zehn Lottoscheine kaufen (etwas mehr als 100.000), ohne jemals zu gewinnen. Oder sie kaufen eines Tages spontan ein einzelnes Ticket und gewinnen 39.999 Währungseinheiten.
Bei der Datenstrukturanalyse handelt es sich um den ersten Fall, bei dem wir die Kosten für eine Datenstrukturoperation (z. B. Einfügen) über alle Operationen dieser Art amortisieren. Die Durchschnittsfallanalyse befasst sich mit dem erwarteten Wert einer stochastischen Operation (z. B. Suche), bei der wir nicht die Gesamtkosten aller Operationen berechnen können, sondern eine probabilistische Analyse der erwarteten Kosten einer einzelnen Operation liefern können.
Es wird oft behauptet, dass eine amortisierte Analyse für die Situation gilt, in der eine kostenintensive Operation selten ist, und das ist häufig der Fall. Aber nicht immer. Betrachten Sie zum Beispiel die sogenannte "Banker-Warteschlange", eine FIFO-Warteschlange (First-In-First-Out), die aus zwei Stapeln besteht. (Es ist eine klassische funktionale Datenstruktur; Sie können billige LIFO-Stapel aus unveränderlichen, einfach verknüpften Knoten erstellen, aber billige FIFOs sind nicht so offensichtlich). Die Operationen werden wie folgt implementiert:
put(x): Push x on the right-hand stack.
y=get(): If the left-hand stack is empty:
Pop each element off the right-hand stack and
push it onto the left-hand stack. This effectively
reverses the right-hand stack onto the left-hand stack.
Pop and return the top element of the left-hand stack.
Nun behaupte ich, dass die amortisierten Kosten von put
und get
sind O(1)
, vorausgesetzt, ich beginne und ende mit einer leeren Warteschlange. Die Analyse ist einfach: Ich put
gehe immer auf den rechten Stapel und get
vom linken Stapel. Abgesehen von der If
Klausel ist jeder put
ein push
und jeder get
ein a pop
, die beide sind O(1)
. Ich weiß nicht, wie oft ich die If
Klausel ausführen werde - es hängt vom Muster von put
s und get
s ab -, aber ich weiß, dass sich jedes Element genau einmal vom rechten zum linken Stapel bewegt. Die Gesamtkosten über die gesamte Folge von ns put
und ns get
betragen also: push
ns, ns pop
und ns move
, wobei a a move
istpop
gefolgt von a push
: Mit anderen Worten, die 2n-Operationen (ns put
und ns get
) führen zu push
2ns und 2ns pop
. Die fortgeführten Anschaffungskosten eines einzelnen put
oder get
sind eins push
und eins pop
.
Beachten Sie, dass Banker-Warteschlangen genau aufgrund der amortisierten Komplexitätsanalyse (und der Zuordnung des Wortes "amortisiert" zu Finanzen) so genannt werden. Die Warteschlangen von Banker sind die Antwort auf eine häufig gestellte Interviewfrage, obwohl ich denke, dass sie jetzt als zu bekannt angesehen wird: Überlegen Sie sich eine Warteschlange, die die folgenden drei Operationen in der amortisierten O (1) -Zeit implementiert:
1) Holen Sie sich das älteste Element der Warteschlange und entfernen Sie es.
2) Stellen Sie ein neues Element in die Warteschlange.
3) Ermitteln Sie den Wert des aktuellen Maximalelements.