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 ...
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.