Bewertung der durchschnittlichen Zeitkomplexität eines gegebenen Bubblesort-Algorithmus.

11

Betrachtet man diesen Pseudocode eines Bubblesorts:

FOR i := 0 TO arraylength(list) STEP 1  
    switched := false
    FOR j := 0 TO arraylength(list)-(i+1) STEP 1
        IF list[j] > list[j + 1] THEN
            switch(list,j,j+1)
            switched := true
        ENDIF
    NEXT
    IF switched = false THEN
        break
    ENDIF
NEXT

Was wären die Grundideen, die ich berücksichtigen müsste, um die durchschnittliche Zeitkomplexität zu bewerten? Ich habe es bereits geschafft, die schlechtesten und besten Fälle zu berechnen, aber ich bin nicht sicher, wie ich die durchschnittliche Komplexität der inneren Schleife bewerten soll, um die Gleichung zu bilden.

Die Worst-Case-Gleichung lautet:

i=0n(j=0n(i+1)O(1)+O(1))=Ö(n22+n2)=Ö(n2)

wobei das innere Sigma die innere Schleife darstellt und das äußere Sigma die äußere Schleife darstellt. Ich denke, dass ich beide Sigmas aufgrund der "if-then-break" -Klausel ändern muss, die das äußere Sigma beeinflussen könnte, aber auch aufgrund der if-Klausel in der inneren Schleife, die die während einer Schleife ausgeführten Aktionen beeinflusst (4 Aktionen + 1 Vergleich, wenn wahr, sonst nur 1 Vergleich).

Zur Verdeutlichung des Begriffs Durchschnittszeit: Dieser Sortieralgorithmus benötigt unterschiedliche Zeit für verschiedene Listen (gleicher Länge), da der Algorithmus möglicherweise mehr oder weniger Schritte durch / innerhalb der Schleifen benötigt, bis die Liste vollständig in Ordnung ist. Ich versuche einen mathematischen (nicht statistischen) Weg zu finden, um den Durchschnitt der benötigten Runden zu bewerten.

Dafür erwarte ich, dass jede Bestellung die gleiche Möglichkeit hat.

Sim
quelle
6
Sie müssen zuerst definieren, was Durchschnitt überhaupt bedeutet. Da der Algorithmus deterministisch ist, müssten Sie eine Art Verteilung über Eingaben annehmen.
Suresh
@ Sim Können Sie zeigen, wie Sie die Zeitkomplexität im ungünstigsten Fall berechnet haben? Dann könnten wir eine Vorstellung davon bekommen, was Sie unter durchschnittlicher Komplexität in Ihrem Fall verstehen.
0x0
Ich meine die durchschnittliche Zeit in Bezug auf die wahrscheinlichste benötigte Zeit (oder mit anderen Worten die "reine" mathematische Version von: der Mittelwert aller Zeiten, die bei einer statistischen Analyse beobachtet wurden). Zum Beispiel hat Quicksort einen Durchschnitt von nlogn, obwohl sein schlimmster Fall n ^ 2 ist.
Sim
1
@ Sim Im Fall von Blasensortierung Durchschnittsfall = Zeitkomplexität im ungünstigsten Fall, was bedeutet, Durchschnittsfall Zeitkomplexität ist auch n2
0x0
3
Es besteht ein Unterschied. Quicksort wird gemittelt "über die Auswahl der Münzwürfe bei der Auswahl eines Pivots", was nichts mit den Daten zu tun hat. Während Sie implizieren, dass Sie "über alle Eingaben" mitteln möchten, was (zum Beispiel) davon ausgeht, dass Sie erwarten, dass jede Reihenfolge der Eingabe mit der gleichen Wahrscheinlichkeit erfolgt. das ist vernünftig, sollte aber explizit angegeben werden.
Suresh

Antworten:

9

Bei Listen mit der Länge bedeutet Durchschnitt normalerweise, dass Sie mit einer gleichmäßigen Verteilung auf alle n beginnen müssen ! Permutationen von [ 1 , .., n ]: Das sind alle Listen, die Sie berücksichtigen müssen.nn!1n

Ihre durchschnittliche Komplexität wäre dann die Summe der Schrittanzahl für alle Listen geteilt durch .n!

Für eine gegebene Liste ist die Anzahl der Schritte Ihres Algorithmus n d, wobei d der größte Abstand zwischen einem Element x i und seiner rechtmäßigen Position i ist (aber nur, wenn es sich nach links bewegen muss) ist max i ( max ( 1 , i - x i ) ) .(xi)inddxiimaxi(max(1,ixi))

Dann rechnen Sie nach: Finden Sie für jedes die Anzahl c d von Listen mit dieser bestimmten maximalen Entfernung, dann ist der erwartete Wert von d :dcdd

1n! d=0n dcd

Und das sind die Grundgedanken ohne den schwierigsten Teil, der darin besteht, . Vielleicht gibt es aber eine einfachere Lösung.cd

EDIT: "erwartet" hinzugefügt

jmad
quelle
Wenn Sie eine Normalverteilung betrachten, gibt es eine Möglichkeit, zu approximieren ? cd
Sim
Sie können sagen, weil man überall all Permutationen von mischen kann [ 2 , .., d ] und Anfügen 1 am Ende , aber das ist zu klein um zu beweisen , n ² im Durchschnitt. cd(n+1d)(d1)!2d1n²
jmad
19

Denken Sie daran, dass ein Paar (bzw. ( i , j ) ) invertiert ist, wenn i < j und A [ i ] > A [ j ] .(A[i],A[j])(i,j)i<jA[i]>A[j]

Angenommen, Ihr Algorithmus führt für jede Inversion einen Swap durch, hängt die Laufzeit Ihres Algorithmus von der Anzahl der Inversionen ab.

Die Berechnung der erwarteten Anzahl von Inversionen in einer einheitlichen zufälligen Permutation ist einfach:

Lassen eine Permutation, und sei R ( P ) umgekehrt sein P . Wenn zum Beispiel P = 2 , 1 , 3 , 4 ist, dann ist R ( P ) = 4 , 3 , 1 , 2 .PR(P)PP=2,1,3,4R(P)=4,3,1,2

Für jedes Indexpaar gibt es eine Inversion in genau einem von P oder R ( P ) .(i,j)PR(P)

Da die Gesamtzahl der Paare beträgt und die Gesamtzahl und jedes Paar in genau der Hälfte der Permutationen invertiert ist, unter der Annahme, dass alle Permutationen gleich wahrscheinlich sind, beträgt die erwartete Anzahl der Inversionen:n(n1)/2

n(n1)4
Joe
quelle
Dies bewertet die Anzahl der Inversionen. aber wie wäre es mit der Anzahl der Vergleiche, die von der Zeit abhängt, zu der die break-Klausel eingetreten ist
Sim
Sie erhalten einen Vergleich durch Swap und vor allem kann ein Swap die Anzahl der Inversionen um höchstens einen reduzieren.
jmad
Nicht jeder Vergleich führt zu einem Swap. Wenn die if-Klausel falsch ist, wird keine Inversion durchgeführt.
Sim
@rgrig Wenn Sie ein Gegenbeispiel angeben, werde ich meine Antwort korrigieren.
Joe
@ Joe: Ich habe meinen Kommentar entfernt. Es war falsch.
Rgrig
2

Anzahl der Swaps <Anzahl der Iterationen (sowohl im optimierten als auch im einfachen Bubble-Case-Szenario)

Anzahl der Inversionen = Anzahl der Swaps.

n(n1)4

ω(n2)O(n2)

θ(n2)

(Zeitkomplexität = Anzahl der Iterationen Anzahl der Iterationen> Anzahl der Swaps)

kushj
quelle