Teile und Herrsche 1 SS11
Inhaltsverzeichnis |
Autoren:
- Maik Linke (s3malink@stud.hs-zigr.de)
- Romy Müller (s3romuel@stud.hs-zigr.de)
Die Idee
Teile und Herrsche
Bei der systematischen Programmentwicklung und für die unmittelbare Ableitung von Aufwandsaussagen sind verschiedene Entwurfsmethoden für Algorithmen hilfreich. Zu den Entwurfsmethoden gehören zum Beispiel:
- Teile und Herrsche
- Greedy-Algorithmen
- dynamisches Programmieren
Teile und Herrsche (engl. "divide and conquer", lat. "divide et impera") ist die Entwurfsmethode für Algorithmen die wir nachfolgend genauer betrachten wollen.
Diese Methode hat seinen Ursprung als Redewendung und Strategie in der Kriegsführung. Bereits um 500 v. Chr. erwähnte Sunzi, ein chinesischer General sinngemäß "Teile und Herrsche" als Stratgie der chinesischen Kriegskunst. Mit divise pour régner (frz. für "teilen, um zu herrschen") wurde sie als Ausspruch des frz. Königs Ludwig XI. (*1423 †1483) bekannt. Des Weiteren ist die Strategie in der römischen Außenpolitik zu Zeiten Julius Caesars wieder zu erkennen. In Bezug auf Kriegsführung besteht die Taktik darin, die Gegner durch gezieltes gegeneinander Ausspielen in kleine Gruppen zu spalten und somit leichter besiegen zu können.
Das Prinzip ist in der Informatik das Gleiche/ Selbe (!?), wenn auch weniger grausam. Die Methode löst Probleme, indem es
- in Teilprobleme zerlegt wird ("divide")
- die Teilprobleme gelöst und
- die Lösungen der Teilprobleme wieder zusammengesetzt werden ("conquer").
Effizienzbetrachtung von Teile und Herrsche
Wir wollen feststellen ob mit Algorithmen, die nach der Methode "divide and conquer" entworfen wurden, eine Effizienzverbesserung erzielt werden kann. Wir betrachten einen Algorithmus A der unser Problem in \mathcal{O} \left( n \right) , d.h mit T_A \left(n\right) \leq c \cdot n^2 löst. Der Algorithmus T_B bearbeitet drei Probleme der Größe \frac{n}{2} mittels der Prozedur A . Der Gesamtaufwand von unserem Algorithmus T_B fasst die Teillösungen mit einem Aufwand \mathcal{O} \left( n \right) zusammen.
Das Ergebnis zeigt, dass eine Effizienzverbesserung von 25 % festgestellt werden kann. Der Aufwand ist jedoch nach wie vor quadratisch, wie der Exponent der Funktion zeigt. Das bedeutet, dass für größere n keine große Verbesserung in der Effizienz erzielt werden kann. Die Betrachtung eines Algorithmus C , der die drei Teilprobleme mit Rekursion löst, verdeutlicht, dass wir uns mit diesem Ergebnis nicht zufrieden geben müssen. Der Basisfall n \leq n_0 wird weiterhin vom Algorithmus A übernommen. Es entstehen folgende Aufwandsziehungen:
Diese Rekursionsgleichung lösen wir mit dem 1. Fall der Meistermethode.
Die Lösung zeigt, dass durch eine rekursive Lösung die Effizienz dem quadratischen Aufwand gegenüber deutlich verbessert werden kann. Dies veranschaulicht, dass Teile-und-Herrsche-Verfahren immer rekursive Lösung der gebildeten Teilprobleme enthalten müssen. Die Teilprobleme haben eine geringere Problemgröße bei gleicher Problematik, als das zu lösende Ausgangsproblem. Zur rekursiven Lösung gehört ein allgemeiner Fall, wie auch ein Basisfall. Je nach Problem kann aber auch mehrere Basisfälle geben.
Quicksort
Verfahren
Quicksort (schnelles Sortieren) wurde 1962 von dem britischen Informatiker Charles Anthony Richard Hoare (* 11. Januar 1934) entwickelt. Die Idee des Algorithmus besteht darin, die Gesamtliste G = (a_1, a_2, ...,a_n) in eine linke und eine rechte Teilliste zu zerlegen, so dass alle Elemente von L kleiner und von R größer sind als das Vergleichsobjekt v \in G .
Wir vereinbaren, dass die Elemente von G paarweise verschieden sind, also für alle i \not = j gilt a_i \not = a_j. Diese Einschränkung ist nicht notwendig, aber sinnvoll, da es sich um Schlüssel zur Identifikation von Datensätzen handelt. Wir verabreden des Weiteren, dass es sich um natürliche Zahlen handelt. Zusätzlich legen wir fest, dass wir das am weitesten links stehende Element aus G als Vergleichselement v verwenden, also v = a_1 . Die Listen L_{sortiert} , v und R_{sortiert} bilden die sortierte Gesamtliste G_{sortiert} genau in dieser genannten Reihenfolge. Aus Effizienzgründen werden die Teillisten mit Quicksort sortiert.
Es gibt zwei Basisfälle: G ist leer oder besteht aus nur einem Element, dann ist G = G_{sortiert} . Wenn man G in die Teillisten L und R zerlegt, entstehen durch die Entnahme von v Listen, die mindestens ein Element weniger enthalten als G . Somit wird nach endlich vielen Zerlegungen einer der Elementarfälle erreicht.
Funktionsorientierte Beschreibung
erster Versuch :-)
Effizienzbetrachtung von Quicksort
Am Besten arbeitet Quicksort wenn die Teillisten ungefähr gleich groß sind. Es ergibt sie die Lösung von