15.01.2014 Aufrufe

Beuth Hochschule Stichworte Algorithmen WS13/14, S. 1 Stichworte ...

Beuth Hochschule Stichworte Algorithmen WS13/14, S. 1 Stichworte ...

Beuth Hochschule Stichworte Algorithmen WS13/14, S. 1 Stichworte ...

MEHR ANZEIGEN
WENIGER ANZEIGEN

Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.

YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.

<strong>Beuth</strong> <strong>Hochschule</strong> <strong>Stichworte</strong> <strong>Algorithmen</strong> <strong>WS13</strong>/<strong>14</strong>, S. 1<br />

<strong>Stichworte</strong> zu <strong>Algorithmen</strong><br />

<strong>Stichworte</strong> und allgemeine Informationen zur Lehrveranstaltung<br />

<strong>Algorithmen</strong> (MB2-ALG) für den Zug 2<br />

im Studiengang Medieninformatik Bachelor (MD-B)<br />

im Wintersemester 2013/<strong>14</strong> bei Ulrich Grude.<br />

Anmerkung: Die parallele Veranstaltung für den Zug 1 wird von Prof. Schiele betreut.<br />

In dieser Datei finden Sie u.a. die Termine und Orte der einzelnen seminaristischen Unterrichte (SUs)<br />

und Übungen (Üs), die Regeln, nach denen man für diese LV Noten bekommt und weitere Informationen.<br />

Im Laufe des Semesters können Sie in dieser Datei nach jedem SU ("nach jeder Vorlesung") ein<br />

paar <strong>Stichworte</strong> zum Inhalt des Unterrichts (und manchmal auch Korrekturen und Ergänzungen etc.) finden.<br />

Einleitung<br />

1. Diese Lehrveranstaltung (LV) stellt ziemlich hohe Ansprüche an ihre TeilnehmerInnen. Das liegt unter<br />

anderem daran, dass sie (die LV, seit dem SS13) schon im 2. Semester stattfindet und Sie (die TeilnehmerInnen<br />

der LV) vorher nur ein Semester Programmierung hatten.<br />

2. Kommen Sie zu allen Vorlesungen und Übungen. Betrachten Sie das Verpassen einer Vorlesung oder<br />

einer Übung nicht als eine Option, sondern als eine kleine Katastrophe, die aufwendiges Nachholen erforderlich<br />

macht.<br />

3. Wenn Sie das Gefühl bekommen sollten, in den Vorlesungen oder Übungen nicht genug zu lernen,<br />

dann geben Sie nicht gleich auf. Überlegen Sie, was Sie anders machen könnten, um mehr zu lernen, und<br />

was ich (als Betreuer dieser LV) anders machen sollte. Über Verbesserungsvorschläge können wir immer<br />

reden (vorzugsweise vor oder nach dem Unterricht).<br />

Einige Unterlagen zu dieser LV finden Sie (ziemlich weit oben) auf meiner Netzseite<br />

http://public.beuth-hochschule.de/~grude/<br />

Außerdem brauchen Sie Zugriff auf das Buch "Java ist eine Sprache" von Ulrich Grude. Sie können es<br />

kostenlos in der Bibliothek der <strong>Beuth</strong> <strong>Hochschule</strong> ausleihen (oder für viel Geld in einem Buchladen kaufen).<br />

Einige Abschnitte in diesem Buch sind für diese LV <strong>Algorithmen</strong> wichtig.


S. 2, <strong>WS13</strong>/<strong>14</strong> <strong>Stichworte</strong> zu <strong>Algorithmen</strong> <strong>Beuth</strong>-<strong>Hochschule</strong><br />

Termine und Orte<br />

Erster Termin: Dienstag 08.10.2013, 8.00 Uhr, Raum D209<br />

Für den Zug 2 sind zwei Übungsgruppen geplant: 2a und 2b. Es folgen hier die Termine und Orte aller<br />

seminaristischen Unterrichte (SU) und aller Übungen (Ü):<br />

KW<br />

Datum<br />

(immer<br />

dienstags)<br />

08.00-09.30<br />

SU im Raum<br />

D209<br />

10.00-11.30<br />

Ü im Raum<br />

D113L<br />

12.15-13.45<br />

SU im<br />

Raum B013<br />

41 08.10.13 SU01 Ü2a01 SU02<br />

42 15.10.13 SU03 Ü2b01 SU04 Test 1 (08.00 Uhr)<br />

43 22.10.13 SU05 Ü2a02 SU06<br />

44 29.10.13 SU07 Ü2b02 SU08 Test 2 (08.00 Uhr)<br />

45 05.11.13 SU09 Ü2a03 SU10<br />

46 12.11.13 SU11 Ü2b03 SU12 Test 3 (08.00 Uhr)<br />

47 19.11.13 SU13 Ü2a04 SU<strong>14</strong><br />

48 26.11.13 SU15 Ü2b04 SU16 Test 4 (08.00 Uhr)<br />

49 03.12.13 SU17 Ü2a05 SU18<br />

50 10.12.13 Ü2b05 SU19 Test 5 (12.15 Uhr)<br />

51 17.12.13 Ü2a06 SU20<br />

Feiertage<br />

02 07.01.<strong>14</strong> Ü2b06 SU21 Test 6 (12.15 Uhr)<br />

93 <strong>14</strong>.01.<strong>14</strong> Ü2a07 SU22<br />

04 21.01.<strong>14</strong> Ü2b07 SU23 Test 7 (12.15 Uhr)<br />

05 28.01.<strong>14</strong> Ü2a08 SU24<br />

06 04.02.<strong>14</strong> Ü2b08 SU25 Klausur<br />

07 11.02.<strong>14</strong> SU26 Rückgabe der Klausur<br />

Die Hauptklausur findet statt:<br />

am Di 04.02.20<strong>14</strong>, 18-19.30 Uhr, Raum D209 (geändert am 16.12.2013)<br />

Rückgabe: 11.02.20<strong>14</strong>, 12.15 Uhr, Raum D321<br />

Die Nachklausur findet statt<br />

am Fr 28.03.20<strong>14</strong>, 10.00-11.30 Uhr, Raum ??<br />

Rückgabe: Mo 31.03.20<strong>14</strong>, 10.00 Uhr, Raum DE17


<strong>Beuth</strong> <strong>Hochschule</strong> <strong>Stichworte</strong> <strong>Algorithmen</strong> <strong>WS13</strong>/<strong>14</strong>, S. 3<br />

Wie bekommt man eine Note für den Übungsteil dieser LV?<br />

In den geraden Kalenderwochen werden wir insgesamt 7 kleine Tests schreiben, Bearbeitungszeit jeweils<br />

etwa 10 bis 15 Minuten. Die Aufgaben und Fragen in diesen Tests werden sich auf den Stoff beziehen,<br />

der (im SU und in den Ü) vorher behandelt wurde. In jedem Test kann man maximal 20 Punkte erreichen.<br />

Mit 10 oder mehr Punkten hat man den Test bestanden, mit weniger Punkten hat man den Test<br />

nicht bestanden. Wenn Sie 5 oder mehr der 7 Tests bestehen, bekommen Sie für den Übungsteil die Note<br />

m.E. (mit Erfolg), sonst die Note o.E. (ohne Erfolg).<br />

Empfehlung: Schreiben Sie alle Tests mit, bei denen Ihnen das irgendwie möglich ist. Sparen Sie sich<br />

die Möglichkeit, zwei Tests nicht zu bestehen (z.B. weil Sie nicht daran teilgenommen haben) bis zum<br />

Ende des Semesters auf. Wenn Sie an einem Test nicht teilnehmen, spielt es keine Rolle, warum Sie<br />

nicht teilgenommen haben (S-Bahn war eingefroren, Fahrrad hatte einen Platten, war krank, musste<br />

einen hohen Lotto-Gewinn persönlich abholen etc.).<br />

Außerdem wird aus Ihren 5 besten Testergebnissen (das ist eine Punktezahl zwischen 0 und 100) nach<br />

der folgenden Tabelle eine differenzierte Übungsnote zwischen 1,0 und 5,0 berechnet:<br />

Punkte (ab): 95 90 85 80 75 70 65 60 55 50 0-49<br />

Note: 1,0 1,3 1,7 2,0 2,3 2,7 3,0 3,3 3,7 4,0 5,0<br />

Diese differenzierte Übungsnote kann ihre Modulnote verbessern oder verschlechtern.<br />

Wie bekommt man eine Modulnote für diese LV?<br />

Um eine (differenzierte) Modulnote zu bekommen, muss man an einer Klausur teilnehmen (an der<br />

Hauptklausur am Ende des <strong>WS13</strong>/<strong>14</strong> oder an der Nachklausur kurz vor dem SS<strong>14</strong>). An den Klausuren<br />

dürfen alle teilnehmen, die die Lehrveranstaltung MB2-ALG, Zug 2, belegt haben. In den Klausuren sind<br />

jeweils 100 Punkte erreichbar. Nach der Tabelle im vorigen Abschnitt wird daraus die Klausurnote ermittelt.<br />

Die Modulnote wird aus der der Klausurnote (Gewicht: 75%) und aus der differenzierten Übungsnote<br />

(Gewicht: 25%) berechnet. Die folgenden Beispiele sollen zeigen, wie dabei gerundet wird:<br />

Übungsnote Klausurnote Rohergebnis (gerundete) Note<br />

2,3 2,7 (2,3 + 3 * 2,7) / 4 = 2,60 2,7<br />

3,7 1,3 (3,7 + 3 * 1,3) / 4 = 1,90 2,0<br />

2,0 4,0 (2,0 + 3 * 4,0) / 4 = 3,50 3,3<br />

Unterlagen für Tests und Klausuren<br />

Zu jedem der Tests dürfen Sie als Unterlage mitbringen:<br />

1 Blatt, max. DIN A 4, beliebig beschriftet (von Hand oder mit Drucker/Kopierer, nur auf der Rückseite<br />

oder nur auf der Vorderseite oder beidseitig, schwarz-weiß oder farbig, ordentlich oder chaotisch, ...).<br />

Zur Klausur (und zur Nachklausur) dürfen Sie als Unterlagen mitbringen:<br />

5 Blätter, max. DIN A 4, beliebig beschriftet (siehe oben).<br />

Hinweis: 10 einseitig beschriebene Blätter sind 10 Blätter und nicht 5 Blätter!<br />

Übungsgruppen<br />

Wer zu welcher Übungsgruppe (2a bzw. 2b) gehört, wird nicht durch das Online Belegsystem festgelegt,<br />

sondern am Di 08.10.13 kurz nach 8.00 Uhr im ersten seminaristischen Unterricht. Wenn es für eine<br />

Übungsgruppe mehr InteressentInnen gibt als Plätze, entscheidet das Los. Nur persönlich Anwesende<br />

können an den Verlosungen teilnehmen.


S. 4, <strong>WS13</strong>/<strong>14</strong> SU 1. Di 08.10.13, Block 1 <strong>Beuth</strong>-<strong>Hochschule</strong><br />

SU 1. Di 08.10.13, Block 1<br />

1. Begrüßung<br />

2. Namensschilder verteilen, schreiben, aufstellen.<br />

Namensschilder bitte immer mitbringen und möglichst selbständig aufstellen.<br />

3. Wie bekommt man zwei Noten für das Fach <strong>Algorithmen</strong>?<br />

Ü-Note: 7 Tests, wenn man mindestens 5 besteht: m.E., sonst o.E.<br />

Außerdem wird aus den Testergebnissen eine differenzierte Ü-Note (1.0 - 5.0) errechnet<br />

Modul-Note: Klausur-Note (75%) und differenzierte Ü-Note (25%)<br />

Übungen: Zwei Gruppen: 2a (in ungeraden KWs) und 2b (in geraden KWs)<br />

Die Plätze werden (nicht vom OnlineBelegsystem festgelegt, sondern) jetzt und hier verteilt bzw. (falls<br />

es mehr InteresstInnen als Plätze gibt) verlost.<br />

Arbeitsgruppen: Bestehen aus 2 Personen, bearbeiten gemeinsam Projekte (siehe die Datei<br />

Projekte.pdf auf meiner Netzseite). Jede Gruppe braucht nur eine Lösung erstellen und vorzeigen.<br />

Frage: Wer hat einen Laptop? Kann jede Arbeitsgruppe einen Laptop in jeden SU mitbringen?<br />

Lehrkraftnews abonnieren!<br />

Hat jemand noch Fragen zur Organisation dieser Lehrveranstaltung?<br />

Einleitende Anmerkungen zu dieser LV<br />

Die drei Punkte aus der Einleitung auf S. 1:<br />

1. Hohe Anforderungen<br />

2. Kommen Sie zu allen SUs und zu allen Üs<br />

3. Bei Problemen: Lassen Sie uns reden und versuchen, die Probleme zu verkleinern.<br />

Außerdem:<br />

4. Verhalten Sie sich so wie jemand, der den Stoff dieser LV interessant und wichtig findet.<br />

5. Eignen Sie sich den Stoff aktiv an (und warten Sie nicht darauf, "von außen betankt zu werden").<br />

6. Kommen Sie vorbereitet in die Übungen. Lesen Sie die Datei Projekte.pdf zu Hause durch (ungefähr<br />

ein Projekt alle 2 Wochen) und erstellen Sie dabei eine Liste mit Ihren Fragen. In der Übung sollte<br />

es dann vor allem um die Beantwortung ihrer Fragen gehen (nicht um das Lesen der Aufgaben).<br />

Jetzt geht es los mit dem Stoff!<br />

Ziele dieser Lehrveranstaltung<br />

Die Begriffe Programm und Algorithmus sollen behandelt werden. Was haben die miteinander zu tun?<br />

Was unterscheidet sie voneinander?<br />

Was versteht man unter der Zeitkomplexität eines Algorithmus? Die Tilde-Notation und die Groß-O-<br />

Notation.<br />

Einige wichtige Datenstrukturen (Reihungen, Listen, Bäume, Hashtabellen) und ihre <strong>Algorithmen</strong> sollen<br />

genauer behandelt werden.<br />

Eine paar weitere <strong>Algorithmen</strong> sollen behandelt werden.<br />

Was hat es mit den <strong>Algorithmen</strong>-Gruppen P und NP auf sich? Welche <strong>Algorithmen</strong> gehören zur Gruppe<br />

P? Und welche zu NP? Welche <strong>Algorithmen</strong> sind NP-vollständig? Sind die beiden Gruppen wirklich<br />

verschieden?


<strong>Beuth</strong> <strong>Hochschule</strong> <strong>Stichworte</strong> <strong>Algorithmen</strong> <strong>WS13</strong>/<strong>14</strong>, S. 5<br />

Kurze Wiederholung von PR1 (vielleicht ein bisschen anders als Sie es kennen)<br />

Programmieren als ein Rollenspiel, mit 3 Hauptrollen:<br />

Der Programmierer schreibt Programme und übergibt sie dem Ausführer.<br />

Der Ausführer prüft Programme, lehnt sie ab oder akzeptiert sie, führt sie aus.<br />

Der Benutzer befiehlt dem Ausführer, Programme auszuführen und ist für Ein- und Ausgabedaten zuständig.<br />

2 Nebenrollen:<br />

Der Warter wartet die Programme, die der Programmierer geschrieben hat.<br />

Der Wiederverwender verwendet Teile der Programme, um selbst neue Programme daraus machen.<br />

Das wichtigste Grundkonzept der Programmierung<br />

Variablen, deren Wert man beliebig oft verändern kann (anders als Variablen in der Mathematik, deren<br />

Wert man beliebig wählen, aber dann nicht mehr verändern darf).<br />

Kleine Begriffshierarchie:<br />

Ein Wertebehälter ist eine Variable oder ein Ein/Ausgabe-Gerät (Tastatur, Bildschirm, Datei-auf-<br />

Festplatte, Datei-auf-CD, ...)<br />

In Programmiersprachen gibt es 3 Arten von Befehlen:<br />

Bezeichnung deutsch<br />

Vereinbarung<br />

Ausdruck<br />

Anweisung<br />

Bezeichnung englisch Was befiehlt so ein Befehl dem Ausführer?<br />

declaration<br />

expression<br />

statement<br />

Erzeuge ....<br />

(z.B. eine Variable, eine Methode, eine Klasse, ...)<br />

Berechne den Wert des Ausdrucks ...<br />

(z.B. x + 2 oder sin(2*y) - PI etc.)<br />

Tue die Werte ... in die Wertebehälter ...<br />

(z.B. y = x +2; oder print("Hallo!") etc.)<br />

Ein Ausdruck bewirkt (normalerweise) nicht, dass die Inhalte von Wertebehältern verändert werden.<br />

Eine Anweisung verändert die Inhalte von Wertebehältern. Ausdrücke und Anweisungen unterscheiden<br />

sich also dadurch, dass sie Wertebehälter nicht verändern bzw. verändern.<br />

Das Papier Anfangs-Quiz austeilen. Folgende ausgewählte Fragen daraus bearbeiten:<br />

1, 5, 6, 9, 10, 12, 25,<br />

Am kommenden Dienstag 15.10.13 schreiben wir den Test 1.<br />

Er wird ähnliche Fragen wie der Anfangs-Quiz enthalten.<br />

Zur Entspannung: Was kostet ein Studium an der <strong>Beuth</strong> <strong>Hochschule</strong>?<br />

Haushalt der <strong>Beuth</strong> <strong>Hochschule</strong> ca. 80 Millionen [Euro pro Jahr].<br />

An der <strong>Beuth</strong> <strong>Hochschule</strong> studieren ca. 10 Tausend StudentInnen.<br />

Also kostet das Studieren an der <strong>Beuth</strong> <strong>Hochschule</strong> ca. 8000 [Euro pro StudentIn und Jahr].<br />

Ein Bachelor-Studium (6 Semester, 3 Jahre) kostet also ca. 24 Tausend [Euros pro StudentIn].<br />

Pro Jahr hat eine StudentIn ca. 1000 Stunden Lehrveranstaltungen<br />

(ca. 32 Wochen lang ca. 30 Stunden pro Woche).<br />

Also kostet ein Stunde LV pro Studentin ca. 8 Euro (1 Block 16 Euro).


S. 6, <strong>WS13</strong>/<strong>14</strong> SU 2. Di 08.10.13, Block 3 <strong>Beuth</strong>-<strong>Hochschule</strong><br />

SU 2. Di 08.10.13, Block 3<br />

Iteration und Rekursion<br />

Was versteht man unter der Fakultät einer natürlichen Zahl n? Was ist die Fakultät von 3?<br />

Aufgabe-01: Schreiben Sie eine Java-Klassenfunktion (engl. a non-void static method) entsprechend der<br />

folgenden Spezifikation:<br />

1 static int fak01(int n) {<br />

2 // Liefert die Fakultaet von n.<br />

3 // Liefert 1, falls n kleiner (oder gleich) 0 ist.<br />

4<br />

5 int erg = 1;<br />

6 for (int i=2; i


<strong>Beuth</strong> <strong>Hochschule</strong> <strong>Stichworte</strong> <strong>Algorithmen</strong> <strong>WS13</strong>/<strong>14</strong>, S. 7<br />

SU 3. Di 15.10.13, Block 1<br />

Heute schreiben wir den Test 1.<br />

Allgemeine Anmerkungen zum Papier RekursionAufgaben.pdf<br />

1. Jede 2-Personen-Arbeitsgruppe soll (heute im SU 3. und später zu Hause) so lange und so oft Aufgaben<br />

aus diesem Papier lösen, bis Ihnen Rekursion ganz einfach vorkommt.<br />

2. Das Papier RekursionAufgaben.pdf enthält 15 Programmieraufgaben ("Schreiben Sie eine rekursive<br />

Methode die ...") und einige weitere Aufgaben (als Vorbereitungen auf die Programmieraufgaben).<br />

3. In der Datei RekursionTestProgs.txt finden Sie sieben Java-Programme<br />

(namens Rekursion01_Tst bis Rekursion07_Tst),<br />

mit denen Sie Ihre Lösungen der 15 Programmieraufgaben testen können (einzeln, eine nach der anderen).<br />

4. Im Abschnitt 2. Natürliche Zahlen als Folgen von Ziffern bearbeiten geht es um Ganzzahlen (engl.<br />

integral numbers) und ihre Darstellung in verschiedenen Zahlensystemen. Wenn Sie mit den weiteren<br />

Fragen am Anfang dieses Abschnitts Probleme haben, sollten Sie zuerst das Papier<br />

Zahlensysteme.pdf (4 Seiten) durcharbeiten.<br />

Aufgabe-11: fiboR (Fibonacci-Zahlen, rekursiv)<br />

8 weitere Aufgaben Aufgabe-201 bis Aufgabe-208.<br />

Regeln zur Bearbeitung von Ziffern (einer Ganzzahl)<br />

6 Programmieraufgaben Aufgabe-211 bis Aufgabe-216 (im SU nur die ersten beiden?)<br />

Aufgabe-31: fuelleAus (Farbeimer)


S. 8, <strong>WS13</strong>/<strong>14</strong> SU 4. Di 15.10.13, Block 3 <strong>Beuth</strong>-<strong>Hochschule</strong><br />

SU 4. Di 15.10.13, Block 3<br />

Variablen, aus was für Teilen bestehen die eigentlich?<br />

Die Informatik als Studienfach gibt es erst seit den 1970-er Jahren. Damals haben die Informatiker viele<br />

Konzepte und Ideen aus der Elektrotechnik und aus der Mathematik übernommen. Aber ein Grundkonzept<br />

der Informatik war ganz neu:<br />

Das Konzept einer veränderbaren Variablen.<br />

Unterschied zwischen Variablen in der Mathematik und Variablen in Programmiersprachen?<br />

Heute unterscheidet man veränderbare und unveränderbare Variablen, und beide werden in der Informatik<br />

und in der Mathematik verwendet.<br />

Aus wie vielen Teilen und aus welchen Teilen besteht eine Variable?<br />

Das Papier Variablen als Bojen darstellen besprechen (siehe Datei Bojen01.pdf auf meiner Netzseite).<br />

Seitenangaben und Bezeichnungen wie "Beispiel-01" oder "Aufgabe-01" etc. in den folgenden <strong>Stichworte</strong>n<br />

beziehen sich auf dieses Papier.<br />

In Java unterscheidet man:<br />

primitive Typen, primitive Variablen, primitive Werte<br />

Referenztypen, Referenzvariablen, Referenzwerte<br />

Beispiel-01 (Variablen anna, bert und carl) besprechen<br />

Zuweisungen: Ändern immer den Wert einer Variablen (Beispiel-02)<br />

Aufgabe-01 (auf S. 2 unten)<br />

Die new-Regel<br />

Verschiedene equals-Methoden (Beispiel-03)<br />

Jede Klasse erbt eine equals-Methode. Einige Klassen überschreiben die geerbte Methode (engl. they<br />

override the inherited equals method) mit einer eigenen, speziellen equals-Methode, andere Klassen<br />

behalten die geerbte Methode. Der Programmierer muss damit rechnen, dass jede neue equals-Methode,<br />

die ihm begegnet, etwas anderes macht als die, die er schon kennt.<br />

Beispiel: Eine Klasse Auto hat 3 Objektattribute: Typ, Motor_Nr und Farbe.<br />

Wann sind zwei Auto-Objekte gleich? Welche Attribute müssen dazu gleich sein?<br />

Der Gleichheitsoperator == und der Ungleichheitsoperator ==<br />

Die beiden vergleichen immer nur Werte (nie Zielwerte).<br />

Besondere Regeln für den Typ String<br />

Ende der Bearbeitung des Papiers Variablen als Bojen darstellen.<br />

Zur Entspannung: Al-Khwarizmi (ca. 780-850)<br />

Abu Ja'far Muhammad ibn Musa Al-Khwarizmi war ein islamischer Mathematiker, der in Bagdad lebte,<br />

über Indisch-Arabische Zahlen schrieb und zu den ersten gehörte, die die Ziffer 0 benutzten. Aus seinem<br />

Namen entstand (durch Übertragung ins Latein und dann in andere Sprachen) das Wort Algorithmus.<br />

Eine seiner Abhandlungen heißt Hisab al-jabr w'al-muqabala (auf Deutsch etwa: "Über das Hinüberbringen",<br />

von einer Seite einer Gleichung auf die andere). Daraus entstand unser Wort Algebra.<br />

Wenn noch Zeit ist: In der Datei Projekte.pdf das Projekt 1: Sammeln in einer unsortierten Reihung<br />

besprechen und bearbeiten.


<strong>Beuth</strong> <strong>Hochschule</strong> <strong>Stichworte</strong> <strong>Algorithmen</strong> <strong>WS13</strong>/<strong>14</strong>, S. 9<br />

SU 5. Di 22.10.13, Block 1<br />

Rückgabe und kurze Besprechung von Test 1<br />

1. Wenn man einen Satz aus einer Sprache in eine andere übersetzt, sollte "die Bedeutung" des Satzes so<br />

gut wie möglich erhalten bleiben. Spezialfall: Wenn man einen Befehl übersetzt, sollte das Ergebnis auch<br />

ein Befehl sein (keine Beschreibung, keine Beschimpfung etc.)<br />

Anmerkung: Wenn Sie Java-Befehle ins Deutsche übersetzen, dürfen Sie den Ausführer duzen, etwa so:<br />

"Erzeuge eine Variable ..." (statt: "Bitte erzeugen Sie eine Variable ...").<br />

2. "Vereinbaren" ist eine Tätigkeit des Programmierers (der "schreibt Vereinbarungen"). "Erzeugen" ist<br />

eine Tätigkeit des Ausführers (der erzeugt Klassen, Variablen, Methoden etc.). Eine Vereinbarung (des<br />

Programmierers) befiehlt (dem Ausführer), etwas zu erzeugen. Eine Vereinbarung ist also ein Befehl, etwas<br />

zu erzeugen (nicht, etwas zu vereinbaren).<br />

3. Auf eine Frage, die mit "Wie viele ..." beginnt, sollten Sie immer mit einer (nicht-negativen, ganzen)<br />

Zahl antworten, z.B. 17 oder 0 oder ca. 4,3 Milliarden oder so ähnlich, oder mit unendlich viele. Sie<br />

sollten nicht mit einer "Rechenaufgabe" antworten wie z.B. 2 7 oder sin(y) * tg(x) oder -100 bis +100<br />

oder so ähnlich.<br />

4. Unterscheiden Sie zwischen dem primitiven Typ int vom Referenztyp Integer.<br />

Projekt 1 weiter besprechen<br />

Wer ist mit dem Programmieren dieses Projekts fertig oder weitgehend fertig?<br />

Hinweis: Bearbeiten Sie die Projekte von sich aus so weit und so schnell wie möglich. Bedenken Sie dabei,<br />

das Sie gegen Ende des Semester wahrscheinlich eher weniger Zeit haben als jetzt. Wenn Sie auf<br />

Probleme stoßen, dann notieren Sie sich möglichst genaue Fragen (unbedingt aufschreiben, dabei möglichst<br />

viele Fachbegriffe verwenden). Die Fragen können wir dann im SU und in den Übungen besprechen.<br />

Frage 1: Wie löscht man eine Komponente einer unsortierten Reihung?<br />

Indem man sie mit der letzten belegten Komponenten speicher[nfi-1] vertauscht und den Wert<br />

von nfi um 1 verkleinert.<br />

"Physikalisch" ist die Komponente dann noch da, aber "logisch" ist sie gelöscht.<br />

Frage 2: Wie sieht der Rumpf der Methode boolean istDrin(int n) aus?<br />

return index(n) != -1;<br />

Sind alle mit dem Junit-Testprogramm LongSpeicher_Jut.java klargekommen?<br />

Zur Entspannung: Christian Morgenstern (1871-19<strong>14</strong>, München-Meran)<br />

Lyriker, Redakteur, Übersetzer (Ibsen, Strindberg). In seinen Gedichten kommen auch mathematische<br />

Ideen vor. Im folgenden Gedicht geht es um die Evolution großer Tiere und Zahlen:<br />

Anto-Logie<br />

Im Anfang lebte, wie bekannt, als größter Säuger der Gig-ant. ...<br />

Wenn noch Zeit ist: Binäres Suchen (in einer sortierten Reihung)<br />

An der Tafel vormachen (mit einer Reihung der Länge 15)<br />

Dann als Methode:<br />

static int binSuch(long[] r, long n, int von, int bis)<br />

Block 2: Übung 2, Gruppe a: Zahlensysteme, Zahlen umwandeln


S. 10, <strong>WS13</strong>/<strong>14</strong> SU 6. Di 22.10.13, Block 3 <strong>Beuth</strong>-<strong>Hochschule</strong><br />

SU 6. Di 22.10.13, Block 3<br />

Das Papier RekursionAufgaben.pdf weiter bearbeiten<br />

Wer hat seine Lösung zu Aufgabe-11 (Fibonacci-Zahlen, Methode fiboR) mit dem Programm<br />

Rekursion01_Tst getestet?<br />

Hat jemand die Methode fiboR schon mal mit dem Parameter 45 aufgerufen? Oder mit einem noch<br />

größeren Parameter, z.B. 50? Ist Ihnen dabei etwas aufgefallen? Haben Sie gegähnt?<br />

Rechenzeiten von meinem Aldi-Rechner (Intel i3, 2 Kerne mit 3,2 GHz) zu Haus, Werte stark gerundet:<br />

Methodenaufruf Rechenzeit Ergebnis (ungefähr)<br />

fiboR(40) 1 sec 0.10 Milliarden<br />

fiboR(45) 10 sec 1.13 Milliarden<br />

fiboR(50) 100 sec 12.50 Milliarden<br />

fiboR(55) 1000 sec <strong>14</strong>0.00 Milliarden<br />

Wieso braucht die Methode fiboR schon für relativ kleine Parameter wie 50 und 55 so viel<br />

Rechenzeit? Und warum nimmt die benötigte Rechenzeit so schnell zu, wenn der Parameter noch größer<br />

wird?<br />

Genauere Frage: Wie oft wird fiboR aufgerufen für verschiedene Werte von N?<br />

fiboR(N) 0 1 1 2 3 5 8 13 21<br />

N 0 1 2 3 4 5 6 7 8<br />

AnzAufrufe 1 1 3 5 9 15 25 41 67<br />

Denksport-Aufgabe: Welcher Zusammenhang besteht zwischen einer Fibonacci-Zahl (in Zeile 1) und<br />

der Anzahl der Methodenaufrufe (in Zeile 3), die zu ihrer Berechnung ausgeführt werden? Am besten<br />

beginnt man bei der Fibonacci-Zahl 5 (für deren Berechnung 15 Aufrufe nötig sind).<br />

Die 45. Fibonaccizahl (fiboR(45)) ist etwa gleich 1 Milliarde. Um Sie zu berechnen, sind<br />

ein bisschen mehr als 3 Milliarden Aufrufe der Methode fiboR nötig.<br />

Problem: Wenn fiboR die N-te Fibonacci-Zahl berechnet, werden alle kleineren Fibonacci-Zahlen<br />

nicht nur einmal, sondern mehrmals berechnet (je kleiner sie sind, desto häufiger werden sie berechnet).<br />

Wie könnte man das vermeiden (und damit die Berechnung beschleunigen)?<br />

Plan: Wir vereinbaren eine Reihung r von int-Variablen der Länge 1000 und schreiben da ("von links<br />

nach rechts") die Fibonacci-Zahlen rein. Wenn wir "eine kleinere Fibonacci-Zahl" brauchen (um eine<br />

größere zu berechnen), schauen wir in der Reihung nach, statt eine Methode rekursiv aufzurufen.<br />

Diese Technik wird als Memoisation (engl. memoization) bezeichnet: Eine Funktion "speichert ihre Ergebnisse",<br />

statt sie jedesmlaneu zu berechnen.<br />

Wer hat die Aufgabe-211 (im Papier RekursioAufgaben.pdf) fertig und getestet?<br />

Lösen Sie möglichst schnell auch die Aufgaben -212 bis -216 und testen Sie Ihre Lösungen.<br />

Eventuell die Lösung für Aufgabe-31 besprechen:<br />

Lösung der Denksportaufgabe: AnzAufrufe(N) = 3 * fiboR(N) + (N - 5)<br />

Für große N kann man den Summanden (N - 5) vernachlässigen und sagen:<br />

Zur Berechnung der N-ten Fibonaccizahl F wird fiboR etwa 3*F aufgerufen.


<strong>Beuth</strong> <strong>Hochschule</strong> <strong>Stichworte</strong> <strong>Algorithmen</strong> <strong>WS13</strong>/<strong>14</strong>, S. 11<br />

SU 7. Di 29.10.13, Block 1<br />

Heute schreiben wir den Test 2.<br />

Sortieren von Reihungen<br />

Dieses Problem gehört zu den am intensivsten untersuchten algorithmischen Problemen,<br />

für das sehr viele Lösungen entwickelt wurden.<br />

Zur Erinnerung: Die wichtigsten Eigenschaften von Reihungen (engl. arrays)<br />

Positive Eigenschaft: Der Zugriff auf eine beliebige Komponente r[i] benötigt sehr wenig Zeit, und<br />

diese Zugriffszeit ist unabhängig von der Größe von i (ein Zugriff auf r[10000] dauert nicht länger<br />

als ein Zugriff auf r[0]).<br />

Negative Eigenschaft: Reihungen "sind aus Beton" (ihre Länge ist nicht veränderbar).<br />

Ein paar Grundideen zum Sortieren von Reihungen<br />

Sortieren durch Vertauschen benachbarter Komponenten (Bubblesort):<br />

Wenn zwei nebeneinander liegende Komponenten (z.B. r[0] und r[1] oder r[17] und r[18] etc.)<br />

falsch-herum liegen, vertauscht man sie miteinander. Das macht man solange, bis alle Komponenten<br />

richtig-herum liegen.<br />

Sortieren durch Auswahl (Selectionsort):<br />

Man denkt sich die Reihung aus einem (bereits sortierten) Anfangsteil und<br />

einem (noch nicht sortieren) Endteil bestehend.<br />

Anfangs ist der Anfangsteil leer und der Endteil besteht aus der gesamten Reihungen (am Ende ist es<br />

umgekehrt: Der Anfangsteil besteht aus der gesamten Reihung und der Endteil ist leer).<br />

Bei jedem Schritt vertauscht man mit die erste Komponente des Endteils mit der kleinsten Komponente<br />

des Endteils.<br />

Nach jedem Schritt gehört eine Komponente mehr zum Anfangsteil statt zum Endteil.<br />

Sortieren durch Einfügen (Insertionsort):<br />

Man denkt sich die Reihung aus einem (bereits sortierten) Anfangsteil und<br />

einem (noch nicht sortieren) Endteil bestehend.<br />

Anfangs ist der Anfangsteil leer und der Endteil besteht aus der gesamten Reihungen (am Ende ist es<br />

umgekehrt: Der Anfangsteil besteht aus der gesamten Reihung und der Endteil ist leer).<br />

Bei jedem Schritt verschiebt man die erste Komponente des Endteils (durch eventuell mehrmaliges Vertauschen<br />

mit ihrem linken Nachbarn) solange nach links, bis sie "an der richtigen Stelle liegt".<br />

Nach jedem Schritt gehört eine Komponente mehr zum Anfangsteil statt zum Endteil.


S. 12, <strong>WS13</strong>/<strong>14</strong> SU 7. Di 29.10.13, Block 1 <strong>Beuth</strong>-<strong>Hochschule</strong><br />

Zur Entspannung: Alan Mathison Turing (1912-1954), einer der Begründer der Informatik<br />

Bevor man die ersten elektronischen Computer baute, konzipierte und untersuchte der Mathematiker<br />

Turing eine Rechenmaschine, die so einfach war, dass niemand an ihrer prinzipiellen Realisierbarkeit<br />

zweifelte. Eine solche Turing-Maschine besteht aus einem unbegrenzt langen Band, welches in kleine<br />

Abschnitte eingeteilt ist, von denen jeder genau ein Zeichen eines endlichen Alphabets aufnehmen kann.<br />

Ein Schreib-Lese-Kopf über dem Band kann bei jedem Arbeitsschritt der Maschine das Zeichen auf<br />

dem aktuellen Abschnitt lesen und in Abhängigkeit davon ein bestimmtes Zeichen auf den aktuellen<br />

Abschnitt schreiben und einen Abschnitt nach links oder rechts weiter rücken. Ein Programm für eine<br />

solche Maschine besteht aus einer endlichen Menge von Befehlen der folgenden Form:<br />

"Wenn das aktuelle Zeichen gleich X ist, dann schreibe Y und gehe einen Abschnitt nach links bzw.<br />

nach rechts bzw. bleib wo du bist" (wobei X und Y beliebige Zeichen des Alphabets sind).<br />

Wichtige Erkenntnis 1: Es gibt viele (präzise definierte, mathematische) Probleme, die man mit Hilfe einer<br />

solchen Turing-Maschine lösen kann (z. B. das Multiplizieren von dreidimensionalen Matrizen).<br />

Wichtige Erkenntnis 2: Es gibt aber auch (präzise definierte, mathematische) Probleme, die man nicht<br />

mit Hilfe einer solchen Turing-Maschine lösen kann.<br />

Wichtige Vermutung 3: Alle Probleme, die man mit heutigen oder zukünftigen Computern lösen kann,<br />

kann man im Prinzip auch mit einer Turing-Maschine lösen.<br />

Im zweiten Weltkrieg arbeitete Turing für die Government Code and Cypher School in Bletchley Park<br />

(d. h. für den britischen Geheimdienst) und half entscheidend dabei, die Maschine zu durchschauen, mit<br />

der die deutsche Marine ihre Funksprüche verschlüsselte (die Enigma), und wichtige Funksprüche zu<br />

entschlüsseln. Damit hat er vermutlich einer ganzen Reihe von alliierten Soldaten (Engländern, Amerikanern,<br />

Franzosen, Russen) das Leben gerettet.<br />

Weil er homosexuell war, wurde Turing nach dem Krieg zu einer Hormonbehandlung "seiner Krankheit"<br />

gezwungen, bekam schwere Depressionen und nahm sich das Leben. Inzwischen wurden die entsprechenden<br />

Gesetze in England (und ähnliche Gesetze in anderen Ländern) beseitigt. Im September<br />

2009 entschuldigte sich der britische Premierminister Gordon Brown dafür, wie Turing behandelt worden<br />

ist.<br />

Bubbelsort (und evtl. Insertionsort und Selectionsort) programmieren, in die Datei Sort_BIS_A.java<br />

einfügen und testen.<br />

Block 2: Übung 2, Gruppe b: Zahlensysteme, Zahlen umwandeln


<strong>Beuth</strong> <strong>Hochschule</strong> <strong>Stichworte</strong> <strong>Algorithmen</strong> <strong>WS13</strong>/<strong>14</strong>, S. 13<br />

SU 8. Di 29.10.13, 3. Block<br />

Wie kann man <strong>Algorithmen</strong> miteinander vergleichen?<br />

Angenommen, wir haben zwei <strong>Algorithmen</strong> A1 und A2, mit denen man Reihungen sortieren kann. Wie<br />

können wir die miteinander vergleichen um herauszufinden, ob einer der beiden deutlich schneller ist als<br />

der andere?<br />

Dabei ist klar: Das Sortieren einer langen Reihung wird im Allgemeinen länger dauern, als das Sortieren<br />

einer kurzen Reihung. Wir suchen also nicht nach einer Zahl, sondern nach einer Antwort auf die<br />

Frage-1: Wie hängt der Zeitbedarf von A1 (bzw. A2) von der Größe N des bearbeiteten Problems<br />

(im Beispiel: von der Länge der zu sortierenden Reihung) ab?<br />

Vorgehensweise-1: Wir implementieren A1 und A2 z.B. in Java, lassen sie z.B. auf einem Windows<br />

Rechner z.B. mit Pentium-Prozessor Reihungen unterschiedlicher Länge sortieren, Messen die benötigte<br />

Zeit und tragen sie in eine Tabelle ein.<br />

Möglicherweise ist einer der beiden <strong>Algorithmen</strong> bei allen Problemgrößen N schneller als der andere. Es<br />

sind aber auch kompliziertere Ergebnisse möglich, etwa so: Bis zu einer bestimmten Länge der Reihungen<br />

ist A1 schneller, aber für längere Reihungen ist A2 schneller, oder so ähnlich.<br />

Was ist nicht so gut an der Vorgehensweise-1?<br />

(Die Messergebnisse hängen wahrscheinlich nicht nur von den <strong>Algorithmen</strong> ab, sondern auch von der<br />

Programmiersprache, dem Betriebssystem, der Hardware etc. Außerdem ändern sich die Ausführungszeiten,<br />

wenn ein neuer Prozessor oder eine neue Betriebssystem-Version herauskommt).<br />

Frage-2: Wie können wir etwas über den Zeitbedarf eines abstrakten Algorithmus herausfinden, was<br />

möglichst unabhängig ist von bestimmten Programmiersprachen, Betriebssystemen und Prozessoren?<br />

Vorgehensweise-2: Wir untersuchen den Text des Algorithmus und versuchen herauszufinden: Wie viele<br />

Schritte müssen ausgeführt werden, wenn man nach diesem Algorithmus ein Problem der Größe N bearbeitet?<br />

Kernfrage: Was ist (beim Analysieren von <strong>Algorithmen</strong>, nicht beim Wandern) ein Schritt?<br />

Def.: Ein Schritt ist eine Befehlsfolge, von der es plausibel ist anzunehmen, dass ihre Ausführungszeit<br />

immer etwa gleich groß ist oder zumindest eine bestimmte feste Zeit nicht überschreitet.<br />

Insbesondere darf die Ausführungszeit für einen Schritt nicht von der Problemgröße N abhängen.<br />

Bei vielen <strong>Algorithmen</strong> ist die Problemgröße N gleich der Länge der Eingabe, die der Algorithmus bearbeitet.<br />

Beispiel: Bei einem Algorithmus zum Sortieren von Reihungen ist die zu sortierende Reihung die Eingabe.<br />

Mit der Problemgröße N ist in diesem Fall also die Länge dieser Reihung gemeint.


S. <strong>14</strong>, <strong>WS13</strong>/<strong>14</strong> SU 8. Di 29.10.13, 3. Block <strong>Beuth</strong>-<strong>Hochschule</strong><br />

Konkrete Beispiele für Schritte und nicht-Schritte:<br />

Befehlsfolge<br />

1 Addition von zwei int-Werten ja<br />

500 Additionen von je zwei int-Werten ja<br />

Ein Schritt? Begründung<br />

N Additionen von je zwei int-Werten nein abhängig von Problemgröße N<br />

1 Vergleich von zwei char-Werten ja<br />

1 Vergleich von zwei String-Objekten<br />

500 Vergleiche von String-Objekten,<br />

die höchstens 100 Zeichen lang sind<br />

1 Addition von zwei BigInteger-<br />

Objekten<br />

500 Additionen von BigInteger-Objekten,<br />

die weniger als 100 int-Variablen<br />

enthalten.<br />

N Additionen von BigInteger-Objekten,<br />

die weniger als 100 int-Variablen<br />

enthalten<br />

nein<br />

ja<br />

nein<br />

ja<br />

nein<br />

500 Schritte ja<br />

Ein String-Objekt kann bis zu<br />

2,15 Milliarden char-Werte enthalten<br />

Ein BigInteger-Objekt kann bis zu<br />

2,15 Milliarden int-Variablen enthalten<br />

abhängig von Problemgröße N<br />

N Schritte nein abhängig von Problemgröße N<br />

Der Begriff eines Schrittes kann einem anfangs widersinnig vorkommen (z.B. weil man 500 Schritte<br />

auch als 1 Schritt zählen kann). Später werden wir sehen, dass man beim Abschätzen von Schrittzahlen<br />

häufig von konstanten Faktoren abstrahiert, d.h. keinen Unterschied zwischen dem Faktor 1 und einem<br />

Faktor wie 500 macht (wohl aber zwischen den Funktionen N und N 2 und 2 N etc.).<br />

<strong>Algorithmen</strong> analysieren und Schrittfunktionen entwickeln<br />

Die Datei SchrittFunktionenA. java öffnen, die "abstrakten <strong>Algorithmen</strong>" alg00, alg01, ...<br />

ansehen und analysieren und für jeden Algorithmus eine Schrittfunktion stp00, stp01, ... entwickeln.


<strong>Beuth</strong> <strong>Hochschule</strong> <strong>Stichworte</strong> <strong>Algorithmen</strong> <strong>WS13</strong>/<strong>14</strong>, S. 15<br />

SU 9. 05.11.13<br />

Arbeitsblatt austeilen und bearbeiten<br />

Aufgabe-01: Was ist bei diesen <strong>Algorithmen</strong> die Problemgröße n?<br />

Die Länge str.length der zu sortierenden Reihung.<br />

Aufgabe-02: Welche Befehle in diesen <strong>Algorithmen</strong> kann man als einen Schritt zählen?<br />

Den Rumpf der inneren for-Schleifen (Zeile 4-6 bzw. <strong>14</strong>-16).<br />

Aufgabe-03: Schrittfunktion für bubbleSortA?<br />

n * (n - 1) gleich n 2 - n<br />

Aufgabe-04: Schrittfunktion für bubbleSortB?<br />

(n-1) + (n-2) + ... + 2 + 1 = n * (n - 1) / 2 = (n 2 - n) / 2<br />

Von Schrittfunktionen zur Tilde- und zur Groß-O-Notation<br />

Angenommen, wir haben zwei <strong>Algorithmen</strong> A1 und A2, die dasselbe Problem lösen (z.B. Reihungen<br />

sortieren).<br />

Schrittfunktion von A1 (stepA1): n 2<br />

Schrittfunktion von A2 (stepA2): n 2 + 10*n<br />

Ist A2 wesentlich schneller als A1?<br />

Eine Tabelle mit Schrittzahlen (für A1 und A2 und verschiedene n):<br />

Problemgröße n n 2 10*n stepA1 stepA2<br />

5 25 50 25 75<br />

10 100 100 100 200<br />

100 10_000 1_000 10_000 11_000<br />

1_000 1_000_000 10_000 1_000_000 1_010_000<br />

10_000 100_000_000 100_000 100_000_000 100_100_000<br />

100_000 10_000_000_000 1_000_000 10_000_000_000 10_001_000_000<br />

A1 benötigt mehr Schritte als A2. Wie groß ist der Unterschied in % ausgedrückt?<br />

Problemgröße n A2 benötigt wie viel<br />

mehr Schritte als A1?<br />

5 200 %<br />

10 100 %<br />

100 10 %<br />

1_000 1 %<br />

10_000 0,1 %<br />

100_000 0,01 %<br />

Praktisch wichtig sind vor allem die Schrittzahlen für große Probleme (d.h. für große n). Unterschiede<br />

von 1% oder weniger kann man in der Praxis in aller Regel vernachlässigen.<br />

Ergebnis: Zwischen den <strong>Algorithmen</strong> A1 und A2 gibt es keinen praktisch wichtigen Unterschied in den<br />

Schrittzahlen.<br />

Hinweis: Die Eclipse-Version Kepler hat ein Problem mit JUnit-3-Programmen. Wie man das Problem<br />

lösen kann, steht jetzt in der Datei TippsZuEclipse.pdf.


S. 16, <strong>WS13</strong>/<strong>14</strong> SU 9. 05.11.13 <strong>Beuth</strong>-<strong>Hochschule</strong><br />

Arbeitsblatt MB2-ALG (<strong>Algorithmen</strong>)<br />

1. Schrittfunktionen für Varianten von Bubblesort<br />

1 static void bubbleSortA(String[] str) {<br />

2 for (int i=str.length; i>0; i--) {<br />

3 for (int j=0; j0; i--) {<br />

13 for (int j=0; j


<strong>Beuth</strong> <strong>Hochschule</strong> <strong>Stichworte</strong> <strong>Algorithmen</strong> <strong>WS13</strong>/<strong>14</strong>, S. 17<br />

Von Schrittzahlfunktionen zur Tilde- und zur Groß-O-Notation<br />

Beispiel:<br />

Von einem Algorithmus A mit der Schrittfunktion 5*n 3 + 8*n 2 + 4n + 50<br />

sagt man auch: Seine Schrittzahl ist proportional zu 5*n 3<br />

Tilde-Notation: Schrittzahl(A) ~ 5*n 3<br />

Es gilt: Wenn n gegen unendlich geht, dann<br />

geht der Quotient (5*n 3 + 8*n 2 + 4n + 50) / 5*n 3<br />

gegen 1. In diesem Sinne sind die Polynome 5*n 3 + 8*n 2 + 4n + 50 und 5*n 3<br />

im Wesentlichen gleich.<br />

Indem man von der Schrittzahlfunktion 5*n 3 + 8*n 2 + 4n + 50<br />

zu 5*n 3 übergeht, tauscht man also ein bisschen Genauigkeit gegen viel Einfachheit ein.<br />

Meistens geht man noch radikaler vor, und lässt auch noch den Faktor der höchsten Potenz von n (im<br />

Beispiel: 5) weg und beschreibt den Zeitbedarf des Algorithmus A wie folgt:<br />

Groß-O-Notation: Zeitkomplexität(A): O(n 3 )<br />

Falls noch Zeit ist: Projekt 2 (Sammeln in einer sortierten Reihung) und im Papier RekursionAufgaben<br />

die Aufgabe-31 (Methode fuelleAus) und Aufgabe-41 und -42 (Grundrechenarten mul und pot)<br />

programmieren.<br />

Zur Entspannung: Eigenschaften von Qubits (Quanten-Bits)<br />

1. Mit n "normalen Bits" kann man eine Zahl (zwischen 0 und 2 n -1) darstellen. Mit n Qubits kann man<br />

gleichzeitig bis zu 2 n Zahlen (zwischen 0 und 2 n -1) darstellen und mit einer Operation kann man alle<br />

diese Zahlen "gleichzeitig bearbeiten".<br />

Angenommen wir haben einen Speicher S, der aus 20 Qubits besteht. Dann können wir darin etwa 1<br />

Million Zahlen (zwischen 0 und etwa 1 Million) speichern und mit einer Operation all diese Zahlen auf<br />

einmal verändern. Wenn S aus 30 Qubits besteht, gilt alles entsprechend, aber mit 1 Milliarde Zahlen,<br />

und bei 40 Qubits mit 1 Billion Zahlen etc.<br />

2. Wenn man unseren Speicher S "ansieht und ausliest", bekommt man allerdings nur eine der Zahlen,<br />

die sich im Speicher befinden. Die übrigen Zahlen gehen dabei unvermeidbar und unwiderruflich verloren.<br />

Während mit unserem Speicher S gerechnet wird, muss der Speicher deshalb sorgfältig von der<br />

Umwelt isoliert werden, denn fast jede Interaktion des Speichers mit der Umwelt zählt als "ansehen und<br />

auslesen".<br />

3. Es ist nicht möglich, ein Qubit (mit all seinen Werten) zu kopieren. Man kann höchstens einen seiner<br />

Werte kopieren (und die übrigen Werte gehen dabei verloren).<br />

4. Auf Qubits kann man nur umkehrbare Verknüpfungen anwenden.<br />

Zur Zeit (2008) erforschen mehrere Tausend Physiker, Informatiker und Ingenieure in mehr als 100 Forschungsgruppen<br />

etwa ein Dutzend Möglichkeiten, Qbits zu realisieren (durch ion traps. quantum dots,<br />

linear optics, ...).<br />

Eine interessante Einführung in die Quantenmechanik von einer Berliner Schülerin:<br />

Silvia Arroyo Camejo: "Skurrile Quantenwelt", Springer 2006, Fischer 2007


S. 18, <strong>WS13</strong>/<strong>14</strong> SU 9. 05.11.13 <strong>Beuth</strong>-<strong>Hochschule</strong><br />

Block 2: Übung 3, Gruppe a: Papier: TippsZuEclipse.pdf<br />

1. Zeilen-Nummern und Druckgrenze<br />

Starten Sie Ihre Eclipse-Umgebung und stellen Sie sie so ein, dass Java-Quelldateien immer mit Zeilen-<br />

Nummern am Rand auf dem Bildschirm angezeigt und gedruckt werden. Folgen Sie dazu dem Abschnitt<br />

3.1. im oben angegebenen Papier.<br />

Lassen Sie auch gleich eine Druckgrenze (a print margin) anzeigen, z.B. nach Spalte 75 (ebenfalls Abschnitt<br />

3.1.).<br />

2. Einrücktiefe und Tab-Breite<br />

Stellen Sie in Ihrer Eclipse-Umgebung die Einrücktiefe (Indentation size) und die Breite-eines-Drucksauf-die-Tabulator-Taste<br />

(Tab size:) beide auf 3 ein. Folgen Sie dazu dem Abschnitt 3.2. des oben angegebenen<br />

Papiers.<br />

Wenn Sie eine Java-Quelldatei editieren, bewirkt das Tastenkürzel Strg+Ums+F, dass die ganze Datei<br />

(bzw. der ausgewählte Teil der Datei) entsprechend dem aktuellen Profil formatiert wird.<br />

Anmerkung: Die Einstellungen mit 3 sind empfehlenswert, weil in dieser Lehrveranstaltung alle vorgegebenen<br />

Java-Codezeilen mit einer Einrücktiefe von 3 Zeichen erstellt wurden.<br />

3. Ein Tastenkürzel definieren<br />

Definieren Sie in Ihrer Eclipse-Umgebung das Tastenkürzel Alt+C. Es soll die aktuelle Zeile (die, in der<br />

der Cursor gerade steht) ausschneiden (d.h. in die Zwischenablage kopieren und aus der betreffenden<br />

Datei entfernen). Folgen Sie dazu dem Abschnitt 5.2. des oben angegebenen Papiers.<br />

Anmerkung: Ohne ein Tastenkürzel wie Alt+C ist es relativ mühsam, eine Zeile auszuschneiden. Das<br />

Auswählen von genau einer Zeile mit der Maus kostet relativ viel Zeit und ist fehleranfällig (man wählt<br />

leicht ein bisschen zu wenig oder ein bisschen zu viel aus).


<strong>Beuth</strong> <strong>Hochschule</strong> <strong>Stichworte</strong> <strong>Algorithmen</strong> <strong>WS13</strong>/<strong>14</strong>, S. 19<br />

SU 10. Di 05.11.13, Block 3<br />

Alle drei BIS-<strong>Algorithmen</strong> (Bubblesort, Insertionsort, Selectionsort) haben eine<br />

Zeitkomplexität von O(n 2 ).<br />

Was bedeutet das anschaulich? Angenommen, zum Sortieren einer Reihung der Länge 1000 braucht ein<br />

bestimmter Rechner 1 sec. Wie lange braucht er dann wahrscheinlich für eine 2-mal so lange Reihung?<br />

Und für eine 3-mal so lange? Und für eine 4-mal so lange Reihung?<br />

(für eine 2-mal so lange: 2 2 sec, für eine 3-mal so lange: 2 3 sec, für eine 4-mal so lange: 2 4 sec, ...)<br />

Kann man schneller sortieren?<br />

Ja, z.B. mit den folgenden zwei genialen Ideen:<br />

Geniale-Idee-1:<br />

Statt eine Reihung r der Länge n mit Bubblesort zu sortieren,<br />

sortieren wir zwei Reihungen rl und rr (die "linke und die rechte Hälfte" von r) der Länge n/2 .<br />

Zusammenführen (engl. merge): Wir machen aus den beiden sortierten Reihungen rl und rr wieder<br />

eine sortierte Reihung. Was kostet das? (n Schritte).<br />

Beispiel: Eine Reihung der Länge 200 mit Bubblesort: Etwa 200 2 gleich 40_000 Schritte.<br />

Zwei Reihungen der Länge 100 mit Bubblesort: Etwa 2 * 100 2 gleich 20_000 Schritte, plus<br />

Zusammenführen 200 Schritte, insgesamt 20_200 Schritte. Ersparnis: Fast 50 %.<br />

Geniale-Idee-2:<br />

Rekursion: Statt die Teilreihungen rl und rl mit Bubblesort zu sortieren,<br />

sortieren wir sie mit demselben Trick wie die gesamte Reihung.<br />

Wir teilen rl in zwei Hälften rll und rlr und ...<br />

Wir teilen rr in zwei Hälften rrl und rrr und ...<br />

Reihungen der Länge 0 oder 1 sind immer schon sortiert (sogar gleichzeitig auf- und absteigend), wir<br />

brauchen Sie also nicht mehr zu sortieren und können sie gleich zusammenführen (mergen).<br />

Zur Erinnerung: Was sagt uns der log 2 (n) über die Ganzzahl n? Die Anzahl der 2-er-Ziffern, die<br />

man zur Darstellung von n benötigt. Und? ("Wie oft man n halbieren und die Hälften wieder halbieren<br />

und die Viertel wieder halbieren ... etc. kann, bis man bei Teilen der Länge 1 (oder 0) ist").<br />

Dieses Verfahren (Mergesort) kann man etwa so grafisch darstellen:<br />

n Komponenten<br />

log 2<br />

(n) Ebenen<br />

● ● ●<br />

● ● ●


S. 20, <strong>WS13</strong>/<strong>14</strong> SU 11. Di 12.11.13, Block 1 <strong>Beuth</strong>-<strong>Hochschule</strong><br />

SU 11. Di 12.11.13, Block 1<br />

Ab heute findet der Block 1 im Raum D212 statt (nicht mehr im D209)<br />

Heute schreiben wir den Test 3.<br />

Ein Muster für viele <strong>Algorithmen</strong>: Teile und herrsche<br />

Im letzten SU haben wir uns mit dem Sortieralgorithmus Mergesort (Sortieren durch Teilen und Zusammenführen)<br />

befasst. Dieser Algorithmus entspricht einem Muster, dem auch viele andere <strong>Algorithmen</strong><br />

entsprechen.<br />

Dieses Muster sieht drei Schritte vor:<br />

1. Das gesamte zu lösende Problem wird in Teile zerlegt (meistens 2, manchmal mehr Teile).<br />

2. Für jedes Teilproblem wird eine Teillösung berechnet (in einfachen Fällen direkt, sonst rekursiv).<br />

3. Aus den Teillösungen wird eine Lösung des Gesamtproblems zusammengesetzt.<br />

Bezeichnung des Musters in verschiedenen Sprachen:<br />

Latein:<br />

Deutsch:<br />

Englisch:<br />

Divide et impera<br />

Teile und herrsche<br />

Divide and conquer<br />

Beispiele für <strong>Algorithmen</strong>, die diesem Muster entsprechen:<br />

Binäres Suchen (in einer sortierten Reihung), Mergesort, Quicksort (und viele weitere).<br />

Die Datei LongSpeicher_Jut.java: Wozu ist sie da? Wozu nicht?<br />

Diese JUnit-Datei soll die Abnahme der Projekte 1 bis 6 vereinfachen.<br />

Sie ist nicht als Entwicklungswerkzeug gedacht!<br />

Welche Methoden kann diese JUnit-Datei testen? (fuegeEin, loesche und istDrin)<br />

Das sind die in der Schnittstelle LongSpeicher definierten Methoden.<br />

Welche Methoden kann diese JUnit-Datei nicht testen?<br />

In LongSpeicher10 und LongSpeicher20: index<br />

In LongSpeicher30 und LongSpeicher40: vorgaenger<br />

In LongSpeicher50: refk<br />

Es ist aber wichtig (beim Entwickeln der Klasse LongSpeicher20),<br />

die Methode index zu testen, bevor man die übrigen Methoden bearbeitet!<br />

Das geht aber nicht mit LongSpeicher_Jut.java.<br />

Wie sollte man z.B. bei der Entwicklung der Klasse LongSpeicher20 vorgehen?<br />

1. Man schreibt die Methode index.<br />

2. Man testet die Methode index durch Befehle in der main-Methode<br />

3. Man schreibt die Methode fuegeEin.<br />

4. Man testet die Methode fuegeEin durch Befehle in der main-Methode<br />

5. Man schreibt die Methode ...<br />

6. Man testet die Methode ... durch Befehle in der main-Methode.<br />

Für die anderen Projekte gilt Entsprechendes.<br />

Aufgabe-01: Schreiben Sie eine Methode static boolean istPrim(int n) {...}


<strong>Beuth</strong> <strong>Hochschule</strong> <strong>Stichworte</strong> <strong>Algorithmen</strong> <strong>WS13</strong>/<strong>14</strong>, S. 21<br />

Arbeitsblatt MB2-ALG (<strong>Algorithmen</strong>): Was bedeuten bestimmte Zeitkomplexitäten anschaulich?<br />

Die folgende Tabelle stammt aus http://de.wikipedia.org/wiki/Landau-Symbole#Beispiele_und_Notation<br />

und wurde nur geringfügig der Terminologie des vorliegenden Papiers angepasst.<br />

Sei f(n) ein Funktion mit einem positiven, ganzzahligen Parameter n.<br />

Notation Bedeutung Anschauliche Erklärung Beispiele für Laufzeiten<br />

Alle Werte von f liegen (unabhängig<br />

von n) unterhalb einer<br />

Zugriff auf die n-te Komponente<br />

f ϵ O(1) f ist beschränkt<br />

r[n] einer Reihung r.<br />

Konstanten.<br />

f ϵ O(log(n))<br />

f ϵ O(√n)<br />

f ϵ O(n)<br />

f wächst<br />

logarithmisch<br />

f wächst wie die<br />

Quadratwurzelfunktion<br />

f wächst<br />

linear<br />

f ϵ O(n * log(n)) f wächst<br />

super-linear<br />

f ϵ O(n 2 )<br />

f ϵ O(2 n )<br />

f ϵ O(n!)<br />

f wächst<br />

quadratisch<br />

f wächst<br />

exponentiell<br />

f wächst<br />

faktoriell<br />

f wächst ungefähr um einen<br />

konstanten Betrag, wenn man<br />

n ver-2-facht (die Basis des<br />

Logarithmus ist dabei egal).<br />

f wächst ungefähr auf<br />

das 2-fache, wenn man<br />

n ver-4-facht.<br />

f wächst ungefähr auf<br />

das 2-fache, wenn man<br />

n ver-2-facht.<br />

f wächst ungefähr auf<br />

das 4-fache, wenn man<br />

n ver-2-facht.<br />

f wächst ungefähr auf<br />

das 2-fache, wenn man<br />

n um 1 erhöht.<br />

f wächst ungefähr auf<br />

das (n+1)-fache, wenn man<br />

n um 1 erhöht.<br />

Binäre Suche in einer sortierten<br />

Reihung der Länge n.<br />

Naiver Primzahltest mittels Teilen<br />

durch jede ganze Zahl ≤√n.<br />

Suche in unsortierter Reihung der<br />

Länge n<br />

Sehr gute <strong>Algorithmen</strong> zum Sortieren<br />

einer Reihung der Länge n,<br />

z.B. Mergesort, Heapsort<br />

Einfache <strong>Algorithmen</strong> zum Sortieren<br />

einer Reihung der Länge n,<br />

z.B. Selectionsort.<br />

Erfüllbarkeitsproblem der Aussagenlogik<br />

(SAT) mittels exhaustivem<br />

Verfahren<br />

Problem des Handlungsreisenden<br />

Erweitern Sie diese Tabelle um ein paar Zeilen, indem Sie die folgenden Aufgaben lösen. Als Lösung<br />

brauchen Sie jeweils nur eine Zahl oder einen einfachen Ausdruck hinter dem Wort "Faktor" einzufügen.<br />

Aufgabe-02: Angenommen, die Funktion f(n) wächst wie die 3. Wurzel von n (Kubikwurzel von n).<br />

Was bedeutet das anschaulich?<br />

f(n) wächst ungefähr auf das 2-fache, wenn man n um den Faktor vergrößert.<br />

Aufgabe-03: Angenommen, die Funktion f(n) wächst wie die m-te. Wurzel.<br />

Was bedeutet das anschaulich?<br />

f(n) wächst ungefähr auf das 2-fache, wenn man n um den Faktor vergrößert.<br />

Aufgabe-04: Angenommen, die die Funktion f(n) wächst wie die 3. Potenz (wie n 3 ).<br />

Was bedeutet das anschaulich?<br />

f(n) wächst ungefähr um den Faktor , wenn man n ver-2-facht.<br />

Aufgabe-05: Angenommen, die die Funktion f(n) wächst wie die m-te Potenz (wie n m ).<br />

Was bedeutet das anschaulich?<br />

f(n) wächst ungefähr um den Faktor , wenn man n ver-2-facht.


S. 22, <strong>WS13</strong>/<strong>14</strong> SU 11. Di 12.11.13, Block 1 <strong>Beuth</strong>-<strong>Hochschule</strong><br />

Lösung-01: Schreiben Sie eine Methode static boolean istPrim(int n) {...}<br />

1 static boolean istPrim02(int zahl) {<br />

2 // Liefert true, wenn zahl eine Primzahl ist, sonst false.<br />

3<br />

4 int maxTeiler = (int) Math.sqrt(zahl);<br />

5 for (int teiler=2; teiler


<strong>Beuth</strong> <strong>Hochschule</strong> <strong>Stichworte</strong> <strong>Algorithmen</strong> <strong>WS13</strong>/<strong>14</strong>, S. 23<br />

Block 2: Übung 3, Gruppe b: Papier: TippsZuEclipse.pdf<br />

1. Zeilen-Nummern und Druckgrenze<br />

Starten Sie Ihre Eclipse-Umgebung und stellen Sie sie so ein, dass Java-Quelldateien immer mit Zeilen-<br />

Nummern am Rand auf dem Bildschirm angezeigt und gedruckt werden. Folgen Sie dazu dem Abschnitt<br />

3.1. im oben angegebenen Papier.<br />

Lassen Sie auch gleich eine Druckgrenze (a print margin) anzeigen, z.B. nach Spalte 75 (ebenfalls Abschnitt<br />

3.1.).<br />

2. Einrücktiefe und Tab-Breite<br />

Stellen Sie in Ihrer Eclipse-Umgebung die Einrücktiefe (Indentation size) und die Breite-eines-Drucksauf-die-Tabulator-Taste<br />

(Tab size:) beide auf 3 ein. Folgen Sie dazu dem Abschnitt 3.2. des oben angegebenen<br />

Papiers.<br />

Wenn Sie eine Java-Quelldatei editieren, bewirkt das Tastenkürzel Strg+Ums+F, dass die ganze Datei<br />

(bzw. der ausgewählte Teil der Datei) entsprechend dem aktuellen Profil formatiert wird.<br />

Anmerkung: Die Einstellungen mit 3 sind empfehlenswert, weil in dieser Lehrveranstaltung alle vorgegebenen<br />

Java-Codezeilen mit einer Einrücktiefe von 3 Zeichen erstellt wurden.<br />

3. Ein Tastenkürzel definieren<br />

Definieren Sie in Ihrer Eclipse-Umgebung das Tastenkürzel Alt+C. Es soll die aktuelle Zeile (die, in der<br />

der Cursor gerade steht) ausschneiden (d.h. in die Zwischenablage kopieren und aus der betreffenden<br />

Datei entfernen). Folgen Sie dazu dem Abschnitt 5.2. des oben angegebenen Papiers.<br />

Anmerkung: Ohne ein Tastenkürzel wie Alt+C ist es relativ mühsam, eine Zeile auszuschneiden. Das<br />

Auswählen von genau einer Zeile mit der Maus kostet relativ viel Zeit und ist fehleranfällig (man wählt<br />

leicht ein bisschen zu wenig oder ein bisschen zu viel aus).


S. 24, <strong>WS13</strong>/<strong>14</strong> SU 12. Di 12.11.13, Block 3 <strong>Beuth</strong>-<strong>Hochschule</strong><br />

SU 12. Di 12.11.13, Block 3<br />

Das Papier Bojen02.pdf besprechen<br />

Seite 1, Beispiel-01<br />

Reihungen mit primitiven Komponenten (Komponenten liegen innerhalb der Reihung)<br />

Reihungen mit Referenzkomponenten (Die Zielwerte der Komponenten liegen außerhalb der Reihung)<br />

Eine Reihung von String-Variablen enthält also eigentlich keine String-Objekte sondern?<br />

(Referenzen, die auf String-Objekte zeigen).<br />

Die Komponenten von Reihungen sind Beispiele für Variablen ohne (einfachen) Namen.<br />

Was man bei Reihungen weglassen darf: Die length-Variable und die Referenzen von Komponenten.<br />

Seite 2, Beispiel-02<br />

Ein Objekt kann gleichzeitig zu mehreren Reihungen gehören.<br />

Seite 2, Beispiel-03<br />

Null-Komponenten: Keine Kaffeetasse ist etwas anderes, als eine leere Kaffeetasse.<br />

Seite 3, Beispiel-01 und -02: Einstufige und mehrstufige Reihungen<br />

Seite 3, Beispiel-03: Eine Reihung ist n+1-stufig, wenn ihre Komponenten n-stufig sind.<br />

Seite 3, Beispiel-04: Komponententyp und elementarer Komponententyp einer mehrstufigen Reihung<br />

Seite 3, Beispiel-05: Eine 2-stufige Reihung mit primitiven Komponenten und Flatterrand<br />

Seite 4, Beispiel-06: Eine 2-stufige Reihung mit null-Komponenten und Flatterrand<br />

Seite 4: Eine Reihung in 3 Schritten erzeugen (oder in einem einzigen Schritt)<br />

Seite 5 und 6 überspringen wir erst mal.<br />

Seite 7:<br />

Eine Reihung kann Komponenten eines Referenztyps enthalten.<br />

Ein Objekt kann Attribute eines Referenztyps enthalten.<br />

Ein Objekt kann zu mehreren Objekten gehören<br />

Beispiel: Das String-Objekt "Schultze" gehört zu den Objekten anna und bert.


<strong>Beuth</strong> <strong>Hochschule</strong> <strong>Stichworte</strong> <strong>Algorithmen</strong> <strong>WS13</strong>/<strong>14</strong>, S. 25<br />

SU 13. Di 19.11.13, 1. Block<br />

Um 7.45 Uhr: Test3a<br />

Ergänzende Anmerkung zum Arbeitsblatt für den 11. SU<br />

Tabelle mit Zeitkomplexitäten, siehe oben S. 21:<br />

f ϵ O(log(n))<br />

f wächst<br />

logarithmisch<br />

f wächst ungefähr um einen<br />

konstanten Betrag, wenn man<br />

n ver-2-facht (die Basis des<br />

Logarithmus ist dabei egal).<br />

Binäre Suche in einer sortierten<br />

Reihung der Länge n.<br />

Statt "wächst ungefähr um einen konstanten Betrag" kann man auch "wächst um 1 Schritt" sagen. Dadurch<br />

wird die "symmetrische Entsprechung" zu folgender Zeitkomplexität deutlicher:<br />

f ϵ O(2 n )<br />

f wächst<br />

exponentiell<br />

f wächst ungefähr auf<br />

das 2-fache, wenn man<br />

n um 1 erhöht.<br />

Was bedeutet oder bezeichnet der Name einer Rerferenzvariablen?<br />

Angenommen, wir haben folgende Referenzvariable:<br />

1 StringBuilder stb = new StringBuilder("ABC");<br />

Die vier Teile der Variablen stb als (ASCI-) Boje dargestellt:<br />

|stb| Name<br />

|<br />

Referenz<br />

|<br />

[] Wert<br />

|<br />

["ABC"] Zielwert<br />

Erfüllbarkeitsproblem der Aussagenlogik<br />

(SAT) mittels exhaustivem<br />

Verfahren<br />

In jedem der folgenden Befehle kommt der Variablenname stb vor. Welchen Teil der Variable bezeichnet<br />

der Name stb in den einzelnen Befehlen?<br />

1 if (stb == ...) ... // Den Wert []<br />

2 stb.append("ZZ"); // Den Zielwert ["ABC"], ein StringBuilder-Objekt<br />

3 stb = ... ; // Den Wert []<br />

4 pln(stb); // Falls stb den Wert [], dann diesen Wert.<br />

5 // Sonst die Zeichenfolge im Zielwert ["ABC"]<br />

Man muss also immer aus dem Zusammenhang erkennen, ob mit dem Namen einer Referenzvariablen<br />

gerade der Wert oder der Zielwert (bzw. welcher Teil des Zielwertes) gemeint ist.<br />

Was ist gut bzw. schlecht an LongSpeicher20?<br />

Gut: Das Suchen geht sehr schnell.<br />

Schlecht: LongSpeicher20-Objekte "sind aus Beton" (ihre Größe kann nicht geändert werden)<br />

Die "Starrheit" von Reihungen veranlasst Programmierer manchmal, die Reihungen größer zu machen<br />

als sie (meistens) sein müssten. Auf Englisch bezeichnet man das als ein space leak (im Gegensatz zu einem<br />

memory leak).<br />

Projekt 3: LongSpeicher30<br />

Im Projekt 3 geht es um einen LongSpeicher, der "aus Gummi" ist statt "aus Beton": Ein leeres<br />

LongSpeicher30-Objekt belegt nur sehr wenig Speicher und sein Speicherbedarf wird größer (wenn<br />

man Komponenten einfügt) und wird kleiner (wenn man Komponenten löscht). Das ist ein manchmal<br />

sehr wichtiger Vorteil im Vergleich zu Reihungen.


S. 26, <strong>WS13</strong>/<strong>14</strong> SU 13. Di 19.11.13, 1. Block <strong>Beuth</strong>-<strong>Hochschule</strong><br />

Geschachtelte Klassen und innere Klassen<br />

Was ist neu an der Klasse LongSpeicher30? Was hat sie, was noch keine andere Klasse hatte, die<br />

bisher in PR1, PR2 und ALG behandelt wurde?<br />

Innerhalb der Klasse LongSpeicher30 wird eine Klasse (namens Knoten) vereinbart, und zwar als<br />

Klassen-Element (engl. static member).<br />

Def.: Eine Klasse ist eine geschachtelte Klasse (engl. nested class),<br />

wenn sie innerhalb einer anderen Klasse vereinbart wird.<br />

Def.: Eine Klasse ist eine innere Klasse (oder: Objekt-Klasse, engl. inner class),<br />

wenn sie geschachtelt, aber nicht static ist.<br />

Im Internet werden diese Begriffe an einigen Stellen nicht korrekt auseinandergehalten.<br />

Merke: Innere Klassen (Objekt-Klassen, analog zu Objekt-Attributen, Objekt-Methoden) sind ziemlich<br />

komplizierte Gebilde. Man sollte sie nur benutzen, wenn es unbedingt nötig ist. Statische geschachtelte<br />

Klassen (Klassen-Klassen, analog zu Klassen-Attributen, Klassen-Methoden) sind dagegen viel einfacher.<br />

Wann sollte man eine Klasse K2 als geschachtelte Klasse in K1 vereinbaren?<br />

Wenn K2 nur innerhalb von K1 benutzt werden soll. Man kann K2 dann private machen, so dass niemand<br />

"von außerhalb" darauf zugreifen kann. Dann kann man die geschachtelte Klasse jederzeit verändern<br />

(verbessern), ohne andere Programmierer wütend zu machen.<br />

Das Arbeitsblatt AB_Listen, S. 1, austeilen. Es enthält die Bojendarstellung eines leeren<br />

LongSpeicher30-Objekts. Wir entwickeln gemeinsam die fuegeEin-Methode:<br />

1 public boolean fuegeEin(long n) {<br />

2 // Fuegt n in diesen Speicher ein und liefert true<br />

3<br />

4 ADK.next = new Knoten(ADK.next, n);<br />

5 return true;<br />

6 }<br />

Dann in 2-er-Gruppen drei Komponenten in eine anfangs leere LongsSpeicher30-Sammlung einfügen<br />

(wie auf dem Arbeitsblatt angegeben). Dazu ist unbedingt ein Bleistift und ein Radiergummi erforderlich!<br />

Merke: Die Komponenten einer verketteten Liste sind lauter Variablen ohne (einfachen) Namen!<br />

Nach angemessen viel Zeit das Arbeitsblatt AB_Listen, S. 2, austeilen.<br />

Wie löscht man eine Komponente in einer verketteten Liste<br />

Angenommen, wir wollten aus der Sammlung lob (siehe ausgeteiltes Blatt) die Komponente mit data<br />

gleich 33 löschen. Dazu brauchen wir nur den Wert einer einzigen Variablen zu verändern.<br />

Welchen Wert hat diese Variable jetzt, und welchen Wert sollten wir ihr zuweisen?<br />

Sie hat den Wert und sollte den Wert bekommen.<br />

Welchen Wert sollte der Methodenaufruf vorgaenger(33) also liefern (damit wir damit den Wert<br />

durch ersetzen können?<br />

Der Methodenaufruf vorgaenger(33) sollte den Wert liefern (nicht den Wert !),<br />

denn der zeigt auf die Komponente, in der der Wert steht, den wir ändern wollen.<br />

Vor der Methode loesche schreiben wir jetzt die Methode vorgaenger.


<strong>Beuth</strong> <strong>Hochschule</strong> <strong>Stichworte</strong> <strong>Algorithmen</strong> <strong>WS13</strong>/<strong>14</strong>, S. 27<br />

Zur Entspannung: Hilberts Hotel<br />

Denken Sie sich ein Hotel mit unendlich vielen, nummerierten Zimmern: 1, 2, 3, ... . Alle Zimmer sind<br />

belegt. Dieses Hotel wurde nach dem Mathematiker David Hilbert (1862-1943) benannt.<br />

1. Wie kann man einen weiteren Gast unterbringen? (ZrNr := ZrNr + 1)<br />

2. Wie kann man hundert weitere Gäste unterbringen? (ZrNr := ZrNr + 100)<br />

3. Wie kann man unendlich viele weitere Gäste unterbringen? (ZrNr := ZrNr * 2)<br />

danach sind alle Zimmer mit ungeraden Nrn. (1, 3, 5, ...) frei.<br />

Block 2: Übung 4, Gruppe a: Die Wahrheit über Gleitpunktzahlen<br />

Welchen Wert hat das float-Literal 0.1F ?<br />

Welchen Wert das das double-Literal 0.1D (oder einfacher: 0.1)?<br />

Ist der Wert von 0.1F kleiner oder größer als der Wert von 0.1D ?


S. 28, <strong>WS13</strong>/<strong>14</strong> SU <strong>14</strong>. 19.11.13, Block 3 <strong>Beuth</strong>-<strong>Hochschule</strong><br />

SU <strong>14</strong>. 19.11.13, Block 3<br />

Projekt 5: Sammeln in einem binären Baum<br />

Def.: Binärer Baum<br />

Die Knoten bilden Ebenen, die wir (von oben nach unten) mit 0 beginnend nummerieren. Wie viele<br />

Knoten gibt es (höchstens) auf Ebene 0? Auf Ebene 1? Auf Ebene 2? Auf Ebene h? (2 h )<br />

Def.: Tiefe eines binären Baums<br />

Im Projekt 5 (Seite 17): Aufgabe-03 bis Aufgabe-06<br />

Def.: sortiert<br />

Im Projekt 5 (Seite 17): Aufgabe-01, Aufgabe-02<br />

Achtung: Zwei sortierte Reihungen mit gleichen Komponenten sehen genau gleich aus.<br />

Zwei sortierte Bäume mit gleichen Komponenten können sehr verschieden aussehen.<br />

Ein (kleines) Problem beim Implementieren von Bäumen in Java<br />

Eine Liste besteht aus Knoten-Objekten. Ein Baum besteht auch aus Knoten-Objekten, aber Baum-<br />

Knoten sind ein bisschen komplizierter als Listen-Knoten.<br />

Bäume kann man besonders elegant implementieren, wenn die Methoden fuegeEin und loesche die<br />

Werte (nicht die Zielwerte) bestimmter Knoten-Variablen ändern können.<br />

Allerdings gilt: Wenn man einer Java-Methode eine Variable als Parameter übergibt, kann die Methode<br />

den Wert der Original-Variablen nicht ändern (höchstens den Zielwert).<br />

Damit die Methoden fuegeEin und loesche trotzdem die Werte bestimmter Knoten-Variablen ändern<br />

können, verpacken wir jede solche Variable k einzeln in ein Objekt einer zusätzlichen Klasse (namens<br />

RefK wie "Referenz auf Knoten"). Übergibt man einer Methode eine RefK-Variable ref, dann<br />

kann die Methode (zwar nicht den Wert der Variablen ref aber) den Wert des Attributs ref.k verändern.<br />

In anderen Sprachen (z.B. in C++, C# und Ada) kommt man ohne die zusätzliche Klasse RefK aus (u.a.<br />

dadurch sind diese Sprachen aber auch deutlich komplizierter als Java und bieten mehr Möglichkeiten,<br />

Fehler zu machen).<br />

Ein leerer Baum besteht aus einem End-Dummy-Knoten EDK.<br />

Ein Anfangs-Dummy-Knoten ADK ist (in Java) nicht sinnvoll, weil bereits der Typ RefK das Löschen<br />

aller Knoten (auch des ersten) vereinheitlicht. In C++, C# und Ada ist ein ADK erwägenswert.<br />

Wichtiger Hinweis: Beim Bearbeiten von Projekt 5 sollen Sie das Implementieren der Methode<br />

loesche verschieben, bis die Methode in den Übungen besprochen oder im Internet veröffentlicht wurde<br />

(die Methode ist nicht ganz einfach). Implementieren Sie erst mal nur die anderen drei Methoden<br />

(refkR, fuegeEin, istDrin).<br />

Welcher Methode in Projekt 3 (oder 4) entsprechen die Methoden refk und refkR in Projekt 5?<br />

(Der Methode vorgaenger).<br />

Angenommen, wir haben vereinbart:<br />

LongSpeicher50 sp = new LongSpeicher50();<br />

Stellen Sie die Variablen sp.EDK und sp.AR als Bojen dar.


<strong>Beuth</strong> <strong>Hochschule</strong> <strong>Stichworte</strong> <strong>Algorithmen</strong> <strong>WS13</strong>/<strong>14</strong>, S. 29<br />

SU 15. 26.11.13, Block 1<br />

Heute schreiben wir den Test 4.<br />

Parameterübergabe in Java, kurze Zusammenfassung<br />

In Java gilt für das Übergeben von Parametern an Methoden und Konstruktoren:<br />

Den Wert einer Variablen kann man nur per Wert übergeben (aber nicht per Referenz)<br />

Den Zielwert einer Variablen kann man nur per Referenz übergeben (aber nicht per Wert)<br />

Statt "Zielwert" kann man auch "Objekt" sagen (denn in Java sind alle Zielwerte Objekte). In C++ kann<br />

man alle Werte und Objekte wahlweise per Wert oder per Referenz übergeben. Dadurch ist C++ mächtiger<br />

(und bietet damit auch mehr Möglichkeiten, Fehler zu machen).<br />

Was wir im Projekt 5 (binäre Bäume) gern machen würden (in Java aber nicht machen können):<br />

Angenommen, wir haben einen binären Baum mit z.B. 10 Knoten darin. Jeder Knoten enthält zwei Referenzvariablen<br />

lub und rub, die auf den linken bzw. rechten Unterbaum des Knotens zeigen. Insgesamt<br />

gibt es also 10 lub-Variablen und 10 rub-Variablen.<br />

Wir würden gern eine dieser 20 Variablen einer Methode haengeDran übergeben mit der Aufforderung:<br />

"Lass diese (lub- oder rub-) Variable auf einen neuen Knoten zeigen". Dazu müsste die Methode<br />

haengeDran den Wert der übergebenen Variablen ändern. Das könnte sie aber nur, wenn sie die<br />

Referenz der Variablen hätte. Die können wir der Methode haengeDran aber nicht übergeben.<br />

In solchen Fällen kann man sich in Java mit einer zusätzlichen Klasse behelfen. Im Projekt 5 ist diese<br />

Klasse (als geschachtelte Klasse) vorgegeben und heißt RefK. Ihre Vereinbarung ist nur 4 Zeilen lang.<br />

Noch mal eine Schrittfunktion<br />

Wie konnte man im Test 3 (oder 3a) die maximal mögliche Punktzahl bekommen? Hier noch mal ein<br />

Beispiel, wie man vorgehen sollte.<br />

1 static public void alg25(int n) {<br />

2 for (int i=1; i


S. 30, <strong>WS13</strong>/<strong>14</strong> SU 15. 26.11.13, Block 1 <strong>Beuth</strong>-<strong>Hochschule</strong><br />

Knoten in einem binären Baum löschen<br />

Beim Löschen von Knoten gibt es 4 verschiedene Fälle. Davon ist einer ganz einfach, zwei weitere sind<br />

einfach, und nur der vierte Fall ist ein bisschen komplizierter.<br />

In den folgenden Beispielen soll immer der Knoten mit dem Schlüssel 50 gelöscht werden.<br />

Fall 1: Beide Unterbäume des zu löschenden Knotens sind leer (ganz einfach)<br />

Fall 2: Der linke Unterbaum des zu löschenden Knoten ist leer<br />

Fall 3: Der rechte Unterbaum des zu löschenden Knoten ist leer<br />

10<br />

10<br />

10<br />

10<br />

50<br />

50<br />

50<br />

50<br />

70<br />

70<br />

30<br />

30<br />

Fall 2<br />

Fall 3<br />

Fall 4: Beide Unterbäume des zu löschenden Knotens L sind nicht leer<br />

10<br />

10<br />

50<br />

45<br />

30<br />

70<br />

30<br />

70<br />

...<br />

38<br />

1. Daten<br />

kopieren<br />

...<br />

38<br />

2. Knoten<br />

löschen<br />

45<br />

45<br />

40<br />

40<br />

Fall 4<br />

Schritt 4.1.: Wir gehen zum linken Unterbaum des zu löschenden Knotens (der beginnt hier mit 30)<br />

Schritt 4.2.: In diesem Unterbaum suchen wir den Knoten MAX mit dem größten Schlüssel (hier: 45)<br />

Der rechte Unterbaum von MAX ist sicherlich leer (sonst würden darin ja Schlüssel stehen, die größer<br />

sind als der Schlüssel von MAX. Aber dann wäre MAX nicht MAX).<br />

Schritt 4.3.: Wir kopieren die Daten aus MAX in den zu löschenden Knoten (in der Graphik: 1.)<br />

Schritt 4.4.: Wir löschen den Knoten MAX (in der Graphik: 2.)<br />

Anmerkung: Das Löschen von MAX ist ein Fall 3 oder ein Fall 1.<br />

Schreiben Sie jetzt (für das Projekt 5, LongSpeier50, die Methode loesche)<br />

Block 2: Übung 4, Gruppe b: Die Wahrheit über Gleitpunktzahlen<br />

Welchen Wert hat das float-Literal 0.1F ?<br />

Welchen Wert das das double-Literal 0.1D (oder einfacher: 0.1)?<br />

Ist der Wert von 0.1F kleiner oder größer als der Wert von 0.1D ?


<strong>Beuth</strong> <strong>Hochschule</strong> <strong>Stichworte</strong> <strong>Algorithmen</strong> <strong>WS13</strong>/<strong>14</strong>, S. 31<br />

SU 16. 26.11. 13, Block 3<br />

Ein Blatt mit der Bojendarstellung einer LongSpeicher50-Variablen s austeilen.Die Variable s zeigt<br />

auf einen Binärbaum mit 11 Knoten (und einen End-Dummy-Knoten). Die Knoten enthalten folgende<br />

Schlüssel: 45, 27, 68, 18, 35, 57, 11, 23, 32, 52, 61.<br />

Um einen bestimmten Knoten zu löschen, müssen die Werte bestimmter Variablen durch andere Werte<br />

ersetzt werden. Als Lösung der folgenden Aufgabe sollen nur diese Werte angegeben werden, in folgender<br />

Form: NeuerWert → AlterWert.<br />

Es soll jeweils nur ein Knoten aus dem Baum mit 11 Knoten gelöscht werden. Beim Löschen eines Knotens<br />

sollen alle zuvor gelöschten Knoten "wieder da sein".<br />

Aufgabe (mit Lösungen): Löschen Sie die Knoten mit den folgenden Schlüsseln:<br />

Nr Schlüssel Lösung<br />

1. 61 (600 -> 400)<br />

2. 32 (600 -> 370)<br />

3. 35 (370 -> 240)<br />

4. 68 (250 -> 180)<br />

5. 45 ( 35 -> 45, 370 -> 240)<br />

6. 27 ( 23 -> 27, 600 -> 360<br />

7. 57 ( 52 -> 57, 600 -> 390)<br />

Zur Entspannung:Ein Blatt Papier 50 Mal halbieren und stapeln<br />

Stellen Sie sich vor: Wir haben ein großes Blatt Papier (z.B. eine Blatt der Zeitung "Die Zeit"). Wir reißen<br />

oder schneiden das Papier in zwei Hälften und legen die beiden Hälften übereinander. Dann reißen<br />

oder schneiden wir diesen kleinen Stapel ebenso in zwei Hälften und legen sie übereinander, dann reißen<br />

oder schneiden wir diesen Stapel ebenso in zwei Hälften etc. etc. Insgesamt wiederholen wir diesen<br />

Vorgang 50 Mal. Wie hoch ist der Papierstapel am Ende ungefähr?<br />

Tabelle mit 2-er und 10-er-Potenzen, die sich ungefähr entsprechen:<br />

2 10 2 20 2 30 2 40 2 50 2 60<br />

10 3 10 6 10 9 10 12 10 15 10 18<br />

1 Tausend 1 Million 1 Milliarde 1 Billion 1Billiarde 1 Trillion<br />

2 50 Schichten Zeitungspapier ist gleich<br />

10 15 Schichten Zeitungspapier (siehe obige Tabelle).<br />

Angenommen, 10 Schichten sind 1 mm dick. Dann gilt:<br />

1 mm 10 Schichten<br />

1 m 10 000 Schichten<br />

1 km 10 000 000 Schichten (d.h. 10 7 Schichten)<br />

10 15 / 10 7 ist gleich 10 8 gleich 100 Millionen km<br />

Wenn es möglich wäre, ein Blatt Papier 50 Mal zu halbieren und zu stapeln, wäre der Stapel mindestens<br />

100 Millionen km dick (beim letzten Halbieren hätte man also einen Stapel von mindestens 50 Millionen<br />

km Dicke halbieren müssen).


S. 32, <strong>WS13</strong>/<strong>14</strong> SU 16. 26.11. 13, Block 3 <strong>Beuth</strong>-<strong>Hochschule</strong><br />

Zufall in <strong>Algorithmen</strong><br />

Viele <strong>Algorithmen</strong> sind präzise Anweisungen zur Lösung bestimmter Probleme, und die Ergebnisse dieser<br />

<strong>Algorithmen</strong> sind exakt festgelegt (z.B. wenn man Reihungen sortiert oder wenn man zwei Zahlen<br />

mit Papier und Bleistift multipliziert etc.).<br />

Merkwürdigerweise gibt es aber auch eine ganze Reihe von <strong>Algorithmen</strong>, in denen der Zufall eine wichtige<br />

und nützliche Rolle spielt.<br />

Beispiel: Die Kreiszahl pi besteht aus einer unendlichen, nicht-periodischen Folge von Ziffern. Man<br />

kann sie deshalb nicht vollständig berechnen. Aber man kann im Prinzip beliebig lange Anfangsstücke<br />

der unendlichen Ziffernfolge berechnen. Dazu gibt es verschiedene, ziemlich komplizierte <strong>Algorithmen</strong>.<br />

Man kann die ersten Ziffern von pi aber auch ziemlich einfach berechnen, indem man Zufallszahlen benutzt.<br />

Zufallszahlen in Java:<br />

Klassenmethode Math.random: Liefert einen double-Wert aus dem Intervall [0.0, 1.0), jeden<br />

Wert mit der gleichen Wahrscheinlichkeit (gleichverteilt, engl. uniformly distributed).<br />

Jedes Objekt der Klasse Random enthält 8 öffentliche Objektmethoden, die zufällige Werte verschiedener<br />

Typen (boolean, byte[], float, double, int, long) liefern. Die meisten Methoden liefern<br />

gleichverteilte Werte, d.h. jeder mögliche Wert "hat die gleiche Chance dranzukommen". Eine Methode<br />

liefert Gauß-verteilte (normalverteilte, engl. Gaussian or normally distributed) double-Werte (die Zahl<br />

0.0 hat die größte Chance, je weiter eine Zahl von 0.0 entfernt ist, desto geringer ist ihre Chance. Die<br />

Chance, dass irgendeine Zahl drankommt, die außerhalb des Intervalls [-3.0, +3.0] liegt, ist nur<br />

0.27 % (also häufig vernachlässigbar).<br />

Wichtiger Unterschied: Reproduzierbare bzw. nicht-reproduzierbare Zufallszahlen<br />

Wofür nicht-reproduzierbare Zufallszahlen? Glücksspiele, Kryptografie, ...<br />

Wofür reproduzierbare Zufallszahlen? Automatische Erstellung von Testdaten, Simulationen, ...<br />

Erzeugung von Random-Objekten:<br />

1 Random rob01 = new Random(123L); // Fuer reproduzierbaren Zufall<br />

2 Random rob02 = new Random(); // Fuer nicht-reproduzierbaren Zufall<br />

In Zeile 1 wird als Keim (engl. seed) der long-Wert 123 angegeben. Dieser Keim macht die später gelieferten<br />

Zufallszahlen reproduzierbar. In Zeile 2 nimmt der Ausführer die aktuelle Uhrzeit (in Millisekunden)<br />

als Keim. Dadurch wird es sehr schwer, die Zufallszahlen zu reproduzieren.<br />

Aus dem Anfangskommentar eines Programms namens ZufallPi03.java:<br />

/* ------------------------------------------------------------------------<br />

Die Kreiszahl pi mit Hilfe von Zufallszahlen berechnen. Dazu laesst man<br />

in ein Quadrat mit der Kantenlaenge 1.0 an zufaellig gewaehlten Stellen<br />

(x, y) "Regentropfen" fallen und zaehlt, wie viele davon in einen (dem<br />

Quadrat einbeschriebenen) Viertelkreis mit Radius 1.0 fallen.<br />

imQuadrat Anzahl der Tropfen, die man in das Quadrat fallen laesst<br />

imViertelkreis Anzahl der Tropfen, die davon in den Viertelkreis fallen<br />

fQ Flaeche des Quadrats (gleich 1.0)<br />

fV<br />

Flaeche des Viertelkreises (gleich pi/4.0)<br />

Die Anzahl der Tropfen, die auf eine bestimmte Flaeche fallen, wird<br />

ungefaehr proportional zur Groesse der Flaeche sein. Also gilt:<br />

fV / fQ = imViertelkreis / imQuadrat<br />

pi / 4.0 / 1.0 = imViertelkreis / imQuadrat<br />

pi = imViertelkreis / imQuadrat * 4.0<br />

Die letzte Gleichung zeigt, wie man aus den Tropfen-Zahlen imViertelkreis<br />

und imQuadrat eine Naeherung Pi fuer die Kreiszahl pi berechnen kann.


<strong>Beuth</strong> <strong>Hochschule</strong> <strong>Stichworte</strong> <strong>Algorithmen</strong> <strong>WS13</strong>/<strong>14</strong>, S. 33<br />

Hinweis: pi bezeichnet hier die "echte Kreiszahl", PI ein Konstante<br />

in der Klasse Math und Pi die hier berechneten Naeherungswerte fuer pi.<br />

...<br />

------------------------------------------------------------------------ */<br />

Schreiben Sie ein Programm, welches pi näherungsweise berechnet wie oben skizziert.<br />

Eine wichtige Methode aus dem Programm ZufallPi03.java:<br />

1 static void zufaellig(int anzahlTropfen) {<br />

2 // Berechnet Pi mit Tropfen, die an "zufaellige Stellen" fallen.<br />

3<br />

4 Random rand = new Random(123); // Keim (engl. seed) 123<br />

5 int imViertelkreis = 0;<br />

6<br />

7 for (int i=1; i


S. 34, <strong>WS13</strong>/<strong>14</strong> SU 17. 03.12.13, Block 1 <strong>Beuth</strong>-<strong>Hochschule</strong><br />

SU 17. 03.12.13, Block 1<br />

Dies ist der letzte Block 1 in diesem Semester.<br />

Ab dem 10.12.13 beginnen wir mit der Ü im Block 2 (und haben danach einen SU im Block 3).<br />

Zufallszahlen in Java (Fortsetzung und Ende)<br />

Jedes Random-Objekt enthält 8 Methoden, die zufällige Werte liefern:<br />

boolean nextBoolean() // Gleichverteilt aus {false, true}<br />

void nextBytes(byte[] br)<br />

double nextDouble() // Gleichverteilt aus [0.0D, 1.0D)<br />

float nextFloat() // Gleichverteilt aus [0.0F, 1.0F)<br />

double nextGaussian() // Normalverteilt, Mittelwert 0.0D, Standardabweich.1.0D<br />

int nextInt() // Gleichverteilt aus [MIN_VALUE, MAX_VALUE]<br />

int nextInt(int n) // Gleichverteilt aus [0, n)<br />

long nextLong() // Gleichverteilt aus [MIN_VALUE, MAX_VALUE]<br />

Kurz besprechen, was normalverteilt (oder Gauß-verteilt, engl. normally distributed or Gaussian distributed)<br />

heißt.<br />

Aus Google "normalverteilung"<br />

In der Skizze ist x der Mittelwert und s die Standardabweichung. Die Prozentzahlen geben die Wahrscheinlichkeiten<br />

an, mit der man einen Wert aus einem bestimmten Bereich der x-Achse bekommt. Die<br />

Wahrscheinlichkeit, einen Wert zu bekommen, der nicht im Intervall [x - 3s, x + 3s] liegt, beträgt<br />

nur 0,3 %.<br />

Das Papier HashTabellen.pdf (5 Seiten) besprechen<br />

Suchen geht noch schneller als in einer sortierten Reihung oder in einem sortierten binären Baum. Dabei<br />

spielt in einem bestimmten Sinn Zufall eine wichtige Rolle.<br />

Def.: Eine Hash-Tabelle ist eine Reihung von Listen.<br />

Def.: Eine Hash-Funktion bildet Schlüssel auf die Indizes einer Hash-Tabelle ab.<br />

Anmerkung: Manchmal bildet eine Hash-Funktion jeden Schlüssel einfach nur auf eine ganze Zahl z<br />

ab. Der Ausdruck Math.abs(z) % ht.length liefert dann einen Index für die Hash-Tabelle ht.


<strong>Beuth</strong> <strong>Hochschule</strong> <strong>Stichworte</strong> <strong>Algorithmen</strong> <strong>WS13</strong>/<strong>14</strong>, S. 35<br />

Ein konkretes Beispiel:<br />

Wir haben eine Hash-Tabelle ht der Länge 10 (ht enthält also 10 Listen ht[0] bis ht[9]).<br />

In diese Hash-Tabelle wollen wir <strong>14</strong> Schlüssel einfügen: "Ali", "Babsy", ..., "Alf".<br />

Das machen wir mit verschiedenen Hash-Funktionen (um uns klar zu machen, "was eine Hash-Funktion<br />

ist und macht" und was eine gute Hash-Funktion von einer schlechten unterscheidet).<br />

hash01: Eine der schlechtesten Hash-Funktionen die es gibt<br />

Wenn wir nach dem Einfügen jeden eingefügten Schlüssel einmal suchen, brauchen wir dafür insgesamt<br />

105 Liste-Suchschritte: 1 für "Ali", 2 für "Babsy", 3 für "Arno", ..., <strong>14</strong> für "Alf").<br />

hash02: Deutlich besser als hash01, aber noch kein Gewinner der Champions League<br />

65 Listen-Suchschritte<br />

hash03: Noch besser als hash02, mit Mod-Operator %<br />

45 Listen-Suchschritte<br />

Eine Hash-Funktion ist nicht "absolut gut oder schlecht", sondern "gut oder schlecht für bestimmte<br />

Schlüssel". Darum haben wir im Beispiel auch <strong>14</strong> Schlüssel festgelegt.<br />

hash04: für unsere Schlüssel noch besser als hash03, schon fast praxisnah<br />

24 Listen-Suchschritte<br />

hash05: noch besser als hash04, aber ...<br />

19 Listen-Suchschritte<br />

Was ist bei hash05 schlechter als bei hash04?<br />

(Die Zeitkomplexität von hash04 ist O(1), die von hash05 ist O(s.size()).<br />

In Java enthält jedes Objekt eine parameterlose Funktion int hashCode(). Die berücksichtigt natürlich<br />

nicht die Eigenschaften bestimmter Schlüssel, ist aber in vielen Fällen eine brauchbare Hash-Funktion.<br />

Natürlich muss man aus ihrem Ergebnis noch einen Index für die Hash-Tabelle ht berechnen:<br />

Math.abs(ob.hashCode()) % ht.length<br />

Mit hashCode:<br />

22 Listen-Suchschritte<br />

Was liefert die Methode hashCode()? (S. 5 des Papiers)<br />

Zeile 1 und 2: Bei den meisten Objekten gilt:<br />

Verschiedene Objekte haben verschiedene hashCode()-Ergebnisse<br />

Zeile 3 bis 6: Bei String-Objekten hängt der hashCode() nur vom "Inhalt" ab.<br />

Zeile 7 bis 8: Bei StringBuilder-Objekten ist es wie bei bei den meisten Objekten (siehe oben)<br />

Zeile 9 bis 16: Ähnliches wie für String-Objekte gilt auch<br />

für Hüllobjekte (d.h. Objekte einer Hüllklasse)<br />

Zeile 17 bis 18: Vorsicht: hashCode() liefert auch negative Werte!<br />

Aufgabe: Was gilt für die hashCode()-Ergebnisse von BigInteger-Objekten?<br />

Und von BigDecimal-Objekten?<br />

Wichtige Eigenschaften von Hash-Tabellen<br />

Bei einer guten Hash-Tabelle (mit guter Hash-Funktion) haben alle wichtigen Methoden (fuegeEin,<br />

istDrin und loesche) eine Zeitkomplexität von O(1)<br />

d.h. die Ausführungszeiten dieser Methoden ist unabhängig von der Anzahl der Objekte in der Hash-Tabelle.


S. 36, <strong>WS13</strong>/<strong>14</strong> SU 17. 03.12.13, Block 1 <strong>Beuth</strong>-<strong>Hochschule</strong><br />

Vergleich von binären Bäumen und Hash-Tabellen<br />

Bäume sind langsamer, lassen sich aber leicht sortiert ausgeben.<br />

Hash-Tabellen sind schneller, müssen aber "durcheinander" (nicht-sortiert) sein.<br />

Zur Entspannung: Charles Babbage (1791-1871)<br />

Forschte auf verschiedenen Gebieten. Unternahm mehrere Versuche, mechanische Rechenmaschinen zu<br />

bauen. Keine davon wurde funktionstüchtig, aber seine Pläne und Überlegungen dazu waren wichtige<br />

Stationen auf dem Weg zu Computern.<br />

1823 Difference Engine no. 1: In die Entwicklung floßen 17.000 Pfund der briitschen Regierung, was<br />

etwa dem Preis von zwei Schlachtschiffen entsprach. Dann brach die Regierung das Projekt ab.<br />

1833 Analytical Engine: Die sollte sogar schon programmierbar werden und Lochkarten lesen. 2012 begann<br />

ein Projekt mit dem Ziel, diese Maschine zu bauen, siehe http://plan28.org/.<br />

1847 Difference Engine no. 2: Verbesserte Variante der Difference Engine no. 1. Die wurde 1989-191<br />

im Science Museum in London genau nach den Plänen von Babbage gebaut und funktioniert.<br />

Ada Byron, Lady Lovelace (1815-1852), Tochter des berühmten Dichters Lord Byron, arbeitete mit an<br />

der Analytical Engine und gilt seitdem als erste Programmiererin. Nach ihr ist die Sprache Ada benannt<br />

(ANSI/MIL-STD-1815, nach ihrem Geburtsjahr).<br />

Weitere Erfindungen von Charles Babbage: Kuhfänger (für Lokomotiven, z. B. im Wilden Westen). Er<br />

knackte als erster eine Vignére-Verschlüsselung (die vorher als sicher galt). Schrieb das Buch Economy<br />

of machinery and manufactures, eine Analyse des Frühkapitalismus und wichtige Quelle für Karl Marx.<br />

Block 2: Übung 5, Gruppe a:<br />

In Eclipse: Suchen und Ersetzen mit regulären Ausdrücken und Fangmustern<br />

Dazu wird ein Blatt mit 3 Aufgaben ausgeteilt.


<strong>Beuth</strong> <strong>Hochschule</strong> <strong>Stichworte</strong> <strong>Algorithmen</strong> <strong>WS13</strong>/<strong>14</strong>, S. 37<br />

SU 18. 03.12.13, Block 3<br />

Projekt 7: Maximale Teilsumme<br />

Ab S. 20 im Papier Projekte.pdf<br />

1. Ein konkretes Beispiel (S. 20)<br />

Aufgabe-01 (Lösung: 8, von Tag 2 bis 5, oder von Tag 8 bis 9)<br />

2. Grundbegriffe:<br />

Reihung, Teilreihung, Summe einer Reihung, Teilsumme einer Reihung<br />

3. Aufgaben<br />

Die Aufgabe-02 bis Aufgabe-10 bearbeiten<br />

Besonders wichtig: Aufgabe-08 (Methode mts01 mit 3 geschachtelten for-Schleifen)


S. 38, <strong>WS13</strong>/<strong>14</strong> SU 19. 10.12.13, Block 3 <strong>Beuth</strong>-<strong>Hochschule</strong><br />

SU 19. 10.12.13, Block 3<br />

Heute schreiben wir den Test 5.<br />

Was ist für den Algorithmus mts01 ein Schritt?<br />

Jede Addition einer Komponenten r[i] zu einer summe ist ein Schritt (denn alle "größeren Befehle"<br />

sind Schleifen, deren Ausführungszeiten von der Problemgröße N gleich r.length abhängen).<br />

Konstruktion einer Schrittfunktion für den Algorithmus mts01<br />

Herleitung einer Schrittfunktion: Sei N die Länge der Reihung, auf die mts01 angewendet wird. L bezeichnet<br />

die Länge einer Teilreihung (L nimmt die Werte 1 bis N an) und AnzL bezeichnet die Anzahl<br />

der Teilreihungen der Länge L.<br />

Es gilt AnzL ist gleich N-(L-1).<br />

Die Bearbeitung einer Teilreihung der Länge L kostet L Schritte (für jede Komponente eine Addition).<br />

Die Bearbeitung aller Teilreihungen der Länge L kostet also L * (N-(L-1)) Schritte.<br />

SchritteInsgesamt = ∑ L ∗ AnzL=<br />

N<br />

∑<br />

L=1<br />

N<br />

∑<br />

L=1<br />

N<br />

∑<br />

L=1<br />

N<br />

∑<br />

L=1<br />

L∗(N−(L−1)) =<br />

L∗(N+1−L) =<br />

L∗N + L − L 2 =<br />

N<br />

L∗N + ∑<br />

L=1<br />

N<br />

L − ∑ L 2 =<br />

L=1<br />

N<br />

L=1<br />

N 1 2 ∗(N2 +N) + 1 2 ∗(N2 +N) − 1 6 ∗N∗(N+1)∗(2∗N+1) =<br />

1<br />

6 ∗N3 + 1 2 ∗N2 + 1 3 ∗N<br />

Die Zeitkomplexität von mts01 ist also O(N 3 ).


<strong>Beuth</strong> <strong>Hochschule</strong> <strong>Stichworte</strong> <strong>Algorithmen</strong> <strong>WS13</strong>/<strong>14</strong>, S. 39<br />

Idee zur Beschleunigung von mts01:<br />

Können wir mit weniger Additionen auskommen, wenn wir uns die Additionsergebnisse "merken" (d.h.<br />

in einer geeigneten Reihung speichern)?<br />

Eine Teilreihung einer Reihung kann man auf verschiedene Weisen beschreiben, z.B. durch ihren Anfangs-Index<br />

und ihren End-Index. Manchmal ist es günstiger, die Beschreibung durch ihren Anfangs-Index<br />

und ihre Länge zu verwenden.<br />

Wir speichern die Summen der einzelnen Teilreihungen in einer zweistufigen Reihung teilSumme des<br />

Typs int[][]. In die Komponente teilSumme[von, len] schreiben wir die Summe der Teilreihung<br />

mit dem Anfangs-Index von und der Länge len+1.<br />

Lösen Sie dazu (im Papier Projekte.pdf auf S. 39) die<br />

Aufgabe-11: Sei r1 gleich [+3, -2, +1, +1]. Tragen Sie die entsprechenden Teilsummen in die<br />

leeren Kästchen der rechten Darstellung der 2-stufigen Reihung teilSumme ein.<br />

0 1 2 3 0 1 2 3<br />

0<br />

1<br />

2<br />

3<br />

von 0 len 1 von 0 len 2 von 0 len3 von 0 len4<br />

von 1 len 1 von 1 len 2 von 1 len 3<br />

von 2 len 1 von 2 len 2<br />

von 3 len 1<br />

0<br />

1<br />

2<br />

3<br />

+3 +1 +2 +3<br />

-2 -1 0<br />

+1 +2<br />

+1<br />

Bevor Sie die Aufgabe-12 bearbeiten: Wie sieht die Reihung teilSumme aus, wenn der Ausführer sie<br />

gerade erzeugt hat?<br />

Lösen Sie jetzt die Aufgabe-12, d.h. schreiben Sie die Methode mts02.<br />

Zur Entspannung: Charistian Motgenstern (1871 - 19<strong>14</strong>)<br />

Der Werwolf<br />

"Ein Werwolf eines Nachts entwich, .... "<br />

Block 2: Übung 5, Gruppe b:<br />

In Eclipse: Suchen und Ersetzen mit regulären Ausdrücken und Fangmustern<br />

Dazu wird ein Blatt mit 3 Aufgaben ausgeteilt.


S. 40, <strong>WS13</strong>/<strong>14</strong> SU 20. 17.12.13, 3. Block <strong>Beuth</strong>-<strong>Hochschule</strong><br />

SU 20. 17.12.13, 3. Block<br />

Über Ausführungen von Schleifen reden (richtig und falsch)<br />

In der Datei Projekte.txt, ganz am Ende: SchleifenReden.java<br />

Beantworten Sie die Fragen, die am Ende dieser Datei stehen.<br />

Projekt 7: Fortsetzung<br />

4. Vorgabe Testprogramm MaxTeilsummeJut<br />

Nur kurz auf die Existenz des Testprogramms hinweisen<br />

5. mts02 programmieren (haben wir im 19. SU gemacht)<br />

6. "Teile und herrsche"<br />

Aufgabe-13: Warum kann man "Teile und herrsche" nicht (einfach so) auf<br />

das Teilsummen-Problem anwenden?<br />

Weitere Grudbegriffe: rechte Randfolge, rechtes Randmaximum<br />

Aufgabe-<strong>14</strong> bis Aufgabe-16<br />

Aufgabe-17: Methode rechtesRandMax(int[] r, int links, int rechts)<br />

Aufgabe-19: Die Methode mts03<br />

7. Geht es noch besser? (Ja)<br />

Aufgabe-20: Die Methode mts04<br />

Klausur: Di 04.02.20<strong>14</strong>, 18.00 - 19.30 Uhr, Raum D209<br />

Zur Entspannung: Englische Vokabeln: boot, bootstrap<br />

Ein boot ist ein hoher Schuh oder Schnürstiefel, ein bootstrap ein Schnürsenkel für einen Schnürstiefel.<br />

Ein bootstrap gilt als simples Werkzeug, welches immer zur Hand ist und mit dem man sich andere<br />

Werkzeuge "heranziehen kann", z. B. so: Eine Gruppe von Pfadfindern (natürlich alle in Schnürstiefeln)<br />

will ein schweres Stahlkabel über einer Felsspalte anbringen (z.B. als "Rückgrat" einer Hängebrücke).<br />

Dazu knüpfen sie zuerst ihre bootstraps zusammen und ziehen damit ein dünnes Seil über die Felsspalte.<br />

Mit dem dünnen Seil ziehen sie ein dickeres Seil über die Felsspalte und mit dem dickeren Seil<br />

schliesslich das Stahlkabel.<br />

Beim Booten eines Rechners liest der Prozessor zuerst von einem bestimmten Gerät (Platte, CD/DVD,<br />

Stick, ...) einen einzigen Datenblock (z. B. 512 Byte) und springt dann zum ersten Byte dieses Blocks.<br />

Der Block sollte ein kleines Ladeprogramm, enthalten, welches ein größeres Ladeprogramm (z. B. ein<br />

paar Tausend Bytes) vom selben Gerät liest und zum Anfang dieses Ladeprogramms springt. Das größere<br />

Ladeprogramm lädt dann wichtige Teile des Betriebssystems (ein paar Megabyte) und springt an eine<br />

Stelle in diesem Betriebssystem.<br />

Block 2: Übung 6, Gruppe a<br />

Einfache Java-Programme ohne Eclipse compilieren und ausführen


<strong>Beuth</strong> <strong>Hochschule</strong> <strong>Stichworte</strong> <strong>Algorithmen</strong> <strong>WS13</strong>/<strong>14</strong>, S. 41<br />

SU 21. 07.01.20<strong>14</strong><br />

Heute schreiben wir den Test 5.<br />

Graphen<br />

Viele verschiedene Sachverhalte lassen sich beschreiben als eine Menge von Dingen, von denen einige<br />

durch eine Relation miteinander verbunden sind. Beispiele:<br />

Dinge<br />

Orte<br />

Länder<br />

Netzseiten<br />

Personen<br />

Relation<br />

2 Orte sind direkt verbunden durch eine Straße (oder Fahrradwege oder Eisenbahnschienen,<br />

oder durch schiffbares Wasser, oder durch regelmäßige Flüge oder ...)<br />

2 Länder haben eine gemeinsame Grenze<br />

Eine Seite enthält einen Link zu einer anderen Seite<br />

Eine Person ist Vater bzw. Mutter einer anderen Person<br />

Personen Eine Person ist in einem sozialen Netzwerk ein Freund (oder ein Follower oder ...)<br />

einer anderen Person<br />

Wenn man nur weiß, welcher Ort mit welchen anderen durch eine direkte Straße verbunden ist, kann<br />

man herausfinden, welche Orte indirekt miteinander verbunden sind (d.h. über welche Orte man fahren<br />

muss/kann, um von A nach B zu kommen).<br />

Wenn man nur weiß, wer Mutter/Vater von wem ist, kann man alle anderen Verwandtschaftsbeziehungen<br />

(Großmutter/Großvater, Enkel/Enkelin, in-direkter-Linie-verwandt, versorgungspflichtig, erbberechtigt<br />

etc.) ausrechnen.<br />

Die hier skizzierten Sachverhalte kann man durch Graphen darstellen. Da es viele verschiedene solche<br />

Sachverhalte gibt, gibt es auch viele Arten von Graphen. Für alle gilt:<br />

Def.: Ein Graph besteht aus einer Menge von Knoten und einer Menge von Kanten.<br />

Jede Kante verbindet zwei (nicht notwendig verschiedene) Knoten.<br />

Eigenschaften von Graphen 1<br />

- gerichtet/ungerichtet<br />

- kantengewichtet<br />

- knotengewichtet<br />

- mit Schleifen,<br />

- mit Mehrfachkanten<br />

- zusammenhängend/nicht-zusammenhängend<br />

Ein Graph-Problem und eine Lösung von E. W. Dijkstra<br />

Angenommen, wir haben einen kantengewichteten, ungerichteten oder gerichteten Graphen<br />

ohne Mehrfachkanten. Die Kantengewichte sind alle nicht-negativ.<br />

Ein Gewicht 3 an der Kante zwischen zwei Knoten v1 und v2 kann z.B. bedeuten:<br />

- von v1 nach v2 sind es 3 km<br />

- von v1 nach v2 braucht man 3 Stunden<br />

- von v1 nach v2 kostet eine Fahrkarte 3 Euro<br />

etc.<br />

Wir wüssten gern:<br />

Wie lang sind die kürzesten Wege von einem bestimmten Knoten zu jedem anderen Knoten?


S. 42, <strong>WS13</strong>/<strong>14</strong> SU 21. 07.01.20<strong>14</strong> <strong>Beuth</strong>-<strong>Hochschule</strong><br />

Anmerkung: Statt "Von v1 nach v2 gibt es keinen Weg" sagen Mathematiker (mit gutem Grund) lieber:<br />

"Der Weg von v1 nach v2 ist unendlich lang". Damit ist jeder "richtige Weg" kürzer als "kein Weg".<br />

Interpretation von kantengewichteten Graphen<br />

Folgende kantengewichtete Graphen erscheinen einigen Menschen auf den ersten Blick unlogisch. Können<br />

Sie eine logische Erklärung, eine konkrete Interpretation, finden?<br />

A<br />

1<br />

B<br />

10 1<br />

C<br />

D<br />

10<br />

1<br />

E<br />

Graph G1<br />

Graph G2<br />

Wie kann es sein, dass (im ungerichteten Graph G1) der direkte Weg von A nach C viel länger ist, als<br />

der indirekte Weg über B? Und wie kann es sein, dass (im gerichteten Graph G2) der Weg von D nach E<br />

viel länger ist als der "umgekehrte" Weg von E nach D?<br />

Edsger Wybe Dijkstra, 1930 - 2002, Turing Award 1972<br />

Das Arbeitsblatt für den SU 21 austeilen und gemeinsam den Dijkstra-Algorithmus ausführen indem<br />

wir die Tabelle ausfüllen.<br />

Zur Entspannung: Der EPR-Effekt<br />

Albert Einstein mochte die Quantenmechanik nicht. Er dachte sich mehrere Gedankenexperimente aus,<br />

die zeigen sollten, dass sie fehlerhaft ist oder zumindest "keine vollständige Beschreibung der Natur"<br />

liefert. Nils Bohr vertrat die Quantenmechanik und fühlte sich zuständig für ihre Verteidigung. Mehrmals<br />

gelang es ihm, in einem Gedankenexperiment von Einstein einen subtilen Fehler zu entdecken und<br />

die Argumente von Einstein dadurch zu entkräften. Bei einem der Gedankenexperimente gelang ihm das<br />

aber nicht.<br />

Einstein mochte die Quantenmechanik nicht, kannte sie aber offenbar so genau, dass er auch einige ihrer<br />

entfernten Konsequenzen erkennen konnte. Den Effekt, der heute als EPR-Effekt bezeichnet wird (nach<br />

Einstein, seinem Physiker-Kollegen Podolski und einem Studenten Rosen) ist eine Konsequenz der<br />

Quantenmechanik, die Einstein "so unsinnig und unglaubhaft" vorkam, dass er sie als Argument gegen<br />

die Quantenmechanik veröffentlichte. Inzwischen hat man diesen merkwürdigen Effekt experimentell<br />

nachgewiesen und benutzt ihn zur abhörsicheren Übertragung von Daten.<br />

Der EPR-Effekt wird im Film "Only Lovers Left Alive" (2013) von Jim Jarmusch mehrfach erwähnt.<br />

Andere Filme von Jim Jarmusch<br />

1984 Stranger Than Paradise<br />

1986 Down By Law<br />

1989 Mystery Train<br />

1995 Night On Earth


<strong>Beuth</strong> <strong>Hochschule</strong> <strong>Stichworte</strong> <strong>Algorithmen</strong> <strong>WS13</strong>/<strong>14</strong>, S. 43<br />

Arbeitsblatt für den SU 21<br />

Algorithmus von Dijkstra<br />

Mit dem Dijkstra Algorithmus kann man<br />

in einem (ungerichteten oder gerichteten) Graphen mit<br />

nicht-negativen Kantengewichten und<br />

ohne Mehrfachkanten<br />

kürzeste Wege von einem bestimmten Knoten zu jedem anderen Knoten berechnen.<br />

Beispiel-01: Berechnet werden sollen kürzeste Wege vom Knoten A zu den Knoten B, C, D, E, F.<br />

B<br />

4 1<br />

3<br />

A C D<br />

2<br />

4<br />

5 2<br />

E<br />

1<br />

F<br />

Für die Berechnung der kürzesten Wege von Hand wurden verschiedene Formen von Tabellen entwickelt,<br />

unter anderem die hier verwendete Form. Anfangs sieht eine solche Tabelle etwa so aus:<br />

besucht Knoten Min<br />

A 0<br />

B<br />

C<br />

D<br />

E<br />

F<br />

inf<br />

inf<br />

inf<br />

inf<br />

inf<br />

In der 2. Zeile bedeutet die 0, dass ein Weg der Länge 0 von A nach A führt. Das inf (wie infinity) neben<br />

B bedeutet, dass zur Zeit der kürzeste uns bekannte Weg von A nach B unendlich lang ist, d.h. dass wir<br />

noch keinen Wege von A nach B gefunden haben. Für die anderen Knoten C bis F entsprechend.

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!