Was ist die zeitliche Komplexität dieser Funktion?

7

Dies ist ein Beispiel in meinen Vorlesungsunterlagen. Ist diese Funktion mit zeitlicher Komplexität ? Da der schlimmste Fall ist, geht die Funktion in einen Zweig und 2 verschachtelte Schleifen mit einer zeitlichen Komplexität von und , also ist es . Habe ich recht?Ö(nLogn)elseLognnÖ(nLogn)

int j = 3;
int k = j * n / 345;
if(k > 100){
    System.out.println("k: " + k);
}else{
    for(int i=1; i<n; i*=2){
        for(int j=0; j<i; j++){
            k++;
        }
    }
}
Zeitlos
quelle

Antworten:

5

Die zeitliche Komplexität des genannten Algorithmus ist , da Sie für eine konstante Operation (println) haben und wissen: , bedeutet für Ihr Algorithmus eine konstante Laufzeit hat (auch der andere Teil ist konstant, da nur für aufgerufen wird).Ö(1)K.>100j=3,k=3n/.345100=3n/.345n=11500n11500n<11500

Um klarer zu sein, werfen Sie einen Blick auf diese Frage.

Gemeinschaft
quelle
Vielleicht, um Ihre Antwort zu vervollständigen, sollten Sie erwähnen, dass wir uns, wenn wir über Zeitkomplexität sprechen, nur darum kümmern, was passiert, wenn . Oder Sie können auf eine der Fragen verlinken, die sich mit Komplexität befassen, wie diesen
Ran G.
@RanG. Sie haben absolut Recht. Eigentlich dachte ich, ich würde eine formale Definition von Big-Oh schreiben, aber ich dachte, jeder weiß das, eigentlich ist es genug, um es zu findenn0 für den Anfangswert c0für konstanten Koeffizienten. Ich entschiedn0, aber ich habe es nicht erwähnt c0(scheint klar zu sein), aber ja, ich werde es mit Raphaels Antwort verknüpfen (insgesamt bin ich schriftlich faul).
4

EDIT: Wie von Saeed Amiri hervorgehoben, ist dies tatsächlich Ö(1), da für asymptotisch groß nwird der elseZweig nicht wirklich genommen; Das ifTeil wird ausgeführt, was trivial konstant ist. Der Rest dieser Antwort, die ich als Referenz hinterlasse, wäre richtig, wenn zum Beispiel die Bedingung wäre k < 100. Entschuldigung für die Verwechslung.

Die zeitliche Komplexität wird im Wesentlichen in der Größenordnung der Häufigkeit liegen kwird in der verschachtelten forSchleife inkrementiert . Es gibt einige zusätzliche Dinge, aber wenn Sie darüber nachdenken, spielt das nur mit konstanten Faktoren. Wie oft wirdk erhöht werden?

Wann ich=1, kwird einmal erhöht. Wannich=2, kwird zwei weitere Male erhöht. Wannich=x, k wird erhöht xzusätzliche Zeiten. Nehmen wir das jetzt ann=2m+1. Dann wird die letzte Iteration der inneren Schleife kinkrementiert2m mal.

k wird eine Gesamtsumme von erhöht 1+2+...+2m mal oder 2(m+1)- -1mal. Erinnern Sie sich daran, dass `n=2m+1. Damitn- -1=2mund das haben wir k wird erhöht 2(n- -1)- -1 mal insgesamt.

k wird mehrmals inkrementiert, was linear ist n;; Ergo ist das allesÖ(n).

Patrick87
quelle
-1 Die zeitliche Komplexität ist unabhängig von der for-Schleife. (Siehe meine Antwort und probieren Sie es selbst aus).
1
@SaeedAmiri Ups, du hast recht. Ich habe das elseTeil irgendwie verfeinert, ohne die Vorbedingungen zu überprüfen. Antwort bearbeiten, um dies widerzuspiegeln.
Patrick87
Ja, jetzt ist deine Antwort richtig.
1

Obwohl die Kommentare zu den if / else-Zweigen alle korrekt sind, würde ich sagen, dass die Antwort O (log n) ist. Der Grund ist, dass

System.out.println("k: " + k);

beinhaltet die Konvertierung einer Ganzzahl in eine Zeichenfolgenausgabe, und dies ist im allgemeinen Fall O (log n) (nur um jede Ziffer auszudrucken, selbst wenn eine Nachschlagetabelle verwendet wurde).

Ich bin mir nicht sicher, ob das ein Trick war oder nicht ...

ex0du5
quelle
0

Wir werden sehen:

int j = 3; nimmt konstante Zeit O (1).

int k = j * n / 345Nimmt eine Logarithmus-Zeitfunktion von j- und n- Variablen

if (k > 100) nimmt konstante Zeit O (1).

System.out.println("k: " + k);nimmt die Logarithmuszeitfunktion von k

for (int i=1; i<n; i*=2)nimmt die Logarithmuszeitfunktion von n , Θ (log (n)), um genau zu sein, denn wenn t die Anzahl der Iterationen dieser for-Schleife ist, kann der Wert von i ausgedrückt werden als: i = 2 t-1 , wenn t = 1 in der ersten Iteration, so dass die Schleife so lange fortgesetzt wird, wie 2 t-1 <n ist , wobei sich n nicht ändert.

Wenn im Kalkül 2 t-1 <n ist, dann ist t-1 <log 2 (n)

Und wenn t-1 <log 2 (n) ist, dann ist t <log 2 (n) +1

Und wenn in jeder Iteration t um 1 erhöht wird, können wir sehen, dass diese for-Schleife wirklich Θ (log (n)) Zeit benötigt, wenn die Laufzeitkomplexität des Codes in dieser for-Schleife konstant ist, dh O (1) Na sicher!

In dieser for-Schleife befindet sich eine weitere for-Schleife:

for (int j=0; j<i; j++) k++;

Lassen Sie uns dies analysieren:

k++; nimmt konstante Zeit, dh O (1) Zeit.

Daher ist es interessant, die Laufzeitkomplexität der inneren for-Schleife zu analysieren.

Wir werden sehen:

Gemäß dem Code dieser inneren for-Schleife scheint es i Iterationen in dieser inneren for-Schleife zu geben, daher ist die Laufzeit Θ (i) , nicht nur O (i) , da sie in der Mitte nicht bricht. aber denken Sie daran, dass i <n ist , wegen der äußeren for-Schleife, so dass, obwohl am Anfang 1 Iteration erforderlich ist, wenn i = 1 , 2 Iterationen, wenn i = 2 , 4 Iterationen, wenn i = 4 , 8 Iterationen, wenn i = 8 . .. und etc, weil ich mich am Ende der äußeren for-Schleife in der Zeile i * = 2 verdopple , also beträgt die Ausführung insgesamt 1 + 2 + 4 + 8 + ... Iterationen, aber bis i≥nDie maximal mögliche Anzahl von Iterationen in dieser inneren for-Schleife ist also, wenn i = n-1 im schlimmsten Fall. Wenn also in der letzten Ausführung der inneren for-Schleife n-1 Iterationen ausgeführt wurden, bevor sie ausgeführt wurden ( n-1) / 2 Iterationen und davor lief es (n-1) / 4 Iterationen und davor lief es (n-1) / 8 Iterationen ... also war die Ausführung insgesamt:

n-1 + (n-1) / 2 + (n-1) / 4 + (n-1) / 8 ... = (n-1) (1 + 1/2 + 1/4 + 1/8 ...) = (n-1) (2) = 2n-2 = Θ (n)

Denken Sie daran, dass 1 + 1/2 + 1/4 + 1/8 ... = 2 eine bekannte Summe der geometrischen Sequenzen ist.

Denken Sie daran, dass die äußere for-Schleife Θ nimmt (log (n))

Und die innere for-Schleife nimmt Θ (n).

Und die Laufzeitkomplexität der for-Schleife innerhalb der for-Schleife ist die Laufzeitkomplexität der äußeren for-Schleife multipliziert mit der Laufzeitkomplexität der inneren for-Schleife, daher dauert es Θ (nlogn) Laufzeit.

Zusammenfassend ist die Laufzeit dieser Funktion also Θ (nlogn) .

Ich hoffe, dass dies Ihre Frage gut beantwortet und Ihnen zeigt, wie Sie die Laufzeitkomplexität von Algorithmen und Funktionen analysieren können.

Farewell Stack Exchange
quelle
Warum wurde meine Antwort schnell abgelehnt?
Farewell Stack Exchange
Ist meine Analyse falsch?
Farewell Stack Exchange
"int k = j * n / 345 benötigt eine Logarithmus-Zeitfunktion von j- und n-Variablen". Sie verwenden die logarithmischen Zeitkosten pro Operation für Zahlen, aber normalerweise werden die konstanten Zeitkosten pro Operation verwendet, wie dies auch durch die Frage beabsichtigt war. Außerdem ist Ihre Analyse der 2 Schleifen falsch, da j nur bis i in der inneren Schleife ausgeführt wird. O (n) ist, wie von jemand anderem erwähnt, richtig.
Albert Hendriks
Okay, ich stimme dir zu.
Farewell Stack Exchange