Table Of ContentMarkusvonRimscha
Algorithmen kompakt undverständlich
Markus von Rimscha
Algorithmen kompakt
und verständlich
Lösungsstrategien am Computer
2., überarbeitete und ergänzte Auflage
Mit 60 Abbildungen und 35 Tabellen
STUDIUM
VIEWEG+
TEUBNER
BibliografischeInformation der Deutschen Nationalbibliothek
DieDeutsche Nationalbibliothekverzeichnet diesePublikation inder
Deutschen Nationalbibliografie;detailliertebibliografischeDatensindim Internetüber
<http://dnb.d-nb.de>abrufbar.
Dasindiesem WerkenthalteneProgramm-Material istmit keinerverpftichtungoderGarantie irgend
einerArtverbunden. DerAutor übernimmtinfolgedessenkeineVerantwortungundwird keinedaraus
folgende oder sonstige Haltung übernehmen, die auf irgendeine Art aus der Benutzung dieses
Programm-MaterialsoderTeilendavonentsteht.
Höchste inhaltlicheundtechnischeQualitätunsererProdukteist unserZiel. Beider Produktion und
Auslieferung unserer Bücher wollen wir die Umwelt schonen: Dieses Buchist auf säurefreiem und
Chlorfrei gebleichtem Papier gedruckt. Die Einschweißfolie besteht aus Polyäthylen und damit aus
organischen Grundstoffen, die weder bei der Herstellung noch bei der Verbrennung Schadstoffe
freisetzen.
Verlag und Autor weisen darauf hin, dass keine Prüfung vorgenommen wurde, ob die Verwertung
der im Buchbeschriebenen Algorithmenund Verfahren mit Schutzrechten Dritter kollidiert.Verlag
undAutorschließen insofern jede Haftung aus.
1.Auflage2008
2.,überarbeiteteundergänzteAuflage 2010
Alle Rechtevorbehalten
© Vieweg+TeubnerIGWVFachverlageGmbH,Wiesbaden 2010
lektorat:Christel RoßIWalburgaHimmel
Vieweg+Teubnerist Teilder FachverlagsgruppeSpringerSeience-BusinessMedia.
www.viewegteubner.de
Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Jede
Verwertung außerhalb der engen Grenzen des Urheberrechtsgesetzes ist ohne
Zustimmung des Verlags unzulässig und strafbar. Das gilt insbesondere für
vervielfältigungen, Übersetzungen, Mikroverfilmungen und die Einspeicherung
undVerarbeitunginelektronischenSystemen.
DieWiedergabevon Gebrauchanamen, Handelsnamen. Warenbezeichnungen usw.in diesem Werk
berechtigt auch ohne besondere Kennzeichnung nicht zu der Annahme, dass solche Namen im
Sinne der Warenzeichen-und Markenschutz-Gesetzgebungals frei zubetrachten wären und daher
vonjedermannbenutztwerden dürften.
Umschlaggestaltung:Künkell.opka Medienentwicklung,Heidelberg
Druck undbucbbinderischeVerarbeitung:TenBrink, Meppel
Gedrucktaufsäurefreiem undchlorfreigebleichtem Papier.
Printed intheNetherlands
ISBN978-3-8348-0986-5
Vorwort
Sowohl bei der praktischen Arbeit in der Software-Entwicklung, als auch im Rah
men meiner unterrichtenden Tätigkeit werde ich immer wiedergefragt, wie die eine
oder andere Aufgabe am Rechner möglichst geschickt zu lösen sei. Selbstverständ
lich gibtesein breites Sortiment an Fachbüchern zu quasi jedemThema der Softwa
re-Entwicklung, also auch zu Problemlösungsstrategten am Computer - Algorith
men eben. Nicht selten umfassen diese jedoch hunderte von Seiten odergar mehrere
Bände, sind in Englisch geschrieben oder konzentrieren sich auf einen bestimmten
Themenbereich wie etwa Verfahren der Künstlichen Intelligenz oder wiederum
einen Teilaspektwie NeuronaleNetze.Der rote Faden gehthierallzu schnell verlo
ren.
Im Ergebnis wünschen sich viele Software-Entwickler' einen kompakten Leitfaden,
um Probleme selbstständiganzugehen.Zwarsind zahlreiche Verfahren für konkrete
Aufgaben bekanntund können im Zweifelsfallin der Literaturnachgeschlagen wer
den. Wenn aber eine neue oder sehr spezielle Herausforderung auftaucht, ist es an
der Zeit, selbst eine passende Lösung zu entwickeln. Dazu muss die jeweilige Idee
hinter den existierenden Verfahren bekannt sein. Deren Details bezüglich einzelner
Aufgebenstellungen sind zunächst oft ebenso wenig wichtig wie das letzte Quänt
chen an Optimierungspotenzial. Beides lässtsich meistnurbezogen auf diekonkrete
Aufgabe nutzen und istdamitvon Malzu Mal neu zu untersuchen.
Was möchte ich Ihnen also in diesem Buch nahe bringen? Wir werden uns hier un
terschiedliche grundsätzliche Strategien ansehen, wie man am Computer Probleme
lösen kann.Wirwerden lernen,wie man dasschnellund elegant tut,und ein Gefühl
dafür entwickeln,obein Verfahren die passendeLösung fürunsereAufgabe istoder
nicht. Wir werden anhand von einfachen Beispielen unterschiedliche Strategien sys
tematisch durchgehen, ihre Vor- und Nachteile kennen lernen und daraus passende
Anwendungsgebieteableiten.
Bewusst werden wir uns mit Beispielen aus unterschiedlichsten Bereichen beschäfti
gen, seien es Spielstrategten, Gewinnmaximierung durch Optimierung oder Muster
erkennung mit Hilfe Künstlicher Intelligenz.Wir werden uns keines derhier behan
delten Themen in voller Tiefeansehen - dazu seiauf die einschlägige Literatur ver-
Aus Gründen der Lesbarkeit wird in diesem Buch nicht zwischen der männlichen und
weiblichen Form unterschieden;essindjeweils beideGeschlechtergemeint.
v
Vorwort
wiesen. Statt dessen gehen wir nur so weit ins Detail, wie es nötig ist, um ein kon
kretes und lauffähiges Beispiel nachzuvollziehen. Also wird es auch nicht unser
Wunsch sein, am Ende eine tausendseitige Abtipp-Vorlage für alle Lebenslagen in
den Händen zu halten.Vielmehr möchten wir uns mit dem nötigen Handwerkszeug
versorgen, um Probleme künftig selbstständig anzugehen. Am Ende werden wir in
der Lage sein, Aufgaben am Computer zu lösen, an denen wir bisher vielleicht ge
scheitertsind.
Ich wende mich mit diesem Buch an alle, die bereits erste Erfahrungen in der Pro
grammierung gesammelt haben und wissen, wie einfache Funktionen zu program
mieren sind. Wir werden uns hier einige wichtige Methoden in Form von Pro
grammcode ansehen, ausführlichere Beispiele finden sich im Online-Bereich dieses
Buchs unter http://www.viewegteubner.de/on1inep1USoUm den roten Faden nicht
ausden Augen zu verlieren, werden wirauf viele Fehlerabfragenete.verzichten, die
zwarsinnvollwären, den Codeaber unübersichtlich machen.
Mein Dank gilt meinen Eltern und allen, die mich beim Schreiben dieses Buches un
terstützt haben, insbesondere Roben.
Ich wünsche Ihnen nunvielSpaß beim Lesen und Erfolgbeider Umsetzung!
Markus von Rimscha
Juli2008
VorwortzurzweitenAuflage
Ich habe mich sehr überdas rege Interessean diesem Buch gefreut.
Dank des konstruktiven Feedbacks und wertvoller Anregu ngen konnte ich Tipp
fehlerbeseitigen und habeeinige Passagen und Code-Beispieleergänzt.
Ich wünsche Ihnen weiterhin vielSpaßbeim Lesen und Erfolg beider Umsetzung!
Markus von Rimscha
September 2009
VI
Inhalt
1 Einführung 1
2 Arten von Algorithmen 3
2.1 IterativeAlgorithmen 5
2.1.1 Sortieren 6
2.1.2 wegeimLabyrinth 8
2.1.3 Bewertung 12
2.2 RekursiveAlgorithmen 13
2.2.1 DieTürme von Hanoi 15
"!'
2.2.2 Sortiert.. 19
2.2.3 Schach 21
2.2.4 Fraktaleund Bildkompression 25
2.2.5 Bewertung 34
2.3 Dynamische Algorithmen 37
2.3.1 Fibonacci-Zahlen 37
2.3.2 Bewertung 40
2.4 Heuristische Algorithmen 41
2.4.1 Sortieren 42
2.4.2 Bewertung 46
2.5 Zufallsgesteuerte Algorithmen 47
2.5.1 Metropolis-Algorithmusund Simulated Annealing 47
2.5.2 Bewertung 52
2.6 Genetische Algorithmen 53
2.6.1 Rucksack-Problem 55
2.6.2 Gewinnmaximierung 57
2.6.3 Be :ertung 60
2.7 Probebilistische Algorithmen 61
2.7.1 Multiplikationstest 62
2.7.2 Primzahltest 64
2.7.3 Bewertung 66
VII
Inhalt
3 Effizienzeines Algorithmus 67
3.1 Wachstum 68
3.2 Bewertungeines Algorithmus 72
3.2.1 Average-Case und worst-Case 74
3.2.2 Minimaler Aufwand 75
3.3 Laufzeit und Speicher 77
3.4 Parallele Verarbeitung 78
3.4.1 ParalleleAlgorithmen 78
3.4.2 Parallele Programmierung 80
3.5 Übersicht 90
3.6 Nutzung praktisch unlösbarerProbleme 92
4 Wichtige Datenstrukturen 97
4.1 Listen 98
4.2 Mengen 100
4.2.1 SortierteMengen 100
4.2.2 Unsortierte Mengen 100
4.3 Zuordnungen 102
4.4 Bäume 103
4.5 Graphen 105
5 Künstliche Intelligenz 109
5.1 Maschinelles Lernen 113
5.1.1 Entscheidungsbäume 113
5.1.2 Bewertung 128
5.2 Schwarmintelligenz 129
5.2.1 Ameisenalgorithmen 129
5.2.2 Bewertung 140
5.3 Neuronale Netze 141
5.3.1 Hebb'sche Regel 144
5.3.2 Backpropagation 146
5.3.3 Erweiterungen 149
5.3.4 Bewertung 154
Literaturverzeichnis 155
Stichwortverzeichnis 161
VIII
1 Einführung
Manchmalschreiben wirSoftware, ohne unsgenau zu überlegen, wie wir dabeige
nau vorgehen. Wir arbeiten instinktiv, programmieren die Lösung "einfach herun
ter". Das muss nicht unbedingt schlimm sein, denn es kommt durchaus vor, dass
eine Aufgabe so einfach ist, dass wir mit ein wenig Gespür den richtigen Ansatz
wählen und uns tatsächlich keine tiefgründigen Gedanken über die Problemlösung
zu machen brauchen.
Die Programmierung selbst ist oft schon schwierig genug: Welche Bibliotheken nut
zen wir? Wie sind die Aufrufparameter? Welche Rückgabewerte erhalten wir? Wie
funktioniert die Fehlerbehandlung? Usw. Und all das, nachdem wir uns gerade erst
widerwillig in eine neue Programmiersprache eingearbeitet haben, von der neuen
Entwicklungsumgebung ganz zu schweigen...
Leider istdie Welt aber noch viel komplizierter. Mehr und mehrentdecken wir, dass
längst nicht nur die Frage "Wie programmiere ich das?" von Bedeutung ist. Ratlos
stehen wir manchmal vor dem grundsätzlichen Problem: "Wie löse ich überhaupt
diese Aufgabe?"...Von der Programmierungeinmalganz abgesehen,die unsmit zu
nehmender Erfahrung und Kenntnis der verfügbaren Bibliotheken immer weniger
Problemebereitet.Wirerkennen,dassdieerste Idee nichtimmer derWeisheitletzter
Schluss ist, oder kommen überhaupt nicht mehr ans Ziel. Also werden wir uns im
Folgenden zuerstdie zentraleFragestellen:
Wielöstman Problemeam Computer?
Wir werden uns überlegen, was ein Algorithmus überhaupt ist. Anhand einfacher
Beispiele werden wirunterschiedlichste Arten von Lösungsverfahren kennen lernen
und dabei schnell in der Lage sein, völlig neue Herausforderungen zu bewältigen.
Wir werden sehen, dass selbst Aufgaben im Handumdrehen zu lösen sind, die uns
bisherzurVerzweiflung gebracht haben.
Ist dieser wichtige Schritt einmalgetan, überlegen wir uns, wann ein Verfahren gut
ist und wann nicht. Was ist überhaupt "gut" und was ist beispielsweise "schnell"?
Ist eine Sekunde schnell? Eine Minute? Ein Tag? Wann istein Algorithmus die pas
sende Lösung für unser Problem und wann müssen wir nach Alternativen suchen?
Gibt es überhaupt Alternativen? Geht es besser? Nachdem wir uns mit diesen Fra
gen beschäftigt haben, werden wir die Lösung nicht mehr nur "irgendwie hinbie
gen". Im Ergebnishaben wirzusätzlich dasangenehme Gefühl, unsereSachegutge
machtzu haben.
Mi! diesen Kenntnissen wird es uns dann auch nicht mehr schwer fallen, einige
wichtige Datenstrukturen mit ihren Vor- und Nachteilen kennen zu lernen, zu ver-
1
1 Einführung
gleichen und die jeweils passende Variante für unsere konkrete Anwendung zu
wählen.
Schließlich werden wir es wagen und einen ersten schüchternen Blick auf eine der
Königsdisziplinen der Informatik schlechthin riskieren: Die Künstliche Intelligenz.
Vielleicht hatdieses Thema bisher eine sehr abschreckende Wirkung aufuns ausge
übt. Schließlich muss Künstliche Intelligenz wohl etwas Hochkompliziertes sein.
Aufwändige Mathematik,schwierige Programmierung...
Oderetwa nicht?
Sollte es möglich sein, bereits nach einem ersten Überblick über diesen faszinieren
denThemenkomplexzu konkreten undgreifbaren Resultaten zu kommen?
Zu diesem BuchstehtIhnen ein Online-Berelch zur Verfügung unter
Online
http://www.viewegteubner.de/onlineplus
Hier finden Sie Antworten auf die Fragen an den Kapitelenden sowie einige Code
beispiele in Java 1.6.Hierbei handelt es sich um Implementierungen, dienur die je
weils relevante Idee veranschaulichen sollen.Essind nichtalle möglichenSonderfäl
le und Fehlersituationen beachtet;so bleibtder Code kompakt und einfach, der rote
Faden gehtnicht in Detailfragen verloren.
2
2 Arten von Algorithmen
Wir möchten uns nun mit der Frage beschäftigen, wie man Probleme löst. Dazu
überlegen wir unszunächst, was ein Algorithmusüberhaupt isIIAAl-3].
Einfach gesagt handelt es sich dabei um eine Arbeitsanweisung. die uns zeigt, wie
eine Aufgabe zu lösen ist- vorzugsweise am Computer. Für die jeweiligen Anwen
dungsgebiete gibtes ein breites Spektrum an solchen Verfahren.In unserem alltägli
chen Leben kommtein Kochrezeptdem wohl am nächsten. Eine solche Handlungs
anweisung sollteeinige Eigenschaften erfüllen:
1. Ein Algorithmus istallgemeingültig.
Wir möchten unser Lösungsverfahren späterauf verschiedene Probleme an
setzen, Im Moment wissen wir noch überhaupt nicht, wie diese genau aus
sehen werden. Das Einzige, was wir jetzt schon sagen können, ist, dass es
sich um gleichartige Aufgabenstellungen handeln wird.
Deswegen muss ein Algorithmus eine allgemein gültige Handlungsanwei
sung sein, die nicht nur zu einem bestimmten Problem, sondern zu allen
gleichartigen Aufgaben passt.
Es geht also beispielsweise nicht um die Frage "Wie sortiertman 3Zahlen?"
sondern ganz allgemein "Wie sortiert man Zahlen?". Der Algorithmus soll
funktionieren, egal ob wir später 3,7oder 23847657 zahlen sortieren möch
ten.
2. Ein Algorithmus istausführbar.
Grundsätzlich muss es möglich sein, den Algorithmus abzuarbeiten. Dazu
müssenendlich viele Anweisungen eindeutig,verständlich und in einer kla
ren Reihenfolge gegeben sein.
Für uns Menschen mag eine informelle sprachliche Beschreibung genügen,
für den Computer werden wir uns aber die Mühe machen müssen, unser
Verfahren in einerProgrammiersprache zu formulieren.
Eine Anweisung wie "Gehe nach links oder nach rechts" ist beispielsweise
nicht ausführbar,denn es istnicht klar, was tatsächlich zu tun ist. Wir benö
tigen eindeutige Vorgaben, also z.B. "Wenn der Eingabewert ungerade ist,
danngehenach links, ansonstennach rechts".
3. Natürlich mussein Algorithmuszu einem Ende kommen.
Diese Forderung klingt vielleicht banal, hat aber ihre Tücken. Praktisch ge
sehen istein Lösungsverfahren natürlich wertlos,wenn esnicht irgendwann
mit seinerBerechnung fertigwird.
Trotzdem werden wir recht bald Verfahren sehen, die ihrem Wesen nach
unendlich lange laufen.Wir werden uns also immerGedanken darüber ma-
3