Michael Auerbach 20901 Effiziente Algorithmen I: Approximationsalgorithmen – Motivation und Begriffe Viele fundamentale Optimierungsprobleme lassen sich für die Praxis nicht schnell genug exakt lösen. Daher besteht der Wunsch, das optimale (exakte) Ergebnis mit effizienten (d.h. schnelleren) Algorithmen möglichst gut anzunähern (zu approximieren). Ein erstes Beispiel ist das Problem Multiprozessor-Scheduling MPS: Gegeben: Eine Folge von n Jobs J1, . . . , Jn mit Laufzeiten d1, . . . , dn und m identische Maschinen. Gesucht: Eine Verteilung der Jobs auf die Maschinen, die die Bearbeitungszeit minimiert. Die optimale Lösung für dieses Problem würde man finden, in dem man alle möglichen Verteilungen der Jobs auf die Maschinen durchprobiert und sich die jeweils aktuelle Verteilung mit Bearbeitungszeit notiert, wenn sie eine kürzere Bearbeitungszeit aufweist als die bisher „beste“ Verteilung, d.h. als die Verteilung mit der bisher kürzesten Bearbeitungszeit. Dieses Durchprobieren aller Möglichkeiten führt aber zu einer mindestens exponentiellen Laufzeit des Algorithmus für zwei oder mehr Maschinen. Daher versucht man, einen Algorithmus zu finden, der polynomielle Laufzeit besitzt, und trotzdem möglichst nahe an die optimale Lösung herankommt. Eine Möglichkeit wäre, die Jobs der Reihe nach durchzugehen und den aktuellen Job der Maschine mit dem aktuell frühesten Terminierungszeitpunkt (d.h., der Maschine, die zuerst frei wird) zuzuordnen: ListScheduling FOR i:=1 TO m DO ti:=0;Li:=[]; END FOR k:=1 TO n DO Bestimme Maschine Mi mit frühestem Terminierungszeitpunkt ti; sk:=ti; Füge Job Jk an Belegungsliste Li an; ti:=ti + dk; END RETURN(L1,...,Lm) Erläuterung: Li ist die aktuelle Belegungsliste der Maschine Mi, ti ist die Terminierungszeit der Maschine Mi bezüglich der aktuellen Belegung und sk ist die Startzeit des Jobs Jk. Es zeigt sich, daß dieser Algorithmus ListScheduling eine Laufzeit von O(nm) besitzt (für jeden Job J1 bis Jn muß geprüft werden, welche der m Maschinen zuerst frei wird), und daß die von ihm ermittelte Verteilung eine Bearbeitungszeit besitzt, die kleiner oder gleich (2 - 1/m)*Optimum ist. Beweis: Sei Jk der Job, der zuletzt beendet wird, und Mi die ihn bearbeitende Maschine. Vor dem Startzeitpunkt sk müssen alle Maschinen belegt sein, sonst wäre für Jk eine andere Maschine gewählt worden. 1 Sei td = (1/m) * ∑ n i =0 ti = (1/m) * ∑ n i =0 di die durchschnittliche Terminierungszeit der Maschinen. Es gilt sk ≤ (1/m) * ( ∑i =0 di + k −1 ∑ n di ). Weiterhin ist das Optimum opt mindestens td, da td nicht von der gewählten Belegung abhängt. Zusätzlich gilt dk ≤ opt. i = k +1 Die Bearbeitungszeit sk+dk der von ListScheduling gelieferten Belegung ist demnach maximal n n k −1 k −1 ∑ di + ∑ di ∑ di + ∑ di + ( m * dk ) (m * dk ) i =1 i = k +1 i = k +1 i =1 + = m m m n ∑ di + ((m − 1) * dk ) (m − 1) * dk = i =1 = td + . m m Da dk und td kleiner oder gleich opt sind, können wir für sie opt einsetzen und erhalten für die Bearbeitungszeit die obere Schranke: opt + (m − 1) * opt 1 = 2 − * opt. m m Die relative Güte r beträgt also 2 − 1 . m Statt des Optimums der Bearbeitungszeit, welches nicht bekannt ist (und auch nur für konkrete Eingaben bekannt sein könnte), wird für die Abschätzung der Güte des Algorithmus (d.h., wie nahe er an die optimalen Lösungen aller möglichen Eingaben herankommt) eine untere Schranke für das Optimum genutzt, td = ((d1 + d2 + . . .+ dn-1 + dn ) / m), was dem Fall entspricht, wenn man alle Jobs so verteilen kann, daß die Maschinen bei voller Auslastung zum selben Zeitpunkt fertig werden. Die Suche nach einer Schranke für das Optimum ist ein entscheidender Schritt bei der Analyse und in einigen Fällen auch der Schlüssel zum Entwurf von Approximationsalgorithmen. Definition (Optimierungsproblem): Ein Optimierungsproblem Π besteht aus folgenden drei Komponenten: - den Instanzen, E = Menge aller Eingaben, - den Lösungen, S(I) = Menge aller zulässigen Lösungen der Instanz I ∈ E, - und der Zielfunktion z : S(I) → R+. Die Aufgabe liegt nun darin, zu einer gegebenen Instanz I ∈ E eine Lösung Opt(I) ∈ S(I) zu finden mit z(Opt(I)) ≤ z(σ) ∀σ ∈ S(I) (Minimierungsproblem) bzw. z(Opt(I)) ≥ z(σ) ∀σ ∈ S(I) (Maximierungsproblem). Den Wert einer optimalen Lösung bezeichnen wir mit opt(I) := z(Opt(I)). 2 Z.B. ist MPS ein Minimierungsproblem. Eine Instanz besteht aus der Zahl m der Maschinen und einer Folge von n Joblaufzeiten. Die zulässigen Lösungen sind alle Belegungen der Maschinen mit den n Jobs. Zielfunktion ist die Bearbeitungszeit einer Belegung. Diese ist zu minimieren. Definition (Approximationsalgorithmus): Gegeben sei ein Optimierungsproblem Π. Ein Algorithmus A heißt Approximationsalgorithmus für Π, falls gilt: - Die Laufzeit von A ist polynomiell in der Eingabegröße. - Für jede Instanz I ∈ E(Π) erzeugt A eine Lösung A(I) ∈ S(I). Den Wert der erzeugten Lösung bezeichnen wir mit a(I) := z(A(I)). Der Algorithmus ListScheduling ist ein Approximationsalgorithmus für MPS mit a(I) ≤(2 - 1/m) * opt(I) für jede Instanz I. Die Laufzeit des Algorithmus ist O(nm) und damit polynomiell. Definition (Approximationsfaktor): Sei A ein Approximationsalgorithmus für ein Optimierungsproblem Π. Der Approximationsfaktor RA(I) für die Instanz I ∈ E(Π) ist definiert als RA(I) := a(I) / opt(I). Wir bemerken, daß für Minimierungsprobleme stets RA(I) ≥ 1 und für Maximierungsprobleme stets RA(I) ≤ 1 gilt. RA(I) = 1 ist gleichbedeutend mit exaktem Lösen. Definition (Relative Güte): Ein Approximationsalgorithmus A für ein Minimierungsproblem Π hat relative Güte r, falls RA(I) ≤ r für alle I ∈ E(Π) gilt (bzw. RA(I) ≥ r für ein Maximierungsproblem). Beispielsweise erreicht der Algorithmus ListScheduling eine relative Güte von (2 - 1/m). Definition (Absolute Güte): Ein Approximationsalgorithmus A für ein Minimierungsproblem Π hat absolute Güte ag, falls |a(I) – opt(I)| ≤ ag für alle I ∈ E(Π) gilt. Die Komplexitätsklassen P und NP Um zu klären, was ein effizienter (schneller) Algorithmus ist und was ihn von einem ineffizienten Algorithmus unterscheidet, und warum also die Entwicklung von Approximationsalgorithmen sinnvoll ist, werden hier einige Begriffe erläutert. Definition (Entscheidungsproblem): Ein Entscheidungsproblem ist eine Abbildung D:E→{0,1}. Erklärung: E ist die Menge der möglichen Instanzen des Entscheidungsproblems und jede Instanz erhält die Antwort ja = 1 oder nein = 0. Beispiele: „Ist der Graph G zusammenhängend?“, „Gibt es ein Scheduling mit Bearbeitungszeit maximal k?“. Hinter dem zweiten Entscheidungsproblem steckt eigentlich das Optimierungsproblem MPS, was zeigt, wie aus einem Optimierungsproblem durch Hinzunahme einer Schranke k ein Entscheidungsproblem gemacht werden kann. 3 Definition (Assoziiertes Entscheidungsproblem): Sei Π ein Minimierungsproblem (Maximierungsproblem). Das zu Π assoziierte Entscheidungsproblem ist die Abbildung DΠ: E(Π) × R+ → {0, 1} mit DΠ(I, k) := 1, falls opt(I ) ≤ k (opt(I ) ≥ k); DΠ(I, k) := 0, falls opt(I ) > k (opt(I ) < k). Definition (Komplexitätsklasse P): Unter der Komplexitätsklasse P verstehen wir die Menge aller Entscheidungsprobleme, die sich durch einen polynomiellen Algorithmus lösen lassen. Die durch einen polynomiellen Algorithmus lösbaren Probleme gelten als effizient lösbar. Definition (Verifikationsalgorithmus): Sei D: E → {0, 1} ein Entscheidungsproblem. Ein Verifikationsalgorithmus für D ist ein polynomieller Algorithmus A mit Eingaben aus E × W, so daß für alle Eingaben I ∈ E gilt: D(I) = 1 ⇔ ∃ w ∈ W : A(I, w) = 1 und |w| = O(|I|c) für eine Konstante c. Erklärung: w ∈ W ist hierbei ein sogenannter Zeuge. Z.B. wäre dies beim Entscheidungsproblem DMPS „Gibt es ein Scheduling mit Bearbeitungszeit maximal k?“ eine Belegung der Maschinen, bei der die Bearbeitungszeit maximal k ist. Der dazugehörige Verifikationsalgorithmus A besteht dann darin, zu überprüfen, ob es sich um eine gültige Belegung handelt (ob w ∈ S(I)) und ob für die Bearbeitungszeit (Zielfunktion) z(w) ≤ k gilt. Wenn dies zutrifft, gibt der Algorithmus A eine 1 aus, woraus folgt, daß auch das Entscheidungsproblem DMPS mit 1=ja beantwortet wird, sonst wird eine 0 ausgegeben. Definition (Komplexitätsklasse NP): Wir definieren die Komplexitätsklasse NP als die Menge aller Entscheidungsprobleme, die einen Verifikationsalgorithmus besitzen. Definition (co-NP): Als co-NP definieren wir die Menge aller Entscheidungsprobleme D, deren Negation ¬D in NP liegen. Dies sind also Probleme, für die eine negative Antwort polynomiell verifizierbar ist. Z.B. ist das Problem „Gibt es kein Scheduling mit Bearbeitungszeit ≤ k?“ in co-NP, da DMPS „Gibt es ein Scheduling mit Bearbeitungszeit ≤ k?“ in NP liegt. Es wird vermutet, daß P ≠ NP und NP ≠ co-NP gilt. Um die Komplexität von Problemen zu vergleichen, wird der Begriff der polynomiellen Reduktion eingeführt. Definition (Polynomielle Reduktion): Seien D: E → {0, 1} und D’: E’ → {0, 1} Entscheidungsprobleme. Dann heißt D polynomiell reduzierbar auf D’, falls es einen polynomiellen Transformationsalgorithmus T: E → E’ gibt mit D(I) = D’(T(I)) ∀I ∈ E. In diesem Fall schreiben wir D ≤p D’. Gilt D ≤p D’, so ist also D „höchstens so schwer“ wie D’. Satz: Gelte D ≤p D’ und D’ ∈ P. Dann ist D ∈ P. Eine Klasse von besonders harten Problemen bilden die NP-schweren Probleme. 4 Definition (NP-schwer und NP-vollständig): Ein Entscheidungsproblem D’ heißt NPschwer, falls D ≤p D’ für alle D ∈ NP gilt. Liegt D’ zusätzlich in NP, so heißt D’ NPvollständig. Z.B. ist das Entscheidungsproblem DMPS NP-vollständig. Eine wichtige Konsequenz aus der P ≠ NP–Vermutung ist, daß NP-schwere Probleme nicht in polynomieller Zeit gelöst werden können, d.h. sie können nicht effizient (für die Praxis nicht schnell genug) gelöst werden. Weiterhin gilt: Satz: Sei D’ NP-schwer und D’ ≤p D’’. Dann ist auch D’’ NP-schwer. Definition (NP-schweres Optimierungsproblem): Ein Optimierungsproblem Π heißt NPschwer, wenn das assoziierte Entscheidungsproblem DΠ NP-schwer ist. Es folgt, daß das Optimierungsproblem MPS dann NP-schwer ist. Ein Optimierungsproblem ist also mindestens so schwer wie sein Entscheidungsproblem. Wenn ein Optimierungsproblem NP-schwer ist, kann man bestenfalls die exakte Lösung effizient (d.h. in Polynomialzeit) mit einem Approximationsalgorithmus annähern, aber man kann das Problem nicht in Polynomialzeit exakt lösen (sofern P ≠ NP ). Ein weiteres NP-schweres Problem (d.h., wir können es in der Praxis nicht exakt lösen) ist das Knapsack-Problem KNAP: Gegeben: Eine Menge D von n Gegenständen mit Volumina V1, . . . ,Vn und den Werten W1, . . . ,Wn ∈ N (z.B. in DM). Zum Verstauen der Gegenstände steht ein Rucksack mit Fassungsvermögen B bereit. Gesucht: Eine Packung X ⊆ D des Rucksacks (∑i∈X Vi ≤ B), die den Gesamtwert ∑i∈X Wi maximiert. Satz: Falls P ≠ NP, dann gibt es keinen Approximationsalgorithmus für KNAP mit konstanter absoluter Güte. Auch das folgende Travelling Salesman Problem (TSP) ist NP-schwer: Gegeben: Eine Kantengewichtung d : E(Kn) → R+ des vollständigen ungerichteten Graphen auf n ≥ 3 Ecken. (Interpretation: d(u, v) = Abstand zwischen u und v.) Gesucht: Ein Hamiltonscher Kreis (Rundreise) v0, v1, . . . , vn-1, vn = v0 mit minimaler Länge n −1 ∑ d (v , v i ). i +1 i =0 Ein Ansatz für einen Approximationsalgorithmus für das TSP besteht darin, eine zufällig erzeugte Rundreise sukzessive durch Umlegen von Kanten zu verbessern. Es gilt aber: Satz: Falls P ≠ NP, dann gibt es keinen Approximationsalgorithmus für TSP mit konstanter relativer Güte. 5