Ich bin festgefahren, wenn ich die zeitliche Komplexität des folgenden Algorithmus analysiere:
def fun (r, k, d, p):
if d > p:
return r
if d = 0 and p = 0:
r <- r + k
return r
if d > 0:
fun (r, k + 1, d - 1, p)
if p > 0:
fun (r, k - 1, d, p - 1)
Der Root-Aufruf wird fun (0, 0, n, n)
und n
ist die Größe des Problems.
Ich denke das: Die Wiederholungsrelation ist , was und somit .
Ist meine Analyse korrekt (ich weiß, dass sie nicht sehr vollständig und genau ist)? Wenn es einen schwerwiegenden Fehler gibt, weisen Sie bitte darauf hin oder zeigen Sie mir einen korrekten und vollständigen Beweis für die zeitliche Komplexität dieses Algorithmus.
d>0
als auchp>0
. Sie zeigen nicht, was die Funktion zurückgibt, wenn wir die 3. und 4. if-Anweisung erreichen. Wollten Siereturn
nach jedem rekursiven Aufruf von eine Anweisung habenfun
? (Wollten Siefun (r, k + 1, d - 1, p)
es seinreturn fun (r, k + 1, d - 1, p)
?) Oder wollten Sie einereturn
Aussage ganz am Ende des Funktionskörpers haben? Bitte bearbeiten Sie Ihren Pseudocode, um zu verdeutlichen und sicherzustellen, dass Sie zeigen, was dies in allen möglichen Fällen zurückgibt.d<=p
undd>0
undp>0
alle halten. Was soll passieren? Führt der Algorithmus zwei rekursive Aufrufe der Funktion durch? Oder ruft es rekursiv auffun(r, k + 1, d - 1, p)
und kehrt dann sofort zurück, ohne rekursiv aufzurufenfun(r, k - 1, d, p - 1)
? Wenn ich Ihren Pseudocode wörtlich nehme, scheint es, dass er zwei rekursive Aufrufe ausführt und dann mit einem undefinierten Rückgabewert zurückkehrt - aber das scheint seltsam und lässt mich fragen, ob der Pseudocode einen Tippfehler enthält.Antworten:
Um eine Obergrenze zu erhalten, beachten Sie, dass wir auf dem Weg zu jedem Blatt durch Knoten gehen und dies eine Obergrenze ergibt, die größer ist als die Untergrenze, dh .2 n Θ ( 4 n / √2n 2n Θ(4n/n−−√)
Wir haben eine Untergrenze von und eine Obergrenze von . Was sind die genauen Asymptotika? Sie wachsen wie die Gesamtzahl der Pfade, die die X-Achse nicht kreuzen und höchstens Schritte in jede Richtung aufweisen. Unter Verwendung des Wahlsatzes von Bertrand können wir einen genauen Ausdruck dafür erhalten: Es bleibt also, diese Summe asymptotisch zu schätzen: O ( 4 n / √Ω(4n/n3/2) n Σ 0 ≤ d ≤ p ≤ N p - d + 1O(4n/n−−√) n
quelle
Von Fall zu Fall:
fun
rekursiert auf d-1 bis d ≯ 0; da p> 0 ist, ist dies in d + linear (Fall 4) .fun
rekursiv auf p-1 bis p ≯ 0; Dies ist linear in p + (einer von Fall 1, 2 oder 5).Beginnend mit d = p = n> 0 trifft Fall 3, gefolgt von Fall 4. Wenn n eine ganze Zahl ist, ist der letzte Fall 2, andernfalls ist der letzte Fall 5. Die Gesamtzeit für diese Fälle ist d + p +1 oder 2n + 1.
quelle
if
als "mach eine davon" genommen, während @Yuval sie als "jede dieser in der richtigen Reihenfolge betrachten" nahm. Letzteres ist natürlich das, wasif
s (ohneelse
) im tatsächlichen Code bedeutet; Ich bin an Ersteres in fast jedem anderen Kontext als dem eigentlichen Code gewöhnt (auch im Pseudocode, obwohl die Verwendung im Pseudocode inkonsistent ist).return
Anweisungen in der zweiten Hälfte des Codes macht dies ziemlich verwirrend.