Ing Mathematik: Landau

Aus testwiki
Zur Navigation springen Zur Suche springen

Vorlage:Navigation zurückhochvor buch


Landau-Symbole werden in der Mathematik und Informatik verwendet, um das asymptotische Verhalten von Funktionen und Folgen zu beschreiben oder auch um das Zeitverhalten von Algorithmen abzuschätzen. Konkrete Laufzeitmessungen sind abhängig von der verwendeten Hardware. Um das auf abstrakterer Ebene durchzuführen verwendet man die Landau-Notation (auch O-Notation, auf englisch Big Oh Notation genannt). Eingeführt wurde das O-Symbol durch den Zahlentheoretiker Paul Bachmann. Bekannt wurde diese Notation durch den Mathematiker Edmund Landau. Es gibt mehrere Landau-Symbole, von denen die Gebräuchlichsten im Nachfolgenden kurz vorgestellt werden.

Vorlage:Wikipedia

Das O-Symbol

Die Definition f(n)=O(g(n)) bedeutet: f(n)cg(n) für alle nn0 und ein c+.

Genaugenommen ist das Gleichheitssymbol bei f(n)=O(g(n)) nicht korrekt. Es müsste heißen f(n)𝒪(g(n)). Aber in der Literatur ist meistens die Variante mit dem Gleichheitszeichen zu finden und das wird auch hier so gehandhabt. Dieses O-Symbol ist das von den Landau-Symbolen am meisten verwendete.

Beispiel 1

Gilt 2n+1=O(2n)?

Lösung:

Es muss gelten: f(n)cg(n), mit f(n)=2n+1,g(n)=2n, d.h.,

2n+1c2n

22nc2n

Mit c2 gilt für alle n0: 2n+1=O(2n), was zu zeigen war.

Nachfolgende Grafik zeigt obigen Sachverhalt für eine Konstante c=3.

Das zugehörige Python-Programm:

import matplotlib.pyplot as plt
import numpy as np

n = np.arange(0, 20, .1)
f = 2**(n+1)
g = 2**n
c = 3

plt.plot(n, f, label = "f = 2**(n+1)", color="orange")
plt.plot(n, c*g, label = "g = 2**n", color ="blue")
plt.grid()
plt.title("O-Notation")
plt.xlabel("n")
plt.ylabel("f,g")
plt.legend(loc="best")
plt.text(10,1e6,"mit c=3")

plt.show()

Beispiel 2

Gilt 2n=O(3n)?

Lösung:

Ja, denn 2nc3n gilt für alle n0 und z.B. c=1.

Das Ω-Symbol

Die Definition f(n)=Ω(g(n)) bedeutet: f(n)cg(n) für alle nn0 und ein c+.

Beispiel

Gilt nn=Ω(n!)?

Lösung:

Wir müssen zeigen, dass nncn! mit einem beliebigen c+, bspw. c=1. Am einfachsten machen wir das mit einer vollständigen Induktion.

Induktionsanfang: n=1

111!

11 passt!

Induktionsschritt:

(n+1)n+1(n+1)!

(n+1)(n+1)n((n+1)n!

(n+1)nn!

Die Induktionsvoraussetzung war aber, dass (n)nn!, somit gilt auch immer (n+1)nn!, was zu zeigen war. Es gilt somit nn=Ω(n!).

Python-Code:

import matplotlib.pyplot as plt
import numpy as np
import scipy.special as scs

n = np.arange(0.5, 5, 0.1)
f = n**n
g = scs.factorial(n)
c = 1

plt.plot(n, f, label = "f = n**n", color="orange")
plt.plot(n, c*g, label = "g = n!", color ="blue")
plt.grid()
plt.title("Omega-Notation")
plt.xlabel("n")
plt.ylabel("f,g")
plt.legend(loc="best")
plt.text(2,20,"mit c=1")
plt.semilogy()

plt.show()

Das Θ-Symbol

Die Definition f(n)=Θ(g(n)) bedeutet: c2g(n)f(n)c1g(n) für alle nn0 und c1,c2+.

Hier gilt es zu zeigen, dass f(n) ab einem n0 zwischen c1g(n) und c2g(n) liegt.

Aufgaben

  • Gilt n=Θ(logn3)?
  • Gilt 100=Θ(log100)?

Rechnen mit der Landau-Notation

Addition

O(f(n)+g(n))O(max(f(n),g(n))

Ω(f(n)+g(n))Ω(max(f(n),g(n))

Θ(f(n)+g(n))Θ(max(f(n),g(n))

Beispiel: O(n3+n2+1)=O(n3)

Multiplikation

O(cf(n))O(f(n))

Ω(cf(n))Ω(f(n))

Θ(cf(n))Θ(f(n))

mit c > 0.

Beispiel: O(500n3)=O(n3)


O(f(n))O(g(n))O(f(n)g(n))

Ω(f(n))Ωg(n))Ω(f(n)g(n))

Θ(f(n))Θg(n))Θ(f(n)g(n))

Beispiel: O(n)O(n!)=O(nn!)

Grenzwertregeln

Ab und zu finden sich auch folgende Regeln zur Definition von O und Ω.

limnf(n)g(n)<f(n)=O(g(n))

limnf(n)g(n)>0f(n)=Ω(g(n))

Komplexitätsklassen

Nachfolgend eine leicht überarbeitete Tabelle aus Vorlage:W mit gebräuchlichen Komplexitätsklassen. Wenn Sie am Anfang nicht alles verstehen - kein Problem, die Tabelle geht schon sehr ins Detail und ist eher für Informatiker von Interesse.

Vorlage:Wikipedia

Notation Bedeutung Anschauliche Erklärung Beispiele für Laufzeiten
f𝒪(1) f ist beschränkt. f überschreitet einen konstanten Wert nicht (ist unabhängig vom Wert des Arguments n). Feststellen, ob eine Binärzahl gerade ist
Nachschlagen des n-ten Elementes in einem Feld in einer Registermaschine
f𝒪(loglogn) f wächst doppel-logarithmisch. Bei Basis 2 erhöht sich f um 1, wenn n quadriert wird. Interpolationssuche im sortierten Feld mit n gleichförmig verteilten Einträgen
f𝒪(logn) f wächst logarithmisch. f wächst ungefähr um einen konstanten Betrag, wenn sich n verdoppelt.
Die Basis des Logarithmus ist dabei egal.
Binäre Suche im sortierten Feld mit n Einträgen
f𝒪(n) f wächst wie die Wurzelfunktion. f wächst ungefähr auf das Doppelte, wenn sich n vervierfacht. Anzahl der Divisionen des naiven Primzahltests (Teilen durch jede ganze Zahl n)
f𝒪(n) f wächst linear. f wächst ungefähr auf das Doppelte, wenn sich n verdoppelt. Suche im unsortierten Feld mit n Einträgen (Bsp. Lineare Suche)
f𝒪(nlogn) f hat super-lineares Wachstum. Vergleichbasierte Algorithmen zum Sortieren von n Zahlen

Mergesort, Heapsort

f𝒪(n2) f wächst quadratisch. f wächst ungefähr auf das Vierfache, wenn sich n verdoppelt. Einfache Algorithmen zum Sortieren von n Zahlen

Selectionsort

f𝒪(nm) f wächst polynomiell. f wächst ungefähr auf das 2m-Fache, wenn sich n verdoppelt. „Einfache“ Algorithmen
f𝒪(2n) f wächst exponentiell. f wächst ungefähr auf das Doppelte, wenn sich n um 1 erhöht. Erfüllbarkeitsproblem der Aussagenlogik (SAT) mittels erschöpfender Suche
f𝒪(n!) f wächst faktoriell. f wächst ungefähr auf das (n+1)-Fache, wenn sich n um 1 erhöht. Problem des Handlungsreisenden (mit erschöpfender Suche)
f𝒪(A(n)) f wächst wie die modifizierte Ackermannfunktion. Problem ist berechenbar, aber nicht notwendig primitiv-rekursiv

Abschätzungen mit der Landau-Notation

Meist wird man an der worst-case-Laufzeit interessiert sein, d.h. die Abschätzungen erfolgen mit dem O-Symbol, z.B.

n = 5                       # O(1)
m = 5                       # O(1)

for i in range(0, n, 1):    # O(n)
    print("Hallo Welt")     # O(1)
    print(m)                # O(1)    
    m += 1                  # O(1)

print("Ende")               # O(1)

Es ergibt sich O(1)+O(1)+O(n)*(O(1)+O(1)+O(1))+O(1)= O(2)+O(n)*O(3)+O(1)=O(2)+O(3n)+O(1)=O(n).

Dieses Beispiel ist von der Komplexitätsklasse O(n). Auch wenn hier die print-Befehle sicher mehr Ressourcen verbrauchen wie einfache Zuweisungen, so wird dies bei der Auswertung mit der Landau-Notation vernachlässigt.


Vorlage:Navigation zurückhochvor buch