<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>PhiLIOsoph &#187; Studium</title>
	<atom:link href="http://www.robertnitsch.de/category/studium/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.robertnitsch.de</link>
	<description>Ansichten, Erlebnisse und Werke eines Heranwachsenden</description>
	<lastBuildDate>Tue, 20 Jul 2010 19:27:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>RFA: Ein rekursiver Algorithmus für das metrische Traveling-Salesman-Problem</title>
		<link>http://www.robertnitsch.de/2010/01/14/rfa-ein-rekursiver-algorithmus-fur-das-metrische-traveling-salesman-problem/</link>
		<comments>http://www.robertnitsch.de/2010/01/14/rfa-ein-rekursiver-algorithmus-fur-das-metrische-traveling-salesman-problem/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 20:30:04 +0000</pubDate>
		<dc:creator>Robert</dc:creator>
				<category><![CDATA[Freaky]]></category>
		<category><![CDATA[Informatik]]></category>
		<category><![CDATA[Mathematik]]></category>
		<category><![CDATA[PC]]></category>
		<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Schule]]></category>
		<category><![CDATA[Studium]]></category>

		<guid isPermaLink="false">http://www.robertnitsch.de/?p=483</guid>
		<description><![CDATA[In diesem Artikel stelle ich einen rekursiven Algorithmus namens RFA für das metrische bzw. geometrische Traveling-Salesman-Problem (Problem des Handlungsreisenden, auch genannt Rundreiseproblem) vor. Idee &#038; Umsetzung stammen von mir; bei meiner Recherche habe ich den Algorithmus nicht finden können. Ich gehe daher vorläufig davon aus, dass ich der erste damit bin. Bei dem hier betrachteten [...]]]></description>
			<content:encoded><![CDATA[<p>In diesem Artikel stelle ich einen rekursiven Algorithmus namens <strong>RFA</strong> für das metrische bzw. geometrische <a href="http://de.wikipedia.org/wiki/Problem_des_Handlungsreisenden" rel="nofollow" class="liwikipedia">Traveling-Salesman-Problem</a> (<em>Problem des Handlungsreisenden</em>, auch genannt <em>Rundreiseproblem</em>) vor. Idee &#038; Umsetzung stammen von mir; bei meiner Recherche habe ich den Algorithmus nicht finden können. Ich gehe daher vorläufig davon aus, dass ich der erste damit bin. <img src='http://www.robertnitsch.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Bei dem hier betrachteten Traveling-Salesman-Problem geht es darum, eine möglichst kostengünstige Rundreise durch eine gegebene Menge an &#8220;Städten&#8221; (ich werde bei der Terminologie &#8220;Stadt&#8221; bleiben) zu finden, wobei jede Stadt genau 1 Mal besucht werden muss. Jede Wegstrecke zwischen 2 Städten ist mit bestimmten Reisekosten verbunden. In dem von mir gemeinten Fall des metrischen TSP entsprechen die Reisekosten genau der Luftlinie zwischen den beiden Städten. Daher habe ich die Städte der Einfachheit halber als Punkte in der Ebene modelliert (mit einer X- und einer Y-Koordinate), womit bereits erste Experimente möglich sind.</p>
<h3>Phase 1: Reduktion auf den Trivialfall des TSP</h3>
<div id="attachment_484" class="wp-caption alignright" style="width: 228px"><a href="http://www.robertnitsch.de/wp-content/uploads/2010/01/00_TSP_Trivialfall.png" class="liimagelink"><img src="http://www.robertnitsch.de/wp-content/uploads/2010/01/00_TSP_Trivialfall.png" alt="TSP - Trivialfall mit nur 3 Städten" title="00_TSP_Trivialfall" width="218" height="201" class="size-full wp-image-484" /></a><p class="wp-caption-text">TSP - Trivialfall mit nur 3 Städten</p></div>
<p>Mein Algorithmus greift darauf zurück, dass das Rundreiseproblem für 3 Städte trivial ist, weil es nur 1 mögliche Rundreise durch 3 Städte gibt (siehe Grafik auf der rechten Seite).</p>
<p>Bei 1-3 Städten kann der Algorithmus daher direkt die Lösung zurückgeben, weil sie offensichtlich ist.</p>
<p>Bei mehr als 3 Städten arbeitet der Algorithmus in 2 Phasen.</p>
<p>In der 1. Phase werden die gegebenen Städte solange gefaltet, bis nur noch 3 Städte übrig sind.</p>
<p>Es werden jeweils 2 Städte gefaltet. Das sieht so aus, dass eine neue fiktive Stadt erzeugt wird, deren Koordinate gleich dem Mittelpunkt/Zentrum der 2 gefalteten Städte ist. Die 2 gefalteten Städte werden dann durch die neue fiktive Stadt <em>ersetzt</em>, wobei sich die fiktive Stadt ihre &#8220;Vorbilder&#8221; (<em>&#8220;Kind-Städte&#8221;</em>) merkt. Dadurch wird das Falten zugleich umkehrbar.</p>
<p>Eine naive Implementierung sieht zum Beispiel so aus, dass in jedem Schritt <em>zufällig</em> eine Stadt ausgewählt und ihr nächster Nachbar berechnet wird. Diese beiden Städte werden dann gefaltet. Der Vorgang wird so lange wiederholt, bis wie gesagt nur noch 3 Städte übrig sind. Fiktive Städte können genauso gefaltet werden wie die Ursprungs-Städte. (Dadurch ergibt sich je nach Anzahl der Städte eine beliebig tiefe &#8220;Verschachtelung&#8221;.)</p>
<div style="clear:both;"></div>
<h3>Phase 2: Entfalten der Städte mit optimaler Integration der Kind-Städte</h3>
<p>Nach der 1. Phase sind wir also beim Trivialfall mit 3 Städten angekommen. Das ist auch schon unsere vorläufige Lösung bzw. die vorläufige Rundreise.</p>
<p>In der 2. Phase werden die fiktiven Städte wieder entfaltet, wobei die vorläufige Rundreise bei jedem Schritt erhalten wird.</p>
<div id="attachment_487" class="wp-caption alignright" style="width: 228px"><a href="http://www.robertnitsch.de/wp-content/uploads/2010/01/01_TSP_Entfalten1.png" class="liimagelink"><img src="http://www.robertnitsch.de/wp-content/uploads/2010/01/01_TSP_Entfalten1.png" alt="" title="01_TSP_Entfalten1" width="218" height="201" class="size-full wp-image-487" /></a><p class="wp-caption-text">TSP - Fiktive Stadt (blau) mit Kind-Städten (rot) in einer vorläufigen Rundreise zu Beginn von Phase 2</p></div>
<p>Betrachten wir die Grafik auf der rechten Seite. Nehmen wir an die beiden rot markierten Städte seien die Kind-Städte der blau markierten fiktiven Stadt. (Wie man auch gut sehen kann befindet sich die blaue Stadt genau im Zentrum ihrer beiden Kind-Städte.)</p>
<p>Wenn die fiktive Stadt nun in Phase 2 durch ihre Kinder ersetzt wird, dann gibt es genau 2 Möglichkeiten, wie man die beiden Kind-Städte in die gegebene Rundreise integrieren kann. Dazu muss man sich die blaue Stadt wegdenken, denn diese existiert dann ja nicht mehr.</p>
<div style="clear:both;"></div>
<div id="attachment_594" class="wp-caption alignright" style="width: 228px"><a href="http://www.robertnitsch.de/wp-content/uploads/2010/01/02_TSP_Entfalten2.png" class="liimagelink"><img src="http://www.robertnitsch.de/wp-content/uploads/2010/01/02_TSP_Entfalten2.png" alt="TSP - Entfalten mit beiden Integrationsmöglichkeiten" title="02_TSP_Entfalten2" width="218" height="201" class="size-full wp-image-594" /></a><p class="wp-caption-text">TSP - Entfalten mit beiden Integrationsmöglichkeiten (grün = die bessere Variante)</p></div>
<p>Auf dem nächsten Bild sind die beiden Möglichkeiten eingezeichnet. Die grüne Variante ist offensichtlich die kürzere und damit auch die bessere Wahl.</p>
<p>Halten wir fest: Beim Entfalten muss der Algorithmus nach jedem Schritt entscheiden, wie er die neuen Städte in die bestehende Rundreise integriert. Dabei gilt es zwischen genau 2 Alternativen zu wählen&#8230; und das ist relativ leicht.</p>
<p>Phase 2 endet, wenn keine fiktiven Städte mehr übrig sind, die noch entfaltet werden könnten. Die Rundreise ist damit &#8220;fertig&#8221; und kann vom Algorithmus zurückgegeben werden.</p>
<div style="clear:both;"></div>
<h3>Namensgebung: RFA</h3>
<p>Weil der Algorithmus auf dem Falten &#038; Entfalten der Städte beruht taufe ich ihn <strong>RFA</strong>: <strong>Rekursiver-Falt-Algorithmus</strong> bzw. <em>recursive-fold-algorithm</em>.</p>
<h3>Beispiele</h3>
<div id="attachment_521" class="wp-caption alignleft" style="width: 299px"><a href="http://www.robertnitsch.de/wp-content/uploads/2010/01/03_TSP_Rundreise_100.png" class="liimagelink"><img src="http://www.robertnitsch.de/wp-content/uploads/2010/01/03_TSP_Rundreise_100-289x300.png" alt="TSP - Rundreise mit 100 Städten" title="03_TSP_Rundreise_100" width="289" height="300" class="size-medium wp-image-521" /></a><p class="wp-caption-text">TSP - Rundreise mit 100 Städten</p></div>
<div id="attachment_523" class="wp-caption alignright" style="width: 299px"><a href="http://www.robertnitsch.de/wp-content/uploads/2010/01/04_TSP_Rundreise_500.png" class="liimagelink"><img src="http://www.robertnitsch.de/wp-content/uploads/2010/01/04_TSP_Rundreise_500-289x300.png" alt="TSP - Rundreise mit 500 Städten" title="04_TSP_Rundreise_500" width="289" height="300" class="size-medium wp-image-523" /></a><p class="wp-caption-text">TSP - Rundreise mit 500 Städten</p></div>
<div style="clear:both;"></div>
<p>Die Rundreise auf der linken Seite besteht aus 100 Städten und wurde im Bruchteil einer Sekunde berechnet.</p>
<p>Die Rundreise auf der rechten Seite besteht aus 500 Städten und wurde in nur etwas mehr als 1 Sekunde berechnet.</p>
<p>Wie man an den beiden Beispielen auch gut sehen kann arbeitet der RFA keineswegs optimal, denn an der einen oder anderen Stelle überschneiden sich die Rundreisen sogar (das sicherste Zeichen dafür, dass eine Lösung suboptimal ist).</p>
<p>Nichtsdestotrotz handelt es sich in beiden Fällen um sehr gute Näherungslösungen, die zudem in kürzester Zeit berechnet wurden.</p>
<h3>Performanz &#038; Güte des RFA</h3>
<p>Der RFA befindet sich, was die Laufzeit betrifft, in der Komplexitätsklasse <strong>O(n²)</strong><sup class='footnote'><a href="#fn-483-1" id='fnref-483-1' class="liinternal">1</a></sup> (Faustregel: Verdoppelt man die Anzahl der Städte, so braucht der Algorithmus 4 Mal so lang). Die Speicherkomplexität liegt dagegen bei <strong>O(n)</strong>.</p>
<p>In allen mir bekannten Fällen stellten die vom Algorithmus erzeugten Rundreisen eine gute bis sehr gute Näherung an die optimale Lösung dar.</p>
<p>Dank seiner überragend hohen Geschwindigkeit <strong>eignet sich der RFA in meinen Augen besonders für die Berechnung von Näherungslösungen bei sehr großen Probleminstanzen mit vielen tausenden Städten</strong>. Für <a href="http://www.robertnitsch.de/wp-content/uploads/2010/01/TSP_Rundreise_10000.png" target="_blank" class="liinternal">eine Rundreise durch 10000 Städte *klick*</a> benötigt meine eigene, sehr simple Python-Implementierung beispielsweise ca. 7 Minuten und 20 Sekunden. Gemessen an der Qualität der erhaltenen Näherungslösung ist das ziemlich schnell.</p>
<p>Ausgehend von dieser Näherungslösung kann die Rundreise dann Stück für Stück durch weitere Algorithmen dem Optimum näher gebracht werden.</p>
<p>Zum Vergleich möchte ich außerdem an meinen evolutionären Algorithmus für das TSP erinnern (habe ich damals ebenfalls in Python implementiert). Dieser brauchte bei Städtezahlen jenseits der 100 bereits ewig für eine Näherungslösung. (Für weitere Details siehe <a href="http://www.robertnitsch.de/projekte/lernleistung/" class="liinternal">Projekte -&gt; Lernleistung</a>.)</p>
<h3>Testlauf mit TSP-Instanzen der TSPLIB</h3>
<p>Für TSP &#8211; Testläufe gibt es die sogenannte <a href="http://comopt.ifi.uni-heidelberg.de/software/TSPLIB95/" class="liexternal">TSPLIB</a>. Sie enthält dutzende von TSP-Instanzen mit den unterschiedlichsten Eigenschaften. Von kleinen bis sehr großen Städte-Zahlen ist alles dabei. Das besondere ist, dass in der TSPLIB in vielen Fällen die optimale Lösung bereits enthalten ist. Damit kann man die Ergebnisse von TSP-Algorithmen überprüfen oder ihre Güte in der Praxis abschätzen.</p>
<p>Bisher habe ich meinen Algorithmus zwar hoch gelobt, aber ich bin glaubwürdige Aussagen schuldig geblieben. Daher habe ich ihn auf einige metrische TSP-Instanzen der TSPLIB angesetzt (<a href="http://www.iwr.uni-heidelberg.de/groups/comopt/software/TSPLIB95/tsp/" class="liexternal">Quelle</a>):</p>
<table border="1">
<thead>
<tr>
<th>Instanz-Bezeichnung<br /><span class="tiny">(enthält Städte-Anzahl)</span></th>
<th>Gesamtlänge der<br />optimalen Rundreise<span class="tiny"> (<a href="http://comopt.ifi.uni-heidelberg.de/software/TSPLIB95/STSP.html" class="liexternal">Quelle</a>)</span></th>
<th>Lösung des RFA</th>
<th>Faktor<sup class='footnote'><a href="#fn-483-2" id='fnref-483-2' class="liinternal">2</a></sup></th>
<th>Laufzeit</th>
</tr>
</thead>
<tbody>
<tr>
<td>a280</td>
<td>2579</td>
<td>3372</td>
<td>130.75%</td>
<td>0.482s</td>
</tr>
<tr>
<td>berlin52</td>
<td>7542</td>
<td>8334</td>
<td>110.5%</td>
<td>0.022s</td>
</tr>
<tr>
<td>bier127</td>
<td>118282</td>
<td>139535</td>
<td>117.97%</td>
<td>0.106s</td>
</tr>
<tr>
<td>brd14051</td>
<td>469385</td>
<td>573675</td>
<td>122.22%</td>
<td>15m 27s</td>
</tr>
<tr>
<td>ch150</td>
<td>6528</td>
<td>7830</td>
<td>119.94%</td>
<td>0.159s</td>
</tr>
<tr>
<td>d18512</td>
<td>645238</td>
<td>779639</td>
<td>120.83%</td>
<td>26m 19s</td>
</tr>
<tr>
<td>eil51</td>
<td>426</td>
<td>524</td>
<td>123.0%</td>
<td>0.023s</td>
</tr>
<tr>
<td>pr76</td>
<td>108159</td>
<td>126086</td>
<td>116.57%</td>
<td>0.049s</td>
</tr>
<tr>
<td>pr107</td>
<td>44303</td>
<td>46578</td>
<td>105.14%</td>
<td>0.078s</td>
</tr>
<tr>
<td>pr439</td>
<td>107217</td>
<td>132462</td>
<td>123.55%</td>
<td>1.079s</td>
</tr>
<tr>
<td>pr1002</td>
<td>259045</td>
<td>323954</td>
<td>125.06%</td>
<td>5.157s</td>
</tr>
<tr>
<td>rat99</td>
<td>1211</td>
<td>1374</td>
<td>113.46%</td>
<td>0.068s</td>
</tr>
<tr>
<td>rat783</td>
<td>8806</td>
<td>10548</td>
<td>119.78%</td>
<td>3.171s</td>
</tr>
</tbody>
</table>
<p></p>
<p>Im Schnitt sind die von meinem Algorithmus berechneten Rundreisen <strong>119.14%</strong> länger als die jeweilige optimale Rundreise.</p>
<p>Damit schlägt sich der RFA bei deutlich besserer Laufzeitkomplexität mindestens genausogut wie die <a href="http://de.wikipedia.org/wiki/Christofides-Heuristik" rel="nofollow" class="liwikipedia">Christofides-Heuristik</a> bzw. der Christofides-Näherungsalgorithmus (mit einer Laufzeitkomplexität von <strong>O(n³)</strong>). Die Christofides-Heuristik hat nämlich für metrische Rundreiseprobleme eine feste Gütegarantie von 50%, d.h. sie garantiert einen Faktor von höchstens 150%, d.h. die Lösungen sind maximal 1,5fach so lang wie die optimale Lösung. (Sie ist damit der bisher beste Algorithmus mit einer festen Gütegarantie.)</p>
<p>Zwar kann ich (noch?) nicht beweisen, dass der RFA ebenfalls über eine Gütegarantie verfügt. Aber in der Praxis zeigt sich, dass der Faktor deutlich unter 150% bleibt.</p>
<h3>Übertragbarkeit auf nicht-metrische Rundreiseprobleme</h3>
<p>Der RFA ist zwar auch übertragbar auf nicht-metrische Rundreiseprobleme (das Falten von 2 &#8220;Städten&#8221; muss man dann entsprechend neu erfinden), allerdings erhoffe ich mir davon keine so guten Resultate. Der RFA beruht nunmal hauptsächlich auf der <a href="http://de.wikipedia.org/wiki/Dreiecksungleichung" rel="nofollow" class="liwikipedia">Dreiecksungleichung</a> (denn für je 2 &#8220;Städte&#8221; muss eine Art fiktive Stadt im Zentrum der 2 Städte konstruierbar sein). Je stärker diese verletzt wird, desto schlechter werden die Ergebnisse vermutlich sein. Daher eignet sich der RFA auch nur bedingt für asymmetrische TSP-Instanzen (also wenn die Reisekosten für A -&gt; B nicht immer auch den Reisekosten B -&gt; A entsprechen (bspw. bergauf vs. bergab)).</p>
<p>Ein dahingehender Test meinerseits steht aber noch aus.</p>
<h3>Verbesserungsmöglichkeiten</h3>
<p>Abgesehen von der Art der Implementierung (bis jetzt nur in Python; viel schneller wäre C++) kann man den Algorithmus selbst, d.h. seine Laufzeitkomplexität, definitiv noch weiter verbessern.</p>
<p>Ich sehe großen Spielraum in Phase 1 beim Falten der Städte. Die wesentliche Rechenleistung in Phase 1 besteht darin, zu einer gegebenen Stadt ihren nächsten Nachbarn zu finden. Das kann man deutlich beschleunigen, indem man die Städte zu Beginn von Phase 1 partitioniert (die &#8220;Landkarte&#8221; wird auf bestimmte Weise in Quadrate aufgeteilt). Dadurch muss man beim Suchen des nächsten Nachbars nicht mehr <em>alle</em> Städte berücksichtigen, sondern nur noch diejenigen Städte, die sich in den umliegenden/benachbarten Partitionen befinden. Beim Falten von 2 Städten muss dann natürlich sichergestellt werden, dass die neu erzeugte fiktive Stadt ihrerseits in die korrekte Partition eingeordnet wird.</p>
<p>Die Güte des Algorithmus kann man womöglich deutlich verbessern, indem man eine Methode entwickelt, die auf intelligente Weise die Städte faltet. In meiner naiven Implementierung geschieht die Auswahl der zu faltenden Städte nämlich <em>zufällig</em>. An dieser Stelle kann man gewiss noch Verbesserungen erzielen, indem man die Reihenfolge des Faltens nicht nur dem Zufall überlässt.</p>
<p>In Phase 2 sehe ich wenig Potenzial zur Verbesserung, weil das Entfalten &#8211; wie beschrieben &#8211; quasi optimal erfolgt. Die Reihenfolge des Entfaltens spielt jedoch mMn. wenigstens eine untergeordnete Rolle, deshalb behalte ich mir eine nähere Untersuchung von Phase 2 vor.</p>
<h3>Zusammenfassung</h3>
<p>Der von mir entwickelte Algorithmus für das metrische TSP hat eine Laufzeitkomplexität von <strong>O(n²)</strong> und eine Speicherkomplexität von <strong>O(n)</strong>. Weil er auf dem Falten &#038; Entfalten der Städte beruht und das TSP dabei (zumindest zwischenzeitlich) auf den Trivialfall reduziert, nenne ich ihn <strong>RFA: Rekursiver-Falt-Algorithmus</strong>.</p>
<p>Obwohl meine Python-Implementierung ausgesprochen naiv vorgeht und ich mir kaum Mühe gegeben habe effizienten Code zu schreiben, bewältigt sie TSP-Instanzen der TSPLIB in sehr kurzer Zeit. Die Länge der dabei gefundenen Lösungen lag im Durchschnitt nur ca. 19% über der jeweils optimalen Lösung (also Faktor 119%; der höchste Faktor betrug 130%).</p>
<p>Daher kann der RFA durchaus mit der <strong>Christofides-Heuristik</strong> &#8211; der bisher beste Algorithmus mit einer festen Gütegarantie für das metrische TSP &#8211; konkurrieren, nicht zuletzt weil diese eine deutlich schlechtere Laufzeitkomplexität von <strong>O(n³)</strong> besitzt (und überdies auch noch sehr viel komplizierter ist). Eventuell kann ich beweisen, dass auch für den RFA eine feste Gütegarantie gilt. In der Praxis schlägt er sich auf alle Fälle sehr gut.</p>
<p>Der RFA ist zwar grundsätzlich auch übertragbar auf nicht-metrische Rundreiseprobleme, allerdings hängt die Güte des RFA sehr wahrscheinlich von der Dreiecksungleichung ab. Je stärker diese verletzt wird, desto schlechter werden die Ergebnisse vermutlich sein.</p>
<p><strong>Dank seiner überragenden Geschwindigkeit eignet sich der Algorithmus in meinen Augen besonders für die Berechnung von Näherungslösungen für sehr große TSP-Instanzen mit vielen Tausend Städten.</strong></p>
<h3>Download meiner Python-Implementierung</h3>
<p><a href="http://www.robertnitsch.de/wp-content/uploads/2010/01/RFA_demo.zip" class="lizip">RFA_demo.zip</a> (2.2 MB)</p>
<p>Der Quelltext befindet sich im Ordner &#8220;src&#8221; (die Dateien sind <strong>UTF-8</strong>-kodiert). Die im Artikel verwendeten TSPLIB-Challenges (und viele weitere) befinden sich im Ordner &#8220;TSPLIB&#8221;.</p>
<p>Die auszuführende Datei ist <strong>src/RFA_demo.py</strong>. Ich habe <a href="http://python.org/download/" class="liexternal">Python 2.6</a> verwendet, es sollte aber auch mit <strong>Python 2.5</strong> laufen.</p>
<p>In der Datei <strong>RFA_demo.py</strong> kann man auch einige Einstellungen verändern. Ich habe die entsprechenden Stellen deutlich hervorgehoben und jede Einstellung in Deutsch beschrieben (ansonsten ist alles in Englisch gehalten). Sogar Laien haben also eine faire Chance die Demonstration auf ihrem PC auszuführen.</p>
<p>Viel Spaß damit!
<div class='footnotes'>
<div class='footnotedivider'></div>
<ol>
<li id='fn-483-1'>Einen Beweis bleibe ich vorerst schuldig. Allerdings ist O(n²) naheliegend, weil der wesentliche Aufwand darin besteht während des Faltens (Phase 1) immer und immer wieder den nächsten Nachbarn zu einer Stadt zu finden. Dort sehe ich übrigens auch schon die ersten vielversprechenden Verbesserungsmöglichkeiten mittels geschickter Partitionierung der Städte (mehr dazu unter &#8220;Verbesserungsmöglichkeiten&#8221;). <span class='footnotereverse'><a href="#fnref-483-1" class="liinternal">&#8617;</a></span></li>
<li id='fn-483-2'>Der Faktor berechnet sich als &lt;RFA-Lösung&gt; / &lt;Optimale-Lösung&gt; und gibt somit die relative Länge der RFA-Lösung zur Länge der optimalen Lösung an. <span class='footnotereverse'><a href="#fnref-483-2" class="liinternal">&#8617;</a></span></li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.robertnitsch.de/2010/01/14/rfa-ein-rekursiver-algorithmus-fur-das-metrische-traveling-salesman-problem/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>TU Darmstadt: Rückblick auf 2 Semester Informatik</title>
		<link>http://www.robertnitsch.de/2009/11/28/tu-darmstadt-ruckblick-auf-2-semester-informatik/</link>
		<comments>http://www.robertnitsch.de/2009/11/28/tu-darmstadt-ruckblick-auf-2-semester-informatik/#comments</comments>
		<pubDate>Sat, 28 Nov 2009 15:00:52 +0000</pubDate>
		<dc:creator>Robert</dc:creator>
				<category><![CDATA[Erfahrungsberichte]]></category>
		<category><![CDATA[Informatik]]></category>
		<category><![CDATA[PC]]></category>
		<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[Real Life]]></category>
		<category><![CDATA[Studium]]></category>

		<guid isPermaLink="false">http://www.robertnitsch.de/?p=316</guid>
		<description><![CDATA[Wie man dem Willkommenstext ganz oben auf der Startseite entnehmen kann studiere ich momentan Informatik an der TU Darmstadt. Ich strebe den Abschluss M.Sc. (Master of Science) Informatik an. Inzwischen habe ich die ersten 2 Semester hinter mir, befinde mich also noch im Bachelor-Stadium; das 3. Semester hat seit einigen Wochen begonnen. Dieser Artikel soll [...]]]></description>
			<content:encoded><![CDATA[<p>Wie man dem Willkommenstext <a href="http://www.robertnitsch.de" class="liinternal">ganz oben auf der Startseite</a> entnehmen kann studiere ich momentan Informatik an der <a href="http://www.tu-darmstadt.de" class="liexternal">TU Darmstadt</a>. Ich strebe den Abschluss <strong>M.Sc.</strong> (<em>Master of Science</em>) Informatik an.</p>
<p>Inzwischen habe ich die ersten 2 Semester hinter mir, befinde mich also noch im Bachelor-Stadium; das 3. Semester hat seit einigen Wochen begonnen. Dieser Artikel soll einen kurzen Rückblick darstellen, der sich wahrscheinlich besonders für diejenigen lohnt, die ein Informatik-Studium in Betracht ziehen.</p>
<p>Hinweis: Ich gebe hier meine Sicht der Dinge wieder, also <em>meine</em> Meinung.</p>
<h3>Wintersemester 08/09</h3>
<p>Im WS 08/09 habe ich mein Informatik-Studium an der TU Darmstadt begonnen. Für diejenigen, die vllt. Informatik studieren werden, dürfte dieser Teil am spannendsten sein.</p>
<h4>Grundlagen der Informatik 1</h4>
<p>In GdI 1 gab es eine Einführung in das Programmieren. Von einer Einführung kann dabei aber kaum die Rede sein, denn es ging durchaus ziemlich in die Tiefe. Angefangen haben wir mit <strong>Scheme</strong>, einer <strong><em>funktionalen</em> Programmiersprache</strong>, die mit LISP verwandt ist und mit der ich und die meisten meiner Kommilitonen zuvor nichts zu tun gehabt haben. Funktionale Programmierung war für die meisten, mich eingeschlossen, absolutes Neuland.</p>
<p>Das war insofern ein Problem, als dass viele meiner Kommilitonen Schwierigkeiten beim Einstieg in die funktionale Programmierung hatten &#8211; nicht nur die absoluten Neulinge, sondern auch einige der Erfahreneren. Bei Scheme werden nämlich fast alle Probleme mit rekursiven Funktionen gelöst. Schleifen im klassischen Sinne stehen quasi nicht zur Verfügung. Und wie sortiert man bspw. eine Liste rekursiv, wenn man bisher nur iterative Implementierungen kennt? Erstmal gar nicht so einfach!</p>
<p>Es stellte sich jedoch sehr schnell heraus, dass die Erfahrung mit Scheme eine echte Bereicherung war. Wer GdI 1 mit einer guten Note übersteht, der dürfte hinterher keine Probleme mehr mit Rekursionen haben. <img src='http://www.robertnitsch.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Der zweite und geringfügig größere Teil drehte sich um <strong>Java</strong>. Das Verhältnis Scheme : Java kann man ungefähr mit 40 : 60 beschreiben. Beinhaltet waren solche Themen wie Objektorientierte Programmierung, d.h. was sind Klassen/Objekte, was ist Vererbung und wie funktioniert sie, Polymorphismus, Generische Typen (Generics) und ähnliches.</p>
<p><strong>Klausuren:</strong> Im Dezember gab es eine Semestralklausur, in der es nur um Scheme ging. Nach Ende der Lehrveranstaltungen (während der Semesterferien) gab es dann noch eine endgültige Prüfung, die zu etwa 40% aus Scheme und zu 60% aus Java-bezogenen Aufgaben bestand.</p>
<p><strong>Bewertung:</strong> Der Veranstalter ist den Studenten bei Problemen fast immer entgegengekommen, die Folien &#038; die Übungen waren gut gemacht und die Klausuren waren sehr fair. Für Einsteiger ohne Programmiererfahrung aber trotzdem ein gewaltiges Stück Arbeit!</p>
<h4>Technische Grundlagen der Informatik 1</h4>
<p>TGdI 1 beinhaltete Grundlagen der Digitaltechnik, also boolesche Algebra / boolesche Funktionen, kombinatorische und sequenzielle Logik, KV-Diagramme, digitale Schaltungen, Signalpfade, wichtige digitale Schaltungen (Multiplexer, Decoder, &#8230;), darunter auch Speicherelemente (Flipflops), Automaten (Mealy und Moore) uvm.</p>
<p><strong>Klausuren:</strong> Auch hier gab es eine Semestralklausur im Dezember und eine Prüfung am Ende des Semesters.</p>
<p><strong>Bewertung:</strong> Die Folien waren relativ gut gemacht, teilweise habe ich aber den roten Faden vermisst. Insgesamt aber immer noch sehr gut gemacht, auch die Übungen und die Klausur ließen nicht viel zu wünschen übrig. Allerdings ist der Stoff einfach einfach. Wer hier durchfällt sollte sich Gedanken machen!</p>
<h4>Mathematik für Informatiker und Wirtschaftsinformatik 1</h4>
<p>Mathematik für Inf und WInf 1 war zusammen mit FGdI 1 die einzige Herausforderung im 1. Semester. Dazu muss ich etwas weiter ausholen.</p>
<p>Inhaltlich gesehen ist Mathe 1 nicht sonderlich schwer. Im Wesentlichen geht es um die <strong>gewöhnliche Analysis</strong> (mit einstelligen Funktionen), d.h. Folgen, Reihen, Grenzwerte, Funktionen, Differential- und Integralrechnung. Jedoch wird das Ganze sehr mathematisch aufgezogen. Der Vorlesung kann man kaum folgen, die wichtigen Informationen gehen in einem Schwall unnötiger mathematischer Sätze und Beweise völlig unter. Dazu muss man sagen, dass die Veranstaltung vom Fachbereich Mathematik organisiert wird. Sie wird also auch von einem Mathematik-Professor gehalten. Das merkt man auch sehr deutlich.</p>
<p><strong>Klausuren:</strong> Es gab nur 1 Klausur am Ende des Semesters.</p>
<p><strong>Bewertung:</strong> In Mathe 1 wird relativ leichter Stoff mit mathematischen Beweisen derart aufgeblasen, dass die eigentliche Leistung darin besteht, die wenigen wichtigen Informationen zu filtern bzw. überhaupt zu erfassen, ohne sich dabei von der gigantischen Menge unnötigen Wissens, das ebenfalls vermittelt wird, erschlagen zu lassen. Die Übungen waren anfangs schwer, weil man mathematische Beweise führen musste. Und das ist erstmal schwer bis unmöglich. Später wurden die Übungen aber besser. Die Klausur war schließlich ausgesprochen fair, aber vor allem eines: leichter, als alle erwartet hatten. Trotzdem sind hier viele gescheitert. <img src='http://www.robertnitsch.de/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<h4>Formale Grundlagen der Informatik 1</h4>
<p>FGdI 1 ist mir bis heute noch ein Rätsel. Wie man dem Titel der Veranstaltung ansehen kann geht es hier um die <strong>theoretische Informatik</strong>.</p>
<p>Rätsel deshalb, weil im Grunde genommen extrem einfacher Stoff (Sprachen, Reguläre Ausdrücke, Grammatiken, Chomsky-Hierarchie und dazugehörend <abbr title="deterministic finite automaton">DFAs</abbr>, <abbr title="non-deterministic finite automaton">NFAs</abbr>, <abbr title="pushdown automaton">PDAs</abbr>) dermaßen mit formaler Sprache aufgeblasen wird, dass man sich erstmal immer fragt: &#8220;WHAT THE FUCK SOLL DAS HEISSEN?&#8221; Und wenn man es dann verstanden hat, denkt man sich: &#8220;Ist ja total easy. -.-&#8221;</p>
<p>Die Verantwortung liegt hier nicht nur bei den Veranstaltern, denn schließlich muss man sich an die formale Sprache erst gewöhnen, bis man sie wirklich verstehen kann. Aber es gab quasi keinerlei Erklärendes. Im Wesentlichen wurde wild drauflos definiert und wir mussten dann erraten, wozu die einzelnen Definitionen jeweils im Gesamtzusammenhang gebraucht wurden. Wie man es auch dreht und wendet: Wenn man gerade erst mit dem Studium anfängt, dann ist das eine echte Herausforderung!</p>
<p><strong>Klausuren:</strong> Es gab wie in Mathe 1 nur eine Klausur am Ende des Semesters. :/</p>
<p><strong>Bewertung:</strong> Während die Vorlesung inkl. Folien ziemlich bescheiden war, so waren die Übungen einigermaßen in Ordnung und die Klausur war sehr fair. Man konnte 60 Punkte erreichen, für eine 1.0 brauchte man aber nur 48 Punkte. Hier kann man eigentlich nur durchfallen, wenn man das falsche lernt. Ein gutes Auge für das Wesentliche hilft Wunder!</p>
<h3>Sommersemester 2009</h3>
<h4>Grundlagen der Informatik 2</h4>
<p>GdI 2 war eine monströse Veranstaltung, in der sich alles um <strong>Algorithmen und Datenstrukturen</strong> drehte, auch mehrere Index-Strukturen waren dabei; Laufzeit- und Speicherkomplexität von Algorithmen inklusive uvm. Alles in allem war es vor allem eines: verdammt viel, für die meisten <em>zu</em> viel! Nicht ohne Grund ist GdI 2 als <strong>&#8220;Exmatrikulator&#8221;</strong> berüchtigt (womit sich die Veranstalter für meinen Geschmack allzu oft gebrüstet haben, so als wären sie besonders stolz darauf).</p>
<p>Hier noch ein paar Stichworte zur Illustration: Komplexität von Algorithmen, Sortierverfahren, Graphenalgorithmen, Allgemeine Bäume und Binärbäume, Binäre Suchbäume, Mehrwegbäume, B-Baum u. Varianten, Digitale Suchbäume, Hashverfahren (intern, extern, erweiterbar), Graphische Datenstrukturen, Spezielle Themen (Bitmap Index, Indexstrukturen für &#8220;broadcast data&#8221;, etc.)</p>
<p><strong>Klausuren:</strong> Nur eine Klausur am Ende des Semesters, für die man sich einen Bonus von bis zu einem ganzen Notensprung erarbeiten konnte.</p>
<p><strong>Bewertung:</strong> Die Vorlesung war in Ordnung, soweit ich das beurteilen kann. Unser Professor schien aber häufig unvorbereitet zu sein; er selbst sagte entschuldigend, er hätte dieses Semester sehr viel zu tun.<br />
Wie bereits geschrieben konnte man sich einen Bonus erarbeiten. Ab 191 Punkten in den bewerteten Hausübungen und Programmieraufgaben hat man einen vollen Notensprung für die Prüfung erhalten. Das war insofern manchmal ärgerlich, als dass die Hausübungen und Programmieraufgaben in mehreren Fällen unklar/missverständlich formuliert waren und die Folien oft erst verspätet ins Netz gestellt wurden. Ansonsten waren die Übungen und die Programmieraufgaben durchaus sehr hilfreich und man konnte sehr viel dabei lernen.<br />
Die Klausur am Ende war ziemlich fair, es wurden sogar diejenigen belohnt, die sich den letzten Foliensatz nochmal komplett durchgeschaut haben (dazu kam eine sehr leichte Aufgabe dran, die man aber ohne diesen Foliensatz nicht bearbeiten konnte). Ich bin sehr zufrieden mit dieser Veranstaltung, einzig die Tatsache, dass man sich ständig als &#8220;Exmatrikulator&#8221; aufgeführt hat, ist mir mehrfach übel aufgestoßen. Man stand quasi dauernd unter Verdacht, Lösungen von Kommilitonen zu kopieren. Das nervt irgendwann&#8230;</p>
<h4>Technische Grundlagen der Informatik 2</h4>
<p>In TGdI 2 wurde uns im Wesentlichen beigebracht wie <strong>Prozessoren</strong> funktionieren. Das beinhaltet die verschiedenen binären Zahlen-Darstellungen (1er-Komplement, 2er-Komplement, Gleitkommazahlen uvm.), die Begriffe Steuerwerk &#038; Operationswerk, ALUs und eine Einführung in die MIPS-Prozessorarchitektur (Eintaktimplementierung, Mehrtaktimplementierung und eine Implementierung mit Pipelining und alles was dazugehört, also z.B. Forwarding und Hazard Detection uvm.). In der Praxis haben wir mit Verilog gearbeitet, einer Hardware-Beschreibungssprache. Mit dieser Sprache haben wir in vielen Übungen digitale Schaltungen beschrieben und simuliert; eine sehr spannende Angelegenheit. Eine kleine Einführung in die Assembler-Programmierung hat es hier ebenfalls gegeben.</p>
<p><strong>Klausuren:</strong> 1 Semestralklausur, die für das Ergebnis nur insofern relevant war, als dass man sich hier einen Bonus für die eigentliche Klausur am Ende des Semesters holen konnte.</p>
<p><strong>Bewertung:</strong> Die Veranstaltung war sehr gut gemacht! Gute Folien, gute Übungen und eine fordernde, aber faire Klausur zum Schluss. Die Semestralklausur war ebenfalls in Ordnung. Außerdem &#8211; gut, das ist jetzt eher subjektiv &#8211; war das Thema sehr interessant. <img src='http://www.robertnitsch.de/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h4>Mathematik für Inf und WInf 2</h4>
<p>Von der Qualität der Veranstaltung her genauso schlimm wie Mathe 1. Die eigentliche Leistung bestand wieder darin rechtzeitig vor den Klausuren den ganzen Schmodder, den man sich umsonst reingezogen hat, wieder loszuwerden und einen freien Kopf zu kriegen. Dann erst kann man sich richtig auf die Klausur vorbereiten.</p>
<p>Inhaltlich bot Mathe 2 lineare Algebra, Analysis mit mehrstelligen Funktionen und einfache Differentialgleichungen (DGL), lineare Systeme von DGL usw.</p>
<p><strong>Klausuren:</strong> Wie bei Mathe 1 gab es nur eine Klausur am Ende des Semesters. Diese Klausur war &#8211; anders als bei Mathe 1 &#8211; <strong>viel schwerer</strong> als wir erwartet hatten. So kam dann auch eine <strong>Durchfallquote von 60%</strong> bzw. eine <strong>Durchschnittsnote von 4.27</strong> zustande. Ich habe es dennoch geschafft unter die besten 10% zu kommen, trotzdem bin ich etwas enttäuscht von der <em>absoluten</em> Note.</p>
<p><strong>Bewertung:</strong> Ja, was soll man dazu sagen? Die Vorlesung ist grauenvoll, weil sie zu 90% unbrauchbares mathematisches Gedöns enthält, das eine riesige Belastung darstellt, weil man eben erstmal nicht weiß, was davon nun Gedöns ist und was man wirklich braucht. Also zieht man sich <em>alles</em> rein und ordnet den Stoff <em>hinterher</em> in &#8220;Unbrauchbar&#8221; und &#8220;Brauchbar&#8221;. Sorry, aber das muss einfach mal gesagt werden: Die Vorlesung ist scheiße.<br />
Die Übungen hingegen waren einigermaßen in Ordnung. Es gab übrigens viele betreute Extra-Übungen vor der Klausur &#8211; eine super Gelegenheit zur Vorbereitung, die man bei anderen Veranstaltungen meist nicht bekommt.</p>
<h4>Formale Grundlagen der Informatik 2</h4>
<p>Kurzfassung: Nach FGdI 2 habe ich mich kaum noch über FGdI 1 beschwert.<br />
Das liegt daran, dass FGdI 2 letzteres nochmals deutlich unterboten hat. Erklärungen gab es keine und die wenigen Beispiele in den Folien verstehe ich heute noch nicht &#8211; trotz guter Prüfungsnote. Hier hat man sich keine Mühe gegeben, so viel steht fest. Mal wieder hat sich mein Motto <strong>&#8220;schlimmer geht immer&#8221;</strong> bestätigt. Dagegen war die Mathe 2 &#8211; Vorlesung fast schon wieder genießbar.</p>
<p>Inhaltlich ging es in FGdI 2 um die <strong>Aussagenlogik</strong> (quasi boolesche Algebra) und die <strong>Prädikatenlogik</strong> (im Wesentlichen Aussagenlogik erweitert um All- und Existenzquantoren).</p>
<p><strong>Klausur:</strong> Nur eine Klausur am Ende des Semesters (48 Punkte brauchte man für 100%, 60 gab es insgesamt). Naja: <em>eigentlich</em>! Leider gab es während der Klausur in einem der Gebäude einen Feueralarm. Dadurch konnten etwa 2 Drittel der Studenten die Klausur nicht weiterschreiben und mussten die Klausur etwa 3 Wochen später wiederholen &#8211; der neue Termin für FGdI 2 lag zudem direkt hinter 2 anderen knackigen Klausuren. Einen Vorteil hatten wir Wiederholenden (ich war einer der Unglücklichen) also nicht, denn wir mussten uns auf die anderen Klausuren konzentrieren (unter anderem auf den &#8220;Exmatrikulator&#8221;: GdI 2). Trotzdem war die Wiederholungsklausur schwerer als die 1. Klausur. Schwerer ist eigentlich der falsche Ausdruck: <strong>Die Wiederholungsklausur war um Längen schwerer!</strong> Es gab in jeder Ecke irgendeine Falle, und die meisten sind voll ins Messer gelaufen.<br />
Hier die Notenspiegel der beiden Klausuren im Vergleich (PDF von mir erstellt, Angaben ohne Gewähr!): <a href="http://www.robertnitsch.de/wp-content/uploads/2009/10/Notenspiegel_FGdI2_SS09.pdf" class="lipdf">Notenspiegel FGdI2 SS09</a><br />
Unbedingt zu beachten sind die Punktegrenzen auf Seite 2. Ursprünglich benötigte man 24 Punkte zum Bestehen (50% von 48). Diese Grenze wurde bereits bei der 1. Klausur deutlich herabgesetzt. Bei der Wiederholungsklausur brauchte man schließlich nur noch 15 Punkte! Das sind etwa 31%!<br />
Man kann sich also ungefähr ausmalen wie viel schwerer die Wiederholungsklausur war. Für mich war das Ganze nicht mehr nachvollziehbar.</p>
<p><strong>Bewertung:</strong> Die Vorlesung &#038; die Folien waren grauenvoll, die Übungen mäßig und die Klausuren wurden insofern versaut, als dass die Wiederholungsklausur in einem völlig unangebrachten Ausmaß schwerer war als die 1. Klausur. FGdI 2 war sehr bitter!</p>
<h3>Fazit</h3>
<p>Die ersten 2 Semester sind definitiv eine <strong>Durststrecke</strong>. Besonders diejenigen Veranstaltungen, die vom Fachbereich Mathematik organisiert werden (das sind Mathe 1 &#038; 2 und Formale Grundlagen 1 &#038; 2), leiden an grauenvollen Vorlesungen und schwer nachvollziehbaren Folien/Skripten. Genausogut könnten wir auch die normalen Mathe-Vorlesungen hören, da bräuchte es kein Mathematik <strong>für Informatiker</strong> (das beziehe ich jetzt wirklich nur auf die Vorlesung; was die Übungen und die Klausur angeht habe ich nichts einzuwenden <img src='http://www.robertnitsch.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ). Mich haben also keineswegs die Veranstaltungen gestört, in denen es etwas theoretischer zuging. Nein, mich stört, dass sich der FB Mathematik bei Veranstaltungen <strong>für Informatiker</strong> scheinbar nicht die allergeringste Mühe zu geben scheint. Die Veranstaltungen tragen zwar &#8220;für Informatiker&#8221; im Namen, inhaltlich ist das jedoch (abgesehen vllt. von der Klausur) kaum zu spüren. Mag sein, dass sie den Stoff tatsächlich ein wenig für die Informatiker angepasst haben. Für mich steht aber fest: Da ist noch viel zu viel Luft nach oben.</p>
<p>Das 3. Semester hingegen sieht bisher ausgesprochen gut aus. Das liegt ganz gewiss auch daran, dass sämtliche Veranstaltungen vom FB Informatik organisiert werden. Man spürt sofort, dass die Veranstalter einen ganz anderen Blick auf die Dinge haben und vermitteln.</p>
<h4>Fallt mir nicht in den Rücken&#8230;</h4>
<p>Ich habe schon mehrfach die Lehrveranstaltungen des FB Mathematik im Fachschaftsforum kritisiert, da hier wie gesagt einiges im Argen liegt. Dabei sind mir viele Kommilitonen in den Rücken gefallen mit scheinheiligen Argumenten wie &#8220;schau dir doch Erklärungen im Internet an&#8221; oder &#8220;das ist der Anspruch einer Universität&#8221; usw. Sinngemäß wurde mir viel zu oft vermittelt: &#8220;Wenn du zu dumm dafür bist, dann studier etwas anderes oder organisiere dich besser.&#8221; Das möchte ich an dieser Stelle gerne vermeiden.</p>
<p>Niemand konnte mir bisher erklären, warum sich manche Veranstalter (des FB Mathematik) auf die faule Haut legen dürfen, während man sich bei anderen bereits über Kleinigkeiten aufregt (mehrfach geschehen).<br />
<strong>Die Grundlagen-Veranstaltungen der ersten 2 Semester, die vom FB Mathematik organisiert werden, sind einfach <em>scheiße</em>.</strong> Diese meine Ansicht habe ich jetzt an mehreren Stellen mehr oder weniger grob erklärt (Kurzfassung: es steht zwar &#8220;für Informatiker&#8221; drauf, das ist aber nicht drin!). Findet euch damit ab, dass man mich nicht von dieser Ansicht abbringt, indem man mir immer wieder erklärt, dass es Veranstaltungen gibt, die noch schlechter sind oder dass ich zu dumm oder zu faul bin. Ich habe Mathe 1/2 und FGdI 1/2 auf Anhieb bestanden und außer bei FGdI 2 habe ich jedes Mal zu den besten 10% gehört (bei FGdI 2 nur zu den besten 16% mangels Motivation). Von Dummheit oder Faulheit möchte ich nichts mehr hören, egal wie ihr diese Anschuldigungen verpackt.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertnitsch.de/2009/11/28/tu-darmstadt-ruckblick-auf-2-semester-informatik/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Java Generics vs. Java Listen</title>
		<link>http://www.robertnitsch.de/2009/03/31/java-generics-vs-java-listen/</link>
		<comments>http://www.robertnitsch.de/2009/03/31/java-generics-vs-java-listen/#comments</comments>
		<pubDate>Tue, 31 Mar 2009 20:09:35 +0000</pubDate>
		<dc:creator>Robert</dc:creator>
				<category><![CDATA[Informatik]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Studium]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.robertnitsch.de/?p=211</guid>
		<description><![CDATA[Beim Thema Generics in Verbindung mit Listen geht vieles drunter und drüber. Dabei ist die Sache gar nicht so schwer, wenn man das Prinzip einmal verstanden hat&#8230; Zunächst einmal: Generics ermöglichen mittels formaler Typparamter, dass Klassen (und Funktionen), die bestimmte Dienste zur Verfügung stellen, mit mehreren Datentypen umgehen können. Wenn wir zum Beispiel zwei beliebige [...]]]></description>
			<content:encoded><![CDATA[<p>Beim Thema Generics in Verbindung mit Listen geht vieles drunter und drüber. Dabei ist die Sache gar nicht so schwer, wenn man das Prinzip einmal verstanden hat&#8230;</p>
<p>Zunächst einmal: Generics ermöglichen mittels <em>formaler Typparamter</em>, dass Klassen (und Funktionen), die bestimmte Dienste zur Verfügung stellen, mit mehreren Datentypen umgehen können.<br />
Wenn wir zum Beispiel zwei beliebige Objekte als &#8220;Paar&#8221; verwalten wollen, dann benötigen wir eine entsprechende Klasse mit zwei Attributen, einer Möglichkeit die Objekte darin zu speichern und wieder auszulesen.</p>
<p>An sich nichts schweres:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Pair <span style="color: #009900;">&#123;</span>
    <span style="color: #003399;">Object</span> obj1, obj2<span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">// Das Einspeichern von Objekten ist der Einfachheit halber nur beim Erzeugen des Paares möglich...</span>
    Pair<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> obj1, <span style="color: #003399;">Object</span> obj2<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">obj1</span> <span style="color: #339933;">=</span> obj1<span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">obj2</span> <span style="color: #339933;">=</span> obj2<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Object</span> getFirst<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">obj1</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Object</span> getSecond<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">obj2</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Diese Klasse hat aber einen Haken. Beim Einspeichern gehen die Informationen über den Typ der eingespeicherten Objekte verloren. Wenn wir den Typ wiederherstellen wollen müssen wir einen expliziten Cast durchführen. Andernfalls erhalten wir immer nur <em>Object</em>s.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Pair paar <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Pair<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> MeinApfel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, <span style="color: #000000; font-weight: bold;">new</span> MeinApfel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
MeinApfel apfel <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>MeinApfel<span style="color: #009900;">&#41;</span>paar.<span style="color: #006633;">getFirst</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Bei Listen ist das Problem noch dramatischer. Ohne Generics muss man bei jeder Leseoperation auf einer Liste explizit casten:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #003399;">Vector</span> liste <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Vector</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> i<span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span><span style="color: #cc66cc;">10</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
    liste.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> MeinApfel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #000000; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> i<span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span>liste.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
    esseApfel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>MeinApfel<span style="color: #009900;">&#41;</span> liste.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Bei so vielen expliziten Casts riskiert man außerdem <em>ClassCastException</em>s, falls das referenzierte Objekt nicht zu dem entsprechenden Typ konvertiert werden kann.</p>
<p>Abhilfe schaffen hier die Generics. Das soll erstmal am Beispiel der obigen Pair-Klasse demonstriert werden, die folgendermaßen generisch gemacht werden kann:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Pair<span style="color: #339933;">&lt;</span>A,B<span style="color: #339933;">&gt;</span> <span style="color: #009900;">&#123;</span>
    A obj1<span style="color: #339933;">;</span>
    B obj2<span style="color: #339933;">;</span>
    Pair<span style="color: #009900;">&#40;</span>A obj1, B obj2<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">obj1</span> <span style="color: #339933;">=</span> obj1<span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">obj2</span> <span style="color: #339933;">=</span> obj2<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">public</span> A getFirst<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">obj1</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">public</span> B getSecond<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">obj2</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>A und B sind sogenannte formale Typparameter, die in diesem Fall für beliebige Typen stehen.<br />
Folgendermaßen erzeugen wir jetzt Paare von Integer-Objekten:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// anschaulich wird hier A = Integer und B = Integer gesetzt</span>
Pair<span style="color: #339933;">&lt;</span>Integer, Integer<span style="color: #339933;">&gt;</span> paar <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Pair<span style="color: #339933;">&lt;</span>Integer, Integer<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Integer</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span>, <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Integer</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// kein Cast mehr nötig, weil auch die Signatur von getFirst() quasi dynamisch an Integer angepasst wurde</span>
<span style="color: #003399;">Integer</span> zahl <span style="color: #339933;">=</span> paar.<span style="color: #006633;">getFirst</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Dasselbe ist natürlich auch bei Listen möglich, die bei der Einführung der Generics auch gleich generisch gemacht wurden. Bei Listen gibt es im Gegensatz zu dem Pair-Beispiel nur <em>einen</em> formalen Typparameter, der den Typ der gespeicherten Elemente festlegt.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// Eine Liste von Elementen des Typs &quot;MeinApfel&quot; anlegen...</span>
Vector<span style="color: #339933;">&lt;</span>MeinApfel<span style="color: #339933;">&gt;</span> liste <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Vector<span style="color: #339933;">&lt;</span>MeinApfel<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
liste.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> MeinApfel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// funktioniert problemlos, da die Signatur von get() genau wie getFirst() aus dem ersten Beispiel an den ggb. Typ angepasst wurde</span>
MeinApfel apfel <span style="color: #339933;">=</span> liste.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Richtig trickreich wird es, wenn Funktionen, die Listen entgegennehmen, generisch gemacht werden sollen. Angenommen wir wollen eine Funktion schreiben, die eine Liste von Nahrungsmitteln entgegennimmt und ihr Gewicht bestimmt.<br />
In diesem Fall werden sogenannte Wildcards benötigt.</p>
<p>Intuitiv müsste die Funktion folgendermaßen aussehen:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">double</span> wiege<span style="color: #009900;">&#40;</span>List<span style="color: #339933;">&lt;</span>Nahrungsmittel<span style="color: #339933;">&gt;</span> liste<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Diese Funktion würde aber entgegen unserer Intuition bspw. keine Liste mit Äpfeln annehmen, obwohl Äpfel in der Klassenhierarchie ganz klar ein Subtyp von Nahrungsmittel darstellen würden (<em>public class Apfel extends Nahrungsmittel</em>).<br />
Es funktioniert deshalb nicht, weil List&lt;Apfel&gt; einfach nicht kompatibel ist zu List&lt;Nahrungsmittel&gt;. Beispiel:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">Vector<span style="color: #339933;">&lt;</span>Nahrungsmittel<span style="color: #339933;">&gt;</span> liste1 <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Vector<span style="color: #339933;">&lt;</span>Nahrungsmittel<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// OK!</span>
Vector<span style="color: #339933;">&lt;</span>Apfel<span style="color: #339933;">&gt;</span> liste2 <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Vector<span style="color: #339933;">&lt;</span>Apfel<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// OK!</span>
liste1 <span style="color: #339933;">=</span> liste2<span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// FEHLER: cannot convert from Vector&lt;Apfel&gt; to Vector&lt;Nahrungsmittel&gt;</span></pre></td></tr></table></div>

<p>Dieser Code wird vom Compiler deshalb nicht akzeptiert, weil man in eine Liste von Äpfeln keine Nahrungsmittel einfügen kann. Wenn <em>liste1</em> vom Typ List&lt;Nahrungsmittel&gt; auf <em>liste2</em> vom Typ List&lt;Apfel&gt; verweisen würde, dann würde das bspw. die Signatur von liste1.add(&#8230;) verletzen, denn liste1.add(new Nahrungsmittel()) wäre nicht möglich, weil liste1 auf eine Liste von Äpfeln (und nur Äpfel!) zeigen würde. Das meine ich, wenn ich schreibe, dass List&lt;Apfel&gt; nicht kompatibel ist zu List&lt;Nahrungsmittel&gt;.</p>
<p>Das Problem löst man mit besagten Wildcards:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">double</span> wiege<span style="color: #009900;">&#40;</span>List<span style="color: #339933;">&lt;?</span> <span style="color: #000000; font-weight: bold;">extends</span> Nahrungsmittel<span style="color: #339933;">&gt;</span> liste<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// akzeptiert alle Listen, deren Elemente Nahrungsmittel oder Subtypen davon sind</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>? steht für einen unbekannten Typ. Bekannt ist bei einer List&lt;?&gt; nur, dass &#8211; wie bei jeder typ-parametrisierten Liste &#8211; die Elemente, die in der Liste gespeichert sind, alle vom selben (unbekannten) Typ sind.<br />
Das &#8220;extends Nahrungsmittel&#8221; schränkt die möglichen Typen hier aber insofern ein, als dass Nahrungsmittel die &#8220;obere Schranke&#8221; darstellt. ? darf hier also vom Typ Nahrungsmittel oder ein Subtyp davon sein.</p>
<p>Es gibt auch die Möglichkeit eine untere Schranke zu definieren: List&lt;? super Nahrungsmittel&gt; bzw. allgemein List&lt;? super X&gt;. Erlaubt sind dann Elemente vom Typ X oder Supertypen davon.</p>
<p>Bleiben wir zunächst bei unserer List&lt;? extends Nahrungsmittel&gt;. Wir können zumindest eingeschränkt mit einer solchen Liste arbeiten: Lesen, aber nicht Einfügen. Das Einfügen klappt deshalb nicht, weil der genaue Typ der Liste nicht bekannt ist. Zwar kann man einen Apfel zu einem Nahrungsmittel konvertieren. Aber die Liste enthält ja nicht notwendigerweise Nahrungsmittel. Sie kann genausogut Birnen enthalten &#8211; daher darf man in eine solche Liste keine neuen Objekte einfügen.</p>
<p>Im Folgenden eine Tabelle, die die erlaubten Operationen auf einer Liste dokumentiert:</p>
<table border="1" class="data">
<tr>
<th>Typ</th>
<th>Lesen</th>
<th>Typ der gelesenen Objekte</th>
<th>Einfügen</th>
<th>Einfügbare Typen</th>
</tr>
<tr>
<th style="text-align:left;">List</th>
<td>Ja</td>
<td>Object</td>
<td>Ja</td>
<td>Beliebig</td>
</tr>
<tr>
<th style="text-align:left;">List&lt;?&gt;</th>
<td>Ja</td>
<td>Object</td>
<td>Nein</td>
<td>-</td>
</tr>
<tr>
<th style="text-align:left;">List&lt;X&gt;</th>
<td>Ja</td>
<td>X</td>
<td>Ja</td>
<td>X oder Subtypen von X</td>
</tr>
<tr>
<th style="text-align:left;">List&lt;? extends X&gt;</th>
<td>Ja</td>
<td>X</td>
<td>Nein</td>
<td>-</td>
</tr>
<tr>
<th style="text-align:left;">List&lt;? super X&gt;</th>
<td>Ja</td>
<td>Object</td>
<td>Ja</td>
<td>X oder Subtypen von X</td>
</tr>
</table>
<p>Bleibt nur noch die Frage zu klären, warum man in eine List&lt;? super X&gt; Elemente vom Typ X und Subtypen von X einfügen darf. Bei List&lt;? extends X&gt; ist das schließlich auch nicht möglich. Nunja, bei <em>extends X</em> sind die Elemente der Liste vom Typ X oder Subtypen davon, d.h. <em>spezieller</em>. Bei <em>super X</em> sind die Elemente vom Typ X oder Supertypen von X, d.h. <em>allgemeiner</em>. Daher kann man Objekte vom Typ X oder von einem Subtyp von X nach Belieben in eine solche Liste einfügen, weil man Objekte von einem bestimmten Typ immer zu einem allgemeineren Typ konvertieren kann.<br />
Faustregel: Jeder Apfel ist ein Obst, aber nicht jedes Obst ein Apfel!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertnitsch.de/2009/03/31/java-generics-vs-java-listen/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Mathematiker stehlen Lebenszeit</title>
		<link>http://www.robertnitsch.de/2009/02/21/mathematiker-stehlen-lebenszeit/</link>
		<comments>http://www.robertnitsch.de/2009/02/21/mathematiker-stehlen-lebenszeit/#comments</comments>
		<pubDate>Sat, 21 Feb 2009 20:39:55 +0000</pubDate>
		<dc:creator>Robert</dc:creator>
				<category><![CDATA[Informatik]]></category>
		<category><![CDATA[Mathematik]]></category>
		<category><![CDATA[Real Life]]></category>
		<category><![CDATA[Studium]]></category>

		<guid isPermaLink="false">http://www.robertnitsch.de/?p=199</guid>
		<description><![CDATA[[Hinweis: Dieser Artikel gibt meine persönliche Meinung wieder.] So&#8230; es muss jetzt mal raus. Seit Montag haben wir Semesterferien, d.h. es gibt keine Vorlesungen/Übungen mehr und wir bereiten uns jetzt auf die Prüfungen vor. Die erste Prüfung ist Mathematik für Informatiker I. Ich habe daher seit Montag jeden Tag etwas geübt und auch damit angefangen, [...]]]></description>
			<content:encoded><![CDATA[<p><em>[Hinweis: Dieser Artikel gibt meine persönliche Meinung wieder.]</em></p>
<p>So&#8230; es muss jetzt mal raus. Seit Montag haben wir Semesterferien, d.h. es gibt keine Vorlesungen/Übungen mehr und wir bereiten uns jetzt auf die Prüfungen vor. Die erste Prüfung ist <strong>Mathematik für Informatiker I</strong>.</p>
<p>Ich habe daher seit Montag jeden Tag etwas geübt und auch damit angefangen, das <a href="https://www3.mathematik.tu-darmstadt.de/fb/mathe/lehre-und-studium/elektronisches-veranstaltungssystem.html?evsid=32&#038;evsver=30&#038;evsdir=100&#038;evsfile=Skript.pdf" class="lipdf">Mathe-Skript</a> vom Professor mal <em>ernsthaft</em> und <em>konzentriert</em> durchzugehen. Das heißt, dass ich v.a. versuche, die vielen Beweise zu verstehen, um die ich bisher häufig einfach einen Bogen gemacht habe. Diese Beweise sind allerdings bis auf ganz wenige Ausnahmen absolut unverständlich&#8230; es werden z.B. ständig die unmöglichsten Umformungen gemacht ohne, dass das auch nur in einer Randnotiz vermerkt wäre &#8211; zum Kotzen!</p>
<p>Nach einem vollen Semester Mathematik &#8211; in dem ich mir wirklich Mühe gegeben habe, zu verstehen, was der Professor da immer predigt &#8211; und nach mehrfachen Versuchen, den Mathematikern doch noch eine Chance zu geben, lautet mein Fazit ein für allemal:</p>
<ul>
<li>Mathematiker erklären ihr Fach absichtlich schlecht, obwohl sie selbst bspw. von Beweisen fordern, dass sie bloß gut kommentiert und nachvollziehbar sein sollen</li>
<li>Mathematiker stehlen dadurch Lebenszeit, die man auch besser nutzen könnte (um mal auf den Titel zurückzukommen)</li>
</ul>
<p>Ich bin ja sowas von <em>angepisst</em> von dieser abartigen Arroganz, die die Mathematiker bei uns an der Uni an den Tag legen&#8230; das ist ja sowas von erbärmlich. Es gibt nichts, was der dümmste Dorftrottel nicht besser erklären könnte als ein Mathematiker &#8211; ich kann mir jedenfalls nichts vorstellen.<br />
So oft haben meine Kommilitonen und ich schon gestöhnt <em>&#8220;oh man, das ist doch eigentlich total einfach&#8221;</em>, nachdem wir endlich etwas verstanden hatten, was uns die lieben Mathematiker auf die gottverdammt dämlichste Art und Weise versuchten, beizubringen (dieses Gefühl wird wohl jeder kennen).</p>
<p>Warum tun sich Mathematiker so schwer damit, ihr Fach menschlich zu erklären? Der Formalismus beißt sich nämlich kein bisschen mit Verständlichkeit (das Gegenteil wird immer von Mathematikern behauptet)!<br />
Ich schätze, dass die Mathematiker einfach nicht wollen, dass man ihr Fach so darstellt, wie es nunmal ist: relativ simpel, wenn man&#8217;s vernünftig erklärt. Oder es ist einfach eine sehr alte Tradition und jeder Professor sagt sich <em>&#8220;warum sollen es die Studenten von heute besser haben als ich &#8211; die sollen auch schuften müssen, auf die vernünftigen Erklärungen scheiße ich&#8221;</em>&#8230;</p>
<p>Zum Schluss möchte ich noch eines sagen: Mathe ist nur eine von 4 Lehrveranstaltungen in diesem Semester. Jede Lehrveranstaltung hat es gewaltig in sich &#8211; und man ist gelegentlich immer mal frustriert. Das ist normal, wenn man studiert &#8211; erst Recht bei Informatik (es ist einfach <strong>schwer</strong>). Aber nirgends ist es a) so heftig wie bei Mathematik und b) nirgends habe ich auch nur den geringsten Anlass dazu zu denken, dass die Professoren/Tutoren ihr Fach mit Absicht schwer erklären. Im Gegenteil: Überall versucht man den Stoff so verständlich und anschaulich rüberzubringen wie nur irgendwie möglich! Nur bei Mathe nicht. Da ist es gerade andersrum&#8230; und DAS ist es, was mich so sauer macht.<br />
Außerdem ist es so, dass Mathematik nicht nur bei uns so verhasst ist. Von verschiedenen Leuten aus meinem Abi-Jahrgang und von Studenten aus anderen Fachbereichen höre ich (im Wesentlichen) genau dasselbe.</p>
<p>Letztenendes muss ich da so oder so durch &#8211; und ich werde es schaffen! Und von Zeit zu Zeit werde ich den Mathematikern gehörig in den Arsch treten, indem ich ihnen zeige, wie man es besser macht&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertnitsch.de/2009/02/21/mathematiker-stehlen-lebenszeit/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Das Studentenleben an der Universität</title>
		<link>http://www.robertnitsch.de/2008/11/01/das-studentenleben-an-der-universitat/</link>
		<comments>http://www.robertnitsch.de/2008/11/01/das-studentenleben-an-der-universitat/#comments</comments>
		<pubDate>Sat, 01 Nov 2008 21:04:56 +0000</pubDate>
		<dc:creator>Robert</dc:creator>
				<category><![CDATA[Erfahrungsberichte]]></category>
		<category><![CDATA[Informatik]]></category>
		<category><![CDATA[Mathematik]]></category>
		<category><![CDATA[Real Life]]></category>
		<category><![CDATA[Schule]]></category>
		<category><![CDATA[Studium]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.robertnitsch.de/?p=130</guid>
		<description><![CDATA[In diesem Artikel möchte ich aus meiner Sicht als Erstsemester kurz und knapp beschreiben, was man als Student während der Vorlesungszeit so macht. Als ich noch Schüler war, habe ich mir einen solchen Text gewünscht. Die Beschreibungen beziehen sich auf meine eigenen Erfahrungen. Ich bemühe mich zwar, alles so allgemein wie möglich zu halten, kann [...]]]></description>
			<content:encoded><![CDATA[<p>In diesem Artikel möchte ich aus meiner Sicht als Erstsemester kurz und knapp beschreiben, was man als Student während der Vorlesungszeit so macht. Als ich noch Schüler war, habe ich mir einen solchen Text gewünscht. Die Beschreibungen beziehen sich auf meine eigenen Erfahrungen. Ich bemühe mich zwar, alles so allgemein wie möglich zu halten, kann aber nicht dafür garantieren, dass es an anderen Universitäten nicht wesentlich anders abläuft. Ich kann auch nicht garantieren, dass alle Angaben korrekt sind und behalte mir Fehler vor. Feedback ist sehr erwünscht, vor allem wenn bestimmte Sachverhalte nicht ausreichend erklärt wurden bzw. unklar sind!</p>
<p>Wichtigster Unterschied zur Schule ist, dass an der Universität keine Allgemeinbildung gelehrt wird. Man kann stattdessen einen von vielen vielen vielen <strong>Studiengängen</strong> wählen. An manchen Universitäten werden mehr Studiengänge angeboten, an anderen weniger. <em>Ich</em> studiere momentan <strong>B.Sc. Informatik</strong> an der TU Darmstadt. B.Sc. bedeutet <strong>Bachelor of Science</strong> und ist ungefähr gleichwertig mit einem Vordiplom. Wenn man diesen Abschluss erreicht hat, dann bedeutet dies, dass man das <strong>Grundstudium</strong> abgeschlossen hat und das Hauptstudium, in welchem man sich i.d.R. weiter spezialisiert, antreten kann.</p>
<p>Jeder Studiengang besteht aus einer bestimmten <strong>Anzahl von Semestern</strong> &#8211; B.Sc. Informatik hat 6 Semester. Jedes Semester ist ein halbes Jahr lang &#8211; man unterscheidet zwischen <strong>Wintersemester</strong> (1. Oktober bis 31. März) und <strong>Sommersemester</strong> (1. April bis 30. September).</p>
<p>Jedes Semester wiederum besteht aus bestimmten <b>Lehrveranstaltungen</b>. Eine Lehrveranstaltung heißt zum Beispiel <a href="https://www3.mathematik.tu-darmstadt.de/?id=84&#038;evsid=23&#038;evsver=30" class="liexternal"><b>&#8220;Mathematik I für Inf und WInf&#8221;</b></a> (Inf=Informatiker, WInf = Wirtschaftsinformatiker) und besteht mindestens aus den zugehörigen <strong>Vorlesungen</strong>, <strong>Übungen</strong> und <strong>Prüfungen</strong>. Jede Lehrveranstaltung wird außerdem von einem <strong>Professor</strong>, dem verschiedene Hilfskräfte zur Seite stehen, geleitet.</p>
<p>In den <strong>Vorlesungen</strong>, die in sehr großen Hörsälen von dem jeweiligen Professor gehalten werden, wird der Stoff in sehr schnellem Tempo abgehandelt. Meistens muss man daher nach der Vorlesung einiges nacharbeiten, um den Stoff auch wirklich zu verinnerlichen. Die Vorlesungen dauern jeweils 2 <strong>Semesterwochenstunden (SWS)</strong>, von denen jede 45 Minuten lang ist. Generell wird an der Universität vieles in Semesterwochenstunden gemessen. Werden für eine Vorlesung zum Beispiel 4 SWS angeben, so heißt das, dass man in dem Semester jede Woche <em>durchschnittlich</em> (!) 4&#215;45 Minuten Vorlesung hat.<br />
(Die Teilnahme an den Vorlesungen ist nicht verpflichtend, aber ratsam.)</p>
<p>Beim Lernen des Stoffes helfen die <strong>Übungen</strong>, die von den Veranstaltern angeboten werden. Eine Übung findet meistens einmal pro Woche oder alle 2 Wochen statt und dauert i.d.R. 2&#215;45 Minuten. Da man nicht alle Hörer der Vorlesung in einer einzigen Übung betreuen kann, werden die Studenten verschiedenen <strong>Übungsgruppen</strong> zugeteilt. Jede Übungsgruppe besteht i.d.R. aus etwa 20-40 Studenten (das ist bei mir so) und wird von einem <strong>Tutor</strong> geleitet. Die Aufgabe des Tutors ist es, den Studenten zu helfen und ihre Fragen so gut es geht zu beantworten.<br />
Man trifft sich dann schließlich zu bestimmten Zeiten mit seiner Übungsgruppe und dem Tutor in einer Räumlichkeit der Universität und bearbeitet verschiedene <strong>Gruppenaufgaben</strong> zum Vorlesungsstoff, die jeweils vor der Übung veröffentlicht und von den Studenten ausgedruckt und mitgebracht werden sollen. Bei der Bearbeitung der Aufgaben soll das Gelernte eingeübt werden.<br />
(Die Teilnahme an den Übungen ist aber meistens nicht verpflichtend, aber wie bei den Vorlesungen ratsam.)</p>
<p>Es gibt allerdings nicht nur Gruppenaufgaben, sondern auch Hausaufgaben. Sie werden <b>Hausübungen</b> genannt. Diese Hausübungen sollen am besten alleine bearbeitet werden, damit man sich auch wirklich sicher sein kann, dass man die Aufgaben selbstständig lösen kann. Meistens ist es erlaubt, die Hausübungen auch in (kleinen!) Gruppen zu lösen &#8211; dies muss aber explizit angegeben werden und es muss trotzdem jeder Student seine eigene Lösung abgeben.</p>
<p>Die Hausübungen <em>kann</em> man am jeweils nächsten Übungstermin bei seinem Tutor abgeben (Anmerkung: bei manchen Lehrveranstaltungen kann man die Hausübungen auch online abgeben, natürlich besonders häufig in der Informatik und ähnlichen Fächern). Der Tutor wird die Lösungen dann bis zum nächsten Übungstermin korrigieren, ggf. sogar mit Anmerkungen versehen (wie man die Aufgabe z.B. hätte besser lösen können o.ä.).<br />
Wichtig: Bei vielen Lehrveranstaltungen steht es dem Studenten frei, ob er seine Hausübung bearbeitet und abgibt (auch, wenn er es im eigenen Interesse tun sollte).<br />
Bei manchen Lehrveranstaltungen werden die Hausübungen allerdings bewertet. Man nennt dies dann <strong>bewertete Hausübungen</strong>. Der Veranstalter kann dann zum Beispiel vorschreiben, dass man mindestens 50% der Punkte in den (bewerteten) Hausübungen erreichen muss, um für die Prüfung zugelassen zu werden. Die Bewertung wird von dem jeweiligen Tutor vorgenommen. Die Abgabe der Hausübungen ist bei solchen Lehrveranstaltungen natürlich Pflicht &#8211; ansonsten erhält man keine Punkte.</p>
<p>Zusätzlich zu den Vorlesungen und den Übungen gibt es bei manchen Lehrveranstaltungen auch noch <strong>Praktika</strong>, <strong>Seminare</strong> und weitere.<br />
Praktika sind zum Beispiel bei <strong>&#8220;Grundlagen der Informatik I&#8221;</strong> kleine Softwareprojekte, die ebenfalls benotet werden. Dabei kommt es vor allem darauf an, das Gelernte anzuwenden. Auch die Planung usw. fließen in die Bewertung ein.<br />
Seminare <del datetime="2009-01-01T16:50:34+00:00">sind, soweit ich das bisher überblicken kann, benotete Vorträge, für die sich Studenten selbstständig etwas tiefer in eine bestimmte Thematik einarbeiten mussten.</del> sind Lehrveranstaltungen kleineren Umfangs (meist über einige Wochen), an deren Ende das Gelernte entweder mit einer Hausarbeit oder einem Vortrag überprüft wird, woraus dann eine Note hervorgeht.</p>
<p>In den <strong>Prüfungen</strong> (der üblichen Lehrveranstaltungen) stellt sich schließlich heraus, ob die Studenten das nötige Wissen verinnerlicht haben und unter Zeitdruck anwenden können. Manche Prüfungen sind übrigens geteilt in zwei einzelne Klausuren (die dann für das Gesamtergebnis zusammengerechnet werden). Die Prüfungen finden während der <strong>Semesterferien</strong> statt. Es handelt sich also gar nicht um echte Ferien &#8211; es werden lediglich keine Vorlesungen mehr gehalten, daher auch <strong>vorlesungsfreie Zeit</strong> genannt.<br />
Zu den Prüfungen ist anzumerken, dass die Veranstalter teilweise komplizierte eigene Regelungen vorsehen. So ist es beispielsweise bei manchen Lehrveranstaltungen so, dass überschüssige Punkte aus den bewerteten Hausübungen zur Verbesserung der Prüfungsnote genutzt werden können. Wenn man sich in den entsprechenden Hausübungen gut schlägt, kann man seine Prüfungsnote am Ende also nochmal deutlich verbessern!<br />
Weiterhin ist zu sagen, dass man die Prüfungen in der Regel relativ leicht schaffen sollte, wenn man die Vorlesungen und Übungen regelmäßig besucht und seine Hausübungen macht. Der Stoff ist schwer, aber man bekommt viel Unterstützung bis zur Prüfung.</p>
<p>Wenn man eine Prüfung nicht besteht, muss man sie &#8211; wenn möglich &#8211; in einem späteren Semester wiederholen oder das Studium abbrechen. Meistens hat man eine begrenzte Anzahl von Versuchen.</p>
<p>Das waren so die wichtigsten Elemente des reinen Studentenlebens.<br />
Während der Vorlesungszeit geht man in die Vorlesungen, besucht die Übungen, macht seine Hausübungen usw. Wie viel Zeit das etwa kostet, kann ich noch nicht genau beschreiben, weil es im 1. Semester natürlich etwas langsamer los geht. Für die zweite Hausübung von <em>Grundlagen der Informatik I</em> habe ich aber immerhin fast 4 Stunden gebraucht. (Ich werde in einigen Wochen, wenn es richtig hart wird, an dieser Stelle einen kleinen Aufwandsvergleich zur Oberstufe einfügen.)<br />
Wenn die Vorlesungen dann vorbei sind, bereitet man sich auf die Klausuren vor. Das schwierigste dabei ist, dass es die meiste Zeit über niemanden gibt, der einen dazu zwingt, zu lernen. Es gibt Menschen, die damit besser umgehen können und es gibt Menschen, die damit eher nicht zurecht kommen &#8211; und der Stoff ist wirklich hart.</p>
<p>Alles in allem macht mir persönlich das Studium bisher wirklich Spaß! Das liegt zum einen daran, dass der Stoff wirklich anspruchsvoll ist und man definitiv nicht gelangweilt ist. Zum anderen ist es schlicht und ergreifend so, dass der Anteil dessen, was mich absolut nicht interessiert, sehr gering ist. Diese ganzen Schulfächer, die man ohne Weiteres aus dem Lehrplan streichen könnte, gibt es jetzt nicht mehr. <img src='http://www.robertnitsch.de/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Als letzter Hinweis sei noch gesagt, dass für <strong>Erstsemester (Ersties)</strong> von der Universität oder von höhersemestrigen Studenten sogenannte <strong>Orientierungsphasen</strong> bzw. <strong>Einführungswochen</strong> angeboten werden. Alles, was in diesem Artikel beschrieben ist und noch viel viel mehr, wird dann innerhalb von 1 Woche o.ä. ausführlich erklärt. Man wird also auf keinen Fall im Regen stehen gelassen. <img src='http://www.robertnitsch.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertnitsch.de/2008/11/01/das-studentenleben-an-der-universitat/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
