vorlesung informatik 1 - hs-esslingen.derau/vorlesungen/informatik1/folien/informatik1... ·...

21
Andreas Rau, 07.12.06 D:\home\ar\fhte\vorlesungen\informatik1\folien\informatik1-theorie-algorithmen.odp Vorlesung Informatik 1 Fachhochschule für Technik Esslingen Studiengang Wirtschaftsinformatik Algorithmen Dr. rer. nat. Andreas Rau http://www.hs-esslingen.de/~rau [email protected]

Upload: lekhue

Post on 09-Aug-2019

223 views

Category:

Documents


0 download

TRANSCRIPT

Andreas Rau, 07.12.06 D:\home\ar\fhte\vorlesungen\informatik1\folien\informatik1-theorie-algorithmen.odp

Vorlesung Informatik 1Fachhochschule für Technik Esslingen

Studiengang Wirtschaftsinformatik

AlgorithmenDr. rer. nat. Andreas Rau

http://www.hs-esslingen.de/[email protected]

Andreas Rau, 07.12.06 D:\home\ar\fhte\vorlesungen\informatik1\folien\informatik1-theorie-algorithmen.odp

In diesem Foliensatz sollen verschiedene Algorithmen genauer untersucht werden. Dabei soll für jeden Algorithmus Problem, Lösungsidee und technische Umsetzung betrachtet werden um so Einblicke zur Entwicklung eigener Lösung zu gewinnen.

Klassische Probleme der Informatik sind u.a.

● Sortieren● Suchen

Weitere Übungen anhand des „interaktiven Labors“...

Inhalt

Andreas Rau, 07.12.06 D:\home\ar\fhte\vorlesungen\informatik1\folien\informatik1-theorie-algorithmen.odp

Sortieralgorithmen

Andreas Rau, 07.12.06 D:\home\ar\fhte\vorlesungen\informatik1\folien\informatik1-theorie-algorithmen.odp

ProblemstellungSowohl Menschen als auch Maschine (vgl. Abschnitt über Suchen) tun sich mit sortierten Daten leichter. Man denke nur an ein unsortiertes Telefonbuch... Daher ist die Aufgabe, eine gegebene Datenmenge zu sortieren ein klassisches Problem der Datenverarbeitung.

Naturgemäß gibt es mehr als eine Lösung für dieses Problem. Jedoch sind nicht alle Lösungen gleich gut. Zur Bewertung kann man z.B. folgende Eigenschaften heranziehen:

ZeitverhaltenWie schnell steigt die Rechenzeit in Abhängigkeit der Datenmenge an?Schlechte Algorithmen brauchen für doppelt soviele Daten viermal solange...

PlatzbedarfWie schnell steigt der Speicherplatz in Abhängigkeit der Datenmenge an?Üblicherweise wird gefordert, daß ohne zusätzlichen Speicherplatz sortiert wird!

StabilitätDamit ist gemeint, ob gleiche Elemente umsortiert werden oder nicht.Dies ist z.B. relevant, wenn man hintereinander nach verschiedenen Kriterien sortiert.

Sortieren(1)

Andreas Rau, 07.12.06 D:\home\ar\fhte\vorlesungen\informatik1\folien\informatik1-theorie-algorithmen.odp

AnwendungsfälleSortierverfahren können in folgenden Anwendungsfällen eingesetzt werden:

● Komplettes Sortieren einer ungeordneten Datenmenge● Umsortieren einer umgekehrt sortierten Datenmenge● Einsortieren eines neuen Datensatzes in eine bereits sortierte Menge

Der zweite Fall ist im Grunde ein pathologischer Sonderfall des ersten Falls bei dem manche Sortierverfahren besonders schlecht funktionieren (wenn man den Fall erkennen würde, wäre es natürlich einfach).

GrundoperationenWie wir sehen werden werden zur Sortierung die folgenden Grundoperationen benötigt:

● Zugreifen / Vergleichen● Vertauschen● Einfügen

Diese funktionieren mit unterschiedlichen Datenstrukturen unterschiedlich gut...

Sortieren(2)

Andreas Rau, 07.12.06 D:\home\ar\fhte\vorlesungen\informatik1\folien\informatik1-theorie-algorithmen.odp

Sortieren(3)VorüberlegungenÜberlegen Sie kurz wie sie in folgenden Fällen selbst beim sortieren vorgehen (würden)

● Sortieren von Karten beim Kartenspiel● Sortieren von Büchern / Filmen / CDs in einem Regal● Sortieren eines Briefen (Stapel) nach Eingangsdatum● Sortieren von ...

Praktische ÜbungFühren sie nun folgende praktische Übung durch:

● Eine DIN A4 Seite längs falten und reißen● Die Teile noch 2x falten und reißen um schließlich 8 Teile zu erhalten● Die 8 Teile mit „Zufallszahlen“ beschriften und mischen● Die oben überlegten Lösungsverfahren praktisch ausprobieren

Andreas Rau, 07.12.06 D:\home\ar\fhte\vorlesungen\informatik1\folien\informatik1-theorie-algorithmen.odp

Sortieren(4)VorbereitungFür die Evaluierung der verschiedenen Sortierverfahren werden wir Arrays mit Zufallszahlen verwenden. Zur Generierung soll die Klasse „Generator“ dienen.

public class Generator { public static void printNumbers( int[] numbers) { boolean delim = false; for ( int i : numbers) { if ( delim) System.out.print( ", "); System.out.printf( "%3d", i); delim = true; } System.out.println(); } public static int[] generateRandomNumbers( int n, int min, int max) { int[] numbers = new int[n]; for ( int i=0; i<n; ++i) { numbers[i] = (int)(Math.random()*(max-min+1) + min); } return numbers; } // ...see next page

Andreas Rau, 07.12.06 D:\home\ar\fhte\vorlesungen\informatik1\folien\informatik1-theorie-algorithmen.odp

Sortieren(5) // ...continued from previous page public static int[] generateAscendingNumbers(int n, int min, int max, int jitter) { int[] numbers = new int[n]; for ( int i=0; i<n; ++i) { min = min + (int)(Math.random()*jitter + 1); numbers[i] = Math.min( min, max); } return numbers; } public static int[] generateDescendingNumbers(int n, int min,int max, int jitter) { int[] numbers = new int[n]; for ( int i=0; i<n; ++i) { max = max - (int)(Math.random()*jitter + 1); numbers[i] = Math.max( min, max); } return numbers; } public static void main( String[] args) { printNumbers( generateRandomNumbers( 10, 1, 100)); printNumbers( generateAscendingNumbers( 10, 1, 100, 20)); printNumbers( generateDescendingNumbers( 10, 1, 100, 20)); }}

Andreas Rau, 07.12.06 D:\home\ar\fhte\vorlesungen\informatik1\folien\informatik1-theorie-algorithmen.odp

Sortieren(6)RahmenprogrammDer Rahmen zur Implementierung der Sortieralgorithmen sieht dann wie folgt aus:

public class SortBy<Verfahren> { public static int[] sort( int[] numbers) { // Implementierung des Algorithmus return numbers; } public static void main( String[] args) { System.out.println( "SortBy<Verfahren>\n"); int[] numbers = Generator.generateRandomNumbers( 10, 1, 100);// int[] numbers = Generator.generateAscendingNumbers( 10, 1, 100, 20);// int[] numbers = Generator.generateDescendingNumbers( 10, 1, 100, 20); Generator.printNumbers( numbers); System.out.println(); long t1 = System.currentTimeMillis(); sort( numbers); long t2 = System.currentTimeMillis(); System.out.println(); Generator.printNumbers( numbers); System.out.println( "\nDone in " + (t2-t1) + "ms"); } }

Andreas Rau, 07.12.06 D:\home\ar\fhte\vorlesungen\informatik1\folien\informatik1-theorie-algorithmen.odp

Sortieren(7)Sortieren durch direktes EinfügenIdee: Sortieren wie beim KartenspielenWir vergleichen jedes Element mit allen Vorgängern und fügen es am richtigen Platz ein. Dadurch wird der Anfang der Wertemenge vorsortiert und Stück für Stück ergänzt.

public static int[] sort( int[] numbers) { for ( int i=1; i<numbers.length; ++i) { int x = numbers[i]; aktuelles Element „nehmen“ int j = i-1; while ( j>=0) { // alle Vorgänger betrachten if ( numbers[j]<=x) break; // wenn Vorgänger nicht größer abbrechen (=stabil) numbers[j+1] = numbers[j]; // sonst nachrücken und weiter j--; } numbers[j+1] = x; // aktuelles Element „einfügen“ Generator.printNumbers( numbers); // Zwischenergebnis ausgeben } return numbers; }

Machen sie sich die Arbeitsweise des Algorithmus anhand der Ausgabe der Zwischenschritte klar. Spielen Sie anschließend verschiedene Szenarien durch.

ACHTUNG: Aussagekräftige Zeitmessungen nur bei auskommentierten Ausgaben.

Andreas Rau, 07.12.06 D:\home\ar\fhte\vorlesungen\informatik1\folien\informatik1-theorie-algorithmen.odp

Sortieren(8)Sortieren durch direktes AuswählenIdee: Systematische SucheWir suchen nacheinander das kleinste, zweitkleinste, ... Element und fügen es am richtigen Platz ein. Dadurch wird die Wertemenge Stück für Stück final sortiert.

public static int[] sort( int[] numbers) { for ( int i=0; i<numbers.length-1; ++i) { int x = i; // aktuelles Element auswählen for ( int j=i+1; j<numbers.length; ++j) { if ( numbers[j]<numbers[x]) x = j; // anderes Element auswählen } // Gefundenes Element durch Austausch an richtige Position bringen int t = numbers[i]; numbers[i] = numbers[x]; numbers[x] = t; Generator.printNumbers( numbers); // Zwischenergebnis ausgeben } return numbers; }

Machen sie sich die Arbeitsweise des Algorithmus anhand der Ausgabe der Zwischenschritte klar. Spielen Sie anschließend verschiedene Szenarien durch.

ACHTUNG: Aussagekräftige Zeitmessungen nur bei auskommentierten Ausgaben.

Andreas Rau, 07.12.06 D:\home\ar\fhte\vorlesungen\informatik1\folien\informatik1-theorie-algorithmen.odp

Sortieren(9)Sortieren durch Wandern (aka Bubblesort)Idee: Bei der Suche bereits kleinere Umstellungen vornehmenWir suchen nacheinander das größte, zweitgrößte, ... Element indem wir vom gegenüberliegenden Ende aus Schritt für Schritt vergleichen und uns „hochtauschen“.

public static int[] sort( int[] numbers) { for ( int i=numbers.length-1; i>0; --i) { for ( int j=0; j<i; ++j) { if ( numbers[j]>numbers[j+1]) { // Gefundenes Element durch Austausch wandern lassen int t = numbers[j]; numbers[j] = numbers[j+1]; numbers[j+1] = t; } } Generator.printNumbers( numbers); // Zwischenergebnis ausgeben } return numbers; }

Machen sie sich die Arbeitsweise des Algorithmus anhand der Ausgabe der Zwischenschritte klar. Spielen Sie anschließend verschiedene Szenarien durch.

ACHTUNG: Aussagekräftige Zeitmessungen nur bei auskommentierten Ausgaben.

Andreas Rau, 07.12.06 D:\home\ar\fhte\vorlesungen\informatik1\folien\informatik1-theorie-algorithmen.odp

Sortieren(10)Sortieren durch „geniale Idee“ (aka Quicksort)Idee: Tauschen über große Distanz mit rekursivem „teilen und herrschen“ public static int[] sort( int[] numbers, int l, int r) { int x = numbers[(l+r)/2]; // "willkürliches" Vergleichselement wählen int i = l, j = r; while (i<=j) { while ( numbers[i]<x) i++; // linken Tauschpartner suchen while ( numbers[j]>x) j--; // rechten Tauschpartner suchen if (i<=j) { // Tausch durchführen int t = numbers[i]; numbers[i] = numbers[j]; numbers[j] = t; i++; j--; } } // jetzt liegt Partitionierung in Teile<=k und Teile>=k vor System.out.printf( "%2d-%2d(%2d):", l, r, x); Generator.printNumbers( numbers); if (l<j) sort( numbers, l, j); // Teilintervall sortieren wenn nicht leer if (i<r) sort( numbers, i, r); // Teilintervall sortieren wenn nicht leer return numbers; } public static int[] sort( int[] numbers) { return sort( numbers, 0, numbers.length-1); // Einstieg in Rekursion }

Andreas Rau, 07.12.06 D:\home\ar\fhte\vorlesungen\informatik1\folien\informatik1-theorie-algorithmen.odp

Sortieren(11)Quicksort ist natürlich „starker Tobak“ und erschließt sich (wenn dann) nur nach mehrmaligem Durchdenken und/oder manuellem Nachvollziehen.

Festzuhalten ist jedoch, daß Quicksort zwar (im Mittel) der schnellste Algorithmus für zufällig sortierte Werte (daher der Name) jedoch beileibe nicht das Maß aller Dinge ist. So hat Quicksort die unangenehme Eigenschaft, in bestimmten Fällen besonders viel Zeit oder besonders viel Speicher zu benötigen (Details siehe Literatur).

Dabei spielt u.a. die Wahl des Vergleichselements eine besondere Rolle. Für das Sortieren kleiner Datenmengen ist Quicksort kaum schneller (und weniger „berechenbar“ als einfache Sortiermethoden).

Für den Anwendungsfall „Einfügen eines einzelnen Elements“ sind einfache Sortierverfahren bzw. geeignete Suchverfahren ohnehin die bessere Wahl.

Andreas Rau, 07.12.06 D:\home\ar\fhte\vorlesungen\informatik1\folien\informatik1-theorie-algorithmen.odp

Suchalgorithmen

Andreas Rau, 07.12.06 D:\home\ar\fhte\vorlesungen\informatik1\folien\informatik1-theorie-algorithmen.odp

Suchen(1)ProblemstellungNeben dem Sortieren ist Suchen die zweite klassische Aufgabe bei der elektronischen Datenverarbeitung. Die Sortierung ist sozusagen nur eine Vorstufe davon, da man in sortierten Daten schneller suchen kann. Bei der Bewertung von Suchalgorithmen zählt vor allem das

ZeitverhaltenWie schnell steigt die Rechenzeit in Abhängigkeit der Datenmenge an?

Dagegen spielt der Platzbedarf i.d.R. keine Rolle da ja direkt in den Daten gesucht wird.Wie hoch ist wohl der maximale Zeitbedarf im worst-case?

GrundoperationenBeim Suchen gibt es im wesentlichen eine Grundoperation

● Vergleichen

dies klingt zwar zunächst trivial, kann aber bei komplexen Objekten auch teuer sein!

Andreas Rau, 07.12.06 D:\home\ar\fhte\vorlesungen\informatik1\folien\informatik1-theorie-algorithmen.odp

Suchen(2)AnwendungsfälleVon dem eigentlichen Grundproblem „finde einen gesuchten Wert in einer vorgegebenen Menge“ gibt es kleine Variationen:● prüfe, ob der gesuchte Wert enthalten ist● zähle, wie oft der gesuchte Wert enthalten ist● finde das erste Vorkommen des Werts (und liefere die Position zurück)● finde das nächste Vorkommen des Werts● finde das letzte Vorkommen des Werts● finde alle Vorkommen des Werts

Einige dieser Fragen lassen implizit die Beantwortung anderer Fragen zu. Welche?

VorüberlegungenWie würden Sie in der realen Welt folgende Suchprobleme lösen● Suchen einer CD im Regal● Suchen eines Motivs in einer Diasammlung● Suchen einer Telefonnummer im Telefonbuch

Offensichtlich ist eine gewisse Ordnung / Sortierung hilfreich bei der Suche!

Andreas Rau, 07.12.06 D:\home\ar\fhte\vorlesungen\informatik1\folien\informatik1-theorie-algorithmen.odp

Suchen(3)RahmenprogrammZur Untersuchung der Suchalgorithmen können wir wiederum Zufallszahlen verwenden. Der Rahmen zur Implementierung der Suchalgorithmen sieht dann wie folgt aus:

public class SearchBy<Verfahren> { public static int search( int[] numbers, int number) { // Implementierung des Algorithmus return index; } public static void main( String[] args) { System.out.println( "SearchBy<Verfahren>\n"); int[] numbers = Generator.generateRandomNumbers( 10, 1, 100); int number = numbers[ (int)(Math.random()*10)]; // zufällige Zahl wählen long t1 = System.currentTimeMillis(); int index = search( numbers, number); // versuchen die Zahl wieder zu finden long t2 = System.currentTimeMillis(); Generator.printNumbers( numbers); if ( -1 != index) { System.out.printf( "%" + (5*index+3) + "s=%d(%d)", "^^^", number, index); } System.out.println( "\nDone in " + (t2-t1) + "ms"); } }

Andreas Rau, 07.12.06 D:\home\ar\fhte\vorlesungen\informatik1\folien\informatik1-theorie-algorithmen.odp

Suchen(4)Lineare SucheIdee: Jedes Element betrachten bis das gesuchte Element gefunden ist.Voraussetzung: Man weiss nichts über die Elemente und deren Ordnung

public static int search( int[] numbers, int number) { for ( int i = 0; i<numbers.length; ++i) { if ( numbers[i]==number) { return i; } } return -1; }

Bei der linearen Suche braucht man im worst-case n, im Mittel n/2 Vergleiche. Da man nichts über die durchsuchten Daten weiß, bleibt einem auch gar nichts anders übrig!

Andreas Rau, 07.12.06 D:\home\ar\fhte\vorlesungen\informatik1\folien\informatik1-theorie-algorithmen.odp

Suchen(5)Binäre SucheIdee: Das gesuchte Element gezielt „einkreisen“ (teilen und herrschen, vgl. Zahlenraten)Voraussetzung: Die Elemente sind in bekannter Weise geordnet.

public static int search( int[] numbers, int number) { int lo = 0, hi = numbers.length-1; do { int index = (hi+lo)/2; if ( numbers[index]<number) { lo = index+1; continue; } if ( numbers[index]>number) { hi = index-1; continue; } return index; } while ( lo<=hi); return -1; }

Man schließt also mit Hilfe der Sortierung bei jedem Schritt möglichst viele Elemente aus. Ordnung hat also große Vorteile! Sie muss aber vorhanden sein, sonst klappt's nicht!

Andreas Rau, 07.12.06 D:\home\ar\fhte\vorlesungen\informatik1\folien\informatik1-theorie-algorithmen.odp

ReferenzenLiteraturhinweise:

[1] Niklaus Wirth, Algorithmen und Datenstrukturen, Teubner Verlag

[2] Robert Sedgewick, Algorithms in <your favorite language>, Addison Wesley

Links:

[1] http://de.wikipedia.org/wiki/Sortierverfahren Analytischer Vergleich verschiedener Verfahren mit Links zu Detailbeschreibungen

[2] http://www.ldv.ei.tum.de/media/files/lehre/gi/praktikum/interaktiv/sort/sort.html Interaktive Animation von Sortieralgorithmen

[3] http://ivs.cs.uni-magdeburg.de/~dumke/EAD/Skript10.html Pseudocode Darstellung von Such- und Sortieralgorithmen

[4] http://www-igm.univ-mlv.fr/~lecroq/string/ Algorithmen zum Stringvergleich (~Suche von Teilfolgen)