Zeitkomplexität

Laufzeit

In a nutshell

Die Laufzeit eines Algorithmus gibt an, wie viel Zeit benötigt wird, um eine Eingabegröße zu verarbeiten, oft in Abhängigkeit von der Größe der Eingabe dargestellt. Sie dient dazu, die Effizienz und Skalierbarkeit von Algorithmen zu bewerten und zu vergleichen.

Laufzeitanalyse Beispiel

In diesem Beispiel ist der Wert von sum Äquivalent zu der Anzahl an Schritten, die der Algorithmus durchläuft
Nach der Ausführung hat sum den Wert n

LineareMethode(n)Zeit1.sum012.for i1 to n don+13.sumsum+1n

Nach der Ausführung hat sum den Wert n2

QuadratischeMethode(n)Zeit1.sum012.for i1 to n don+13.for j1 to n don×(n+1)4.sumsum+1n2

Nach der Ausführung hat sum den Wert n3

KubischeMethode(n)Zeit1.sum012.for i1 to n don+13.for j1 to n don×(n+1)4.for k1 to n don2×(n+1)5.sumsum+1n3

Größenordnungen:

Wachstum W-Ordnungen N = 1000 10N 100N 1000N
konstant 1 1 Minute 1 Minute 1 Minute 1 Minute
logarithmisch log N 1 Minute 1,3 Minuten 1,6 Minuten 2 Minuten
linear N 1 Minute 10 Minuten 2 Stunden 1 Tag
leicht überlinear N log N 1 Minute 13 Minuten 3 Stunden 1½ Tage
quadratisch 1 Minute 2 Stunden 5 Tage 23 Wochen
kubisch 1 Minute 1 Tag 2 Jahre 2000 Jahre
exponentiell 2^N 1 Minute

Fallunterscheidung

Worst-Case Analyse

Average-Case Analyse

Best-Case Analyse

Beispiel: Laufzeitanalyse von insertion sort

InsertionSort(A)Zeit1.for j2 to length(A) don2.keyA[j]n13.ij1n14.while i>0 and A[i]>key don1+tj5.A[i+1]A[i]tj6.ii1tj7.A[i+1]keyn15n4+3tj

tj: Anzahl Wiederholungen der while-Schleife bei Laufindex j

Worst-Case

T(n)=5n4+3j=2n(j1)=2n4+3j=1nj=2n4+3n(n+1)2=3n2+7n82

-> konstante Faktoren wenig Aussagekräftig, da hier im Beispiel gezeigt wird, dass bei steigendem n alles von 3n2 abhängt.

Asymptotische Laufzeitanalyse

O-Notation – Obere Schranke

!250

Ω-Notation – Untere Schranke

!250

Θ-Notation (Theta-Notation)

Echte obere und untere Schranke

Interpretation

"asymptotische Version" von
O
Ω
Θ =
o <
ω >
Ausdruck Wachstum von f Vergleich Wachstum von g
fo(g) Wachstum von f < Wachstum von g
fO(g) Wachstum von f Wachstum von g
fΘ(g) Wachstum von f = Wachstum von g
fΩ(g) Wachstum von f Wachstum von g
fω(g) Wachstum von f > Wachstum von g

Mehrere Parameter & Datenstrukturen:

Laufzeitklassen

n! faktoriell
O(2n) exponentiell
O(n3) kubisch
O(n2) quadratisch (polynomiell)
O(nlog(n)) super-linear
O(n) linear
O((x)) Wurzelfunktion
O(log(n)) logarithmisch
O(1) beschränkt/konstant

Hierarchie

O(logn)O(n)O(n2)O(nc)O(2n)
(für c2) (nicht vollständig)
!Laufzeitklassen Vergleich.png

Laufzeitanalyse von Sortieralgorithmen

Laufzeit elementarer Java-Strukturen (worst-case)

Struktur Operation Laufzeit
Stack (Resizing‑Array) push, pop O(1)
Queue (Ring‑Array) enqueue, dequeue O(1)
LinkedList addFirst, pollFirst O(1)
get(i), set(i), contains O(N)
PriorityQueue (Heap) add, removeMin O(log N)
ArrayList / ArrayDeque addLast amort. O(1)

(ArrayDeque meist schnellste Deque; ArrayList Einfügen mitten­drin O(N)).

Rekursionsbaum

Muster Baumhöhe Verzweigungen k Gesamtlaufzeit
T(N)=T(N−1)+c O(N) 1 Θ(N)
T(N)=T(N/2)+c O(log N) 1 Θ(log N)
T(N)=T(N−1)+T(N−2)+T(N−3)+c O(N) 3 O(3ᴺ)
T(N)=2·T(N/2)+c O(log N) 2 Θ(N)

Komplexitätsklassen

Komplexitätsklassen sind Kategorien, die Berechnungsprobleme danach gruppieren, wie viel Rechenzeit ein Algorithmus im schlimmsten Fall benötigt, um sie zu lösen, abhängig von der Größe der Eingabe.

Klasse Definition Bedeutung
P Probleme lösbar in polynomieller Zeit „praktisch“ effizient
NP Lösung prüfbar in polynomieller Zeit enthält P
NP‑schwer Jedes NP‑Problem polynomiell reduzierbar mind. so schwer wie NP
NP‑vollständig in NP und NP‑schwer härteste NP‑Probleme

Typische NP‑vollständige Probleme

k=0n12k=1(1/2)n+1112=2(112n+1)=212n.