Ein kurzer Ausflug in die Komplexitätstheorie

Werbung
Kapitel 2
Ein kurzer Ausflug in die
Komplexitätstheorie
Dieses Kapitel soll in die Grundlagen der Komplexitätstheorie einführen. Die Ausführungen
sind relativ informell und decken keinesfalls die Inhalte der Vorlesung „Komplexitätstheorie“
ab.
Um die Komplexitäten von Algorithmen und algorithmischen Problemstellungen zu untersuchen, benötigen wir in erster Linie ein Maß um diese anzugeben. Wir greifen hierzu auf
die sogenannten Landau-Symbole zurück.
Seit ihrer ersten Verwendung durch Bachmann im Jahr 1892 hat sich die O−Notation (gesprochen: „groß Oh“) durchgesetzt, um die Wachstumsgeschwindigkeit oder Größenordnung
von Funktionen f : N → R+ und damit von Rechenzeiten zu messen. Ziel ist es, die Beziehungen „≤“, „≥“, „=“, „<“ und „>“ auch auf Funktionen anzuwenden, wobei die strikte
Definition f ≤ g, falls f (n) ≤ g(n) ∀n ∈ N ist, durch eine abgeschwächte Bedingung ersetzt
wird.
Definition 2.1.
• g ∈ O(f ) hat die Interpretation, dass g asymptotisch nicht schneller als f wächst, und
ist definiert durch die Bedingung, dass g(n)/f (n) durch eine Konstante c nach oben
beschränkt ist. D.h.:
O(f ) = {g | g : N → R+ , ∃c > 0 ∃n0 ∈ N ∀n ≥ n0 : g(n) ≤ c · f (n)}
• g ∈ Ω(f ) hat die Interpretation, dass g asymptotisch nicht langsamer als (oder mindestens so schnell wie) f wächst, und ist definiert durch f ∈ O(g). D.h.:
Ω(f ) = {g | g : N → R+ , ∃c > 0 ∃n0 ∈ N ∀n ≥ n0 : g(n) ≥ c · f (n)}
• g ∈ Θ(f ) hat die Interpretation, dass f und g asymptotisch gleich schnell wachsen,
und ist definiert durch g ∈ (f ) und g ∈ Ω(f ). D.h. Θ(f ) = O(f ) ∩ Ω(f ) bzw.:
Θ(f ) = {g | g : N → R+ , ∃c > 0 ∃n0 ∈ N ∀n ≥ n0 :
1
· f (n) ≤ g(n) ≤ c · f (n)}
c
• g ∈ o(f ) hat die Interpretation, dass g asymptotisch langsamer als f wächst, und ist
definiert durch die Bedingung, dass g(n)/f (n) eine Nullfolge ist. D.h.:
o(f ) = {g | g : N → R+ , ∀c > 0 ∃n0 ∈ N ∀n ≥ n0 : g(n) < c · f (n)}
1
KAPITEL 2. EIN KURZER AUSFLUG IN DIE KOMPLEXITÄTSTHEORIE
2
• g ∈ ω(f ) hat die Interpretation, dass g asymptotisch schneller als f wächst, und ist
definiert durch f ∈ o(g). D.h.:
ω(f ) = {g | g : N → R+ , ∀c > 0 ∃n0 ∈ N ∀n ≥ n0 : g(n) > c · f (n)}
Beobachtung 2.2. Falls G ein zusammenhängender Graph ist, so gilt m(G) ∈ O(n(G)2 )
und m(G) ∈ Ω(n(G)).
Bei der Untersuchung von algorithmischen Problemstellungen unterscheiden wir grundsätzlich zwischen Optimierungsproblemen und Entscheidungsproblemen. Ersteres sind vielfältige
Fragestellungen nach (optimalen) Lösungen während letztere nur mit ja oder nein beantwortet werden können. Optimale Lösungen von Optimierungsproblemen und mögliche Lösungen, die zur positiven Beantwortungen eines Entscheidungsproblems führen, nennen wir
positive Lösungen.
Beispielsweise ist die Frage nach der kleinsten Zahl in einer gegebenen endlichen Teilmenge
der ganzen Zahlen ein Optimierungsproblem. Hingegen ist die Frage, ob eine gegebene endliche Teilmenge der ganzen Zahlen eine Zahl kleiner 0 besitzt, ein Entscheidungsproblem.
Falls M = {−3, −1, 0, 2, 5} die Teilmenge der ganzen Zahlen ist, so ist −3 die einzige positive Lösung des Optimierungsproblems. Hingegen sind −3 und −1 positive Lösungen des
Entscheidungsproblems.
Jedes Optimierungsproblem kann in ein Entscheidungsproblem umgeformt werden. Zum
Beispiel erhalten wir aus der Frage nach der kleinsten Zahl in einer endlichen Teilmenge der
ganzen Zahlen das folgende Entscheidungsproblem: Gegeben seien eine ganze Zahl C und
eine endliche Teilmenge M der ganzen Zahlen. Ist C die kleinste Zahl aus M ?
Mit Hilfe der obigen Definitionen können die Worst-Case Komplexitäten von Algorithmen
analysiert werden. Dabei unterscheidet man zwischen der (Lauf-) Zeitkomplexität, was die
Anzahl der im schlechtesten Fall nötigen Rechenschritte ist, und der Platzkomplexität, was
den im schlechtesten Fall nötigen Bedarf an Speicherplatz darstellt. Sei zum Beispiel der
folgende Algorithmus gegeben.
Algorithmus 1
Input: Ein Graph G mit Knoten {v1 , v2 , . . . , vn(G) } und Knotengewichten w : V (G) → R.
1: for i1 = 1 to n(G) do
2:
for i2 = 1 to n(G) do
..
3:
.
4:
for in(G) = 1 to n(G) do
Pn(G)
Bestimme w({vi1 , vi2 , . . . , vin(G) }) = j=1 w(vij ).
6:
end for
..
7:
.
8:
end for
9: end for
10: Bestimme S ? ∈ Argmax{w({vi1 , vi2 , . . . , vin(G) }) : i1 , i2 , . . . , in(G) ∈ [n(G)]}.
Output: Eine Menge S ? ⊆ V (G).
5:
Der Algorithmus berechnet n(G)n(G) mal den Wert w({vi1 , vi2 , . . . , vin(G) }) und speichert
diesen ab. Das heißt, er benötigt n(G) Speicherorte zum Verwahren der Gewichte w(vi ) und
n(G)n(G) Speicherorte zum Verwahren der Werte w({vi1 , vi2 , . . . , vin(G) }). Die Platzkomplexität ist also O(n(G)n(G) ). Bei der Bestimmung von w({vi1 , vi2 , . . . , vin(G) }) für gegebene
{i1 , i2 , . . . , in(G) } werden n(G) Werte in O(n) aufsummiert. Ein Maximum von
{w({vi1 , vi2 , . . . , vin(G) }) : i1 , i2 , . . . , in(G) ∈ [n(G)]}
KAPITEL 2. EIN KURZER AUSFLUG IN DIE KOMPLEXITÄTSTHEORIE
3
kann in O(n(G)n(G) ) Rechenschritten gefunden werden. Also ist die Zeitkomplexität des
Algorithmus O(n(G) · n(G)n(G) ).
Im Allgemeinen beschränken wir uns in dieser Vorlesung auf Untersuchungen zur Zeitkomplexität von Algorithmen und algorithmischen Problemstellungen.
Definition 2.3. Ein Algorithmus heißt effizient, wenn es ein Polynom p : N → R gibt,
sodass die Zeitkomplexität des Algorithmus O(p(n)) ist, wobei n das Maß für die Länge der
Eingabe ist.
Ein algorithmisches Problem, gleich ob Optimierungs- oder Entscheidungsproblem, gehört
zur Komplexitätsklasse P der polynomiell lösbaren Probleme, wenn es durch einen effizienten Algorithmus gelöst werden kann. Wir sagen dann, das Problem ist effizient lösbar.
Ein algorithmisches Problem gehört zur Komplexitätsklasse NP der nichtdeterministisch
polynomiell lösbaren Probleme, wenn eine positive Lösung, egal woher diese stammt, in
polynomieller Zeit überprüft werden kann.
Auch wenn man für einen Großteil der Problemstellungen aus NP in polynomieller Zeit
eine nicht positive Lösung verifizieren kann, ist unklar ob dies für alle Problemstellungen
aus NP gilt. Es is weiterhin klar, dass jedes Problem in P auch zu NP gehört. Ob auch
jedes Problem aus NP zu P gehört, führt zum Milleniumproblem
=
P
NP.
6=
Beispielweise gehören die beiden oben eingeführten Probleme zu kleinsten Zahlen in einer
endlichen Teilmenge M natürlicher Zahlen zur Klasse NP. Für eine beliebige natürliche
Zahl C kann in O(1) überprüft werden, ob diese negativ ist und in O(|M |) festgestellt
werden, ob sie ein Element aus M ist und ob sie gegebenenfalls die kleinste Zahl aus M
ist. Allgemein kann man die kleinste Zahl einer gegebenen endlichen Menge M in O(|M |)
bestimmen. Damit gehören beide Probleme auch zu P.
So wie mit Hilfe der Landau-Symbole Funktionen miteinander vergleichen werden, so können
wir auch algorithmische Problemstellungen untereinander in Beziehung setzen.
Definition 2.4. Seien A und B zwei algorithmische Probleme. Das Problem A ist algorithmisch nicht schwieriger als das Problem B, in Zeichen A ∝ B, wenn es einen Algorithmus
zur Lösung von A mit Maß n für die Länge der Eingabe gibt, der auf einen Algorithmus von
B zurückgreifen darf und folgende Eigenschaften hat:
• Die Rechenzeit ohne die Aufrufe zur Lösung von B ist durch ein Polynom p(n) beschränkt.
• Die Anzahl der Aufrufe des Algorithmus zur Lösung von B ist durch ein Polynom q(n)
beschränkt.
• Die Eingabelänge für jeden Aufruf des Algorithmus zur Lösung von B ist durch ein
Polynom r(n) beschränkt.
A und B sind algorithmisch gleich schwer falls A ∝ B und B ∝ A.
Mit Hilfe von Definition 2.4 können weitere Komplexitätsklassen definiert werden.
Definition 2.5. Ein algorithmisches Problem A gehört zur Komplexitätsklasse NP-schwer
der NP-schweren Probleme, falls für alle B ∈ NP die Beziehung B ∝ A gilt.
A gehört weiterhin zur Komplexitätsklasse NP-vollständig der NP-vollständig Probleme,
falls A ∈ NP und A ∈ NP-schwer.
Jedes Problem der Klasse NP-vollständig gehört auch zur Klasse NP-schwer. Andersherum
ist dies jedoch nicht immer der Fall.
Herunterladen