<?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; Informatik</title>
	<atom:link href="http://www.robertnitsch.de/category/informatik/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>Datei-Backups leicht gemacht mit WinRAR</title>
		<link>http://www.robertnitsch.de/2010/01/11/datei-backups-leicht-gemacht-mit-winrar/</link>
		<comments>http://www.robertnitsch.de/2010/01/11/datei-backups-leicht-gemacht-mit-winrar/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 15:00:30 +0000</pubDate>
		<dc:creator>Robert</dc:creator>
				<category><![CDATA[Erfahrungsberichte]]></category>
		<category><![CDATA[Informatik]]></category>
		<category><![CDATA[PC]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://www.robertnitsch.de/?p=413</guid>
		<description><![CDATA[WinRAR kann man ganz leicht als Backup-Tool für Dateien und Verzeichnisse nutzen. Das hat einige Vorteile: Der Backup-Vorgang ist durchschaubar bzw. leicht nachvollziehbar, weil es sich um einen gewöhnlichen Packer handelt und nicht um eine spezielle Backup-Software, bei der man so genau gar nicht weiß, wie sie arbeitet (das kann ich persönlich gar nicht leiden). [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.winrar.de" class="liexternal">WinRAR</a> kann man ganz leicht als Backup-Tool für Dateien und Verzeichnisse nutzen. Das hat einige Vorteile:</p>
<ul>
<li>Der Backup-Vorgang ist durchschaubar bzw. leicht nachvollziehbar, weil es sich um einen gewöhnlichen Packer handelt und nicht um eine spezielle Backup-Software, bei der man so genau gar nicht weiß, wie sie arbeitet (das kann ich persönlich gar nicht leiden).</li>
<li>RAR-Dateien kann man (im Gegensatz zu den meisten Backup-Containern kommerzieller Backup-Software, bspw. Acronis True Image) nahezu auf jeder Plattform entpacken, weil der Entpack-Algorithmus öffentlich verfügbar ist. Das gilt natürlich auch für ZIP, 7zip und die meisten anderen Archiv-Formate.</li>
<li>Das RAR-Format unterstützt sogenannte <em>recovery records</em> (Wiederherstellungsinformationen). Kleinere Schäden an der Backup-Datei (Beispiel: ein paar Sektoren auf der Festplatte spielen verrückt) können damit behoben werden.</li>
<li>Die Verschlüsselung von RAR-Dateien erfolgt &#8211; wenn gewünscht &#8211; mit <a href="http://de.wikipedia.org/wiki/Advanced_Encryption_Standard" rel="nofollow" class="liwikipedia">AES-128</a>. Dieser Standard gilt als sicher.</li>
</ul>
<p>Im Folgenden zeige ich mit welchen Einstellungen man WinRAR für Backups optimiert.</p>
<h3>Einstellungen: &#8220;Allgemein&#8221;</h3>
<p><a href="http://www.robertnitsch.de/wp-content/uploads/2010/01/00_Allgemein.png" class="liimagelink"><img src="http://www.robertnitsch.de/wp-content/uploads/2010/01/00_Allgemein.png" alt="WinRAR - Allgemeine Einstellungen" title="00_Allgemein" width="452" height="411" class="alignright size-full wp-image-423" /></a></p>
<ol>
<li>Ziel-Datei: In welcher Archivdatei sollen die Dateien gesichert werden?</li>
<li>Update-Modus: Das Backup-Archiv soll mit den Quelldaten synchronisiert werden. Das bedeutet, dass neue Dateien hinzugefügt, geänderte Dateien erneuert und gelöschte Dateien auch im Backup gelöscht werden. Hierdurch werden außerdem das 2. und alle folgenden Backups stark beschleunigt, weil quasi-inkrementelle Backups gemacht werden.</li>
<li>Kompressions-Methode: Damit das Komprimieren nicht zu viel Zeit in Anspruch nimmt stellen wir die Kompression auf eine schwächere aber schnellere Stufe.</li>
<li>Authentizitätsinformationen hinzufügen: Fügt bei der Erstellung des Archivs nochmal einige allgemeine Daten wie Archivname etc. in das Archiv ein. Diese werden beim späteren Öffnen des Archivs geprüft, um grobe Manipulationen zu verhindern. Bietet zwar wenig Sicherheit, kostet aber auch nichts.</li>
<li>Wiederherstellungs-Informationen hinzufügen: Hier handelt es sich um den oben beschriebenen <em>recovery record</em>. Unter <em>Erweitert</em> kann man dieses Feature genauer konfigurieren.</li>
</ol>
<div style="clear:both;"></div>
<h3>Einstellungen: &#8220;Erweitert&#8221;</h3>
<p><a href="http://www.robertnitsch.de/wp-content/uploads/2010/01/01_Erweitert.png" class="liimagelink"><img src="http://www.robertnitsch.de/wp-content/uploads/2010/01/01_Erweitert.png" alt="WinRAR - Erweiterte Einstellungen" title="01_Erweitert" width="441" height="400" class="alignright size-full wp-image-431" /></a></p>
<p>Einstellungen, die sehr nützlich sind, aber dem persönlichen Gutdünken obliegen, habe ich blau eingerahmt.</p>
<p>Zu den roten Markierungen:</p>
<ol>
<li>Datenströme speichern: Sehr wichtig, wenn NTFS als Dateisystem eingesetzt wird. Einige Applikationen legen in zusätzlichen NTFS-Dateiströmen einige Informationen ab, die nicht zu den Dateiinhalten selbt gehören, aber mit den jeweiligen Dateien verknüpft sind. Es handelt sich quasi um eine Art von <em>Meta-Informationen</em>, die ohne diese Einstellungen verlorengehen würden.</li>
<li>Wiederherstellungs-Informationen: Hiermit legt man fest, wie groß der prozentuale Anteil des recovery records am Archiv sein soll. 2-5% halte ich für angemessen. Standard ist übrigens 1%.</li>
</ol>
<p>Zu den &#8220;Volumen&#8221;-Einstellungen: Diese sind nur nutzbar, wenn man das Backup-Archiv in mehrere Teilarchive aufsplittet. Dazu muss man eine Volumengröße unter &#8220;Allgemein&#8221; angeben.<br />
Jedes &#8220;Wiederherstellungs-Volumen&#8221; kann genau 1 Original-Volumen wiederherstellen, sogar dann, wenn dieses komplett verloren gegangen ist. Angenommen man hat 30 Teil-Archive (&#8220;Volumen&#8221;) und 3 Wiederherstellungsvolumen, dann dürfen bis zu 3 Volumen verlorengehen bzw. beschädigt werden. Im Zweifel lohnt sich hier ein Blick in die WinRAR-Hilfe.</p>
<div style="clear:both;"></div>
<h3>Einstellungen: &#8220;Dateien&#8221;</h3>
<p><a href="http://www.robertnitsch.de/wp-content/uploads/2010/01/02_Dateien.png" class="liimagelink"><img src="http://www.robertnitsch.de/wp-content/uploads/2010/01/02_Dateien.png" alt="WinRAR - &quot;Dateien&quot;" title="02_Dateien" width="452" height="411" class="alignright size-full wp-image-444" /></a></p>
<p>Der wahrscheinlich wichtigste Teil am Backup: Die zu sichernden Dateien bzw. Verzeichnisse müssen ausgewählt werden.</p>
<p>Hier kann man außerdem bestimmte Dateien bzw. Verzeichnisse vom Backup ausschließen. Bei mir gehören zum Beispiel Downloads definitiv zu den ausgeschlossenen Daten. *.tmp sowie *.bak-Dateien brauchen genausowenig gesichert zu werden.</p>
<p>Ebenfalls sehr nützlich ist es, bestimmte Dateien zwar zu sichern, aber dabei von der Kompression auszuschließen. Das macht das Backup dieser Dateien/Dateitypen deutlich schneller. Zum Beispiel macht es wenig Sinn *.rar, *.zip oder *.jpg-Dateien zu komprimieren, weil diese Dateien bereits komprimiert vorliegen. Ein paar weitere Vorschläge für diesen Filter: *.mp3 *.avi *.mpg</p>
<p>Aufpassen muss man bei der Struktur des zu erzeugenden Archivs. Ich spreche mich sehr stark für die Einstellung <em><strong>&#8220;Volle Pfade inkl. Laufwerksbuchstaben&#8221;</strong></em> aus, damit nicht nur die Daten selbst, sondern auch ihr genauer Ablageort jederzeit wiederherstellbar bzw. nachvollziehbar ist. In der Standardeinstellung gehen diese Informationen verloren und bei vielen Dateien wird das sehr schnell sehr hässlich, weil man nicht mehr unterscheiden kann, woher die Dateien/Ordner im Einzelnen gekommen sind.</p>
<div style="clear:both;"></div>
<h3>Einstellungen: &#8220;Backup&#8221;</h3>
<p><a href="http://www.robertnitsch.de/wp-content/uploads/2010/01/03_Backup.png" class="liimagelink"><img src="http://www.robertnitsch.de/wp-content/uploads/2010/01/03_Backup.png" alt="WinRAR - &quot;Backup&quot;" title="03_Backup" width="452" height="411" class="alignright size-full wp-image-450" /></a></p>
<p>Wie der Name sagt sind diese Einstellungen speziell für Backups vorgesehen.</p>
<p><strong>&#8220;Gemeinsam genutzte Dateien öffnen&#8221;</strong> sorgt dafür, dass WinRAR versucht, auch momentan durch andere Programme geöffnete Dateien zu sichern. Nichtsdestotrotz wird WinRAR das bei vielen Dateien mit einer Fehlermeldung quittieren. Das ist aber völlig normal.</p>
<p><strong>&#8220;Archivnamen aus folgender Maske erzeugen&#8221;</strong> hängt an den Archivnamen eine Zeichenkette an, die dynamisch zum Beispiel aufgrund der aktuellen Kalenderwoche erzeugt wird. In meinem Fall wird &#8220;yyyymm&#8221; angehängt, also z.B. &#8220;201001&#8243;. Dadurch wird maximal 1 Monat lang einunddasselbe Archiv genutzt (&#8220;RobertBackup201001.rar&#8221;). Für den nächsten Monat erzeugt WinRAR automatisch ein neues Archiv (&#8220;RobertBackup201002.rar&#8221;).<br />
Folgende Zeichen werden in der Maske akzeptiert (aus der WinRAR &#8211; Hilfe; dort findet man weitere nützliche Details):</p>
<table>
<tr>
<th>Y</th>
<td>Jahr</td>
</tr>
<tr>
<th>M</th>
<td>Monat</td>
</tr>
<tr>
<th>MMM</th>
<td>Monatsnamen (Jan, Feb, usw.)</td>
</tr>
<tr>
<th>W</th>
<td>Kalenderwoche (eine Woche beginnt mit einem Montag)</td>
</tr>
<tr>
<th>A</th>
<td>Tag der Woche (Montag ist 1, Sonntag ist 7)</td>
</tr>
<tr>
<th>D</th>
<td>Tag des Monats</td>
</tr>
<tr>
<th>E</th>
<td>Tag des Jahres</td>
</tr>
<tr>
<th>H</th>
<td>Stunden</td>
</tr>
<tr>
<th>M</th>
<td>Minuten (wird als Minuten behandelt, wenn es nach Stunden auftritt)</td>
</tr>
<tr>
<th>S</th>
<td>Sekunden</td>
</tr>
<tr>
<th>N</th>
<td>Archivnummer. WinRAR sucht nach einem bereits vorhandenen Archiv mit dem erzeugten Namen und erhöht im Falle der Existenz die Archivnummer, bis ein eindeutiger Name erzeugt wurde. Das Formatzeichen &#8216;N&#8217; wird beim Erstellen von mehrteiligen Archiven (Volumen) nicht unterstützt.</td>
</tr>
</table>
<p>Damit kann man schon eine ganze Menge erreichen. In diesem Punkt steht WinRAR kommerzieller Backup-Software in nichts nach, eher im Gegenteil. Lediglich das Löschen alter Archive geschieht nicht so leicht automatisch, da muss man schon noch selbst Hand anlegen. Aber um ehrlich zu sein lösche ich meine Backups auch viel lieber selbst&#8230;</p>
<div style="clear:both;"></div>
<h3>Kommentar hinzufügen</h3>
<p>Im letzten Reiter kann man dem Archiv einen Kommentar hinzufügen. Beispiel:</p>
<blockquote><p>In diesem Backup enthalten:<br />
C:\Users\Robert\<br />
D:\eclipse</p>
<p>Ausgeschlossen:<br />
C:\Users\Robert\Downloads *.tmp *.bak </p>
<p>Backup-Methode: Synchronisation (geänderte/neue Dateien werden hinzugefügt/überschrieben, gelöschte Dateien werden aus dem Archiv gelöscht)</p></blockquote>
<h3>Speichern der Einstellungen als Profil</h3>
<p><a href="http://www.robertnitsch.de/wp-content/uploads/2010/01/04_Profile.png" class="liimagelink"><img src="http://www.robertnitsch.de/wp-content/uploads/2010/01/04_Profile.png" alt="WinRAR - &quot;Aktuelle Einstellungen als Profil speichern...&quot;" title="04_Profile" width="452" height="411" class="alignright size-full wp-image-455" /></a></p>
<p>Nun wäre das ganze ziemlich mühselig, wenn man all diese Einstellungen jedes Mal aufs Neue festlegen müsste. Dafür bietet WinRAR sogenannte Profile an. Unter &#8220;Allgemein&#8221; kann man seine Einstellungen auf diese Weise für das nächste Mal speichern (siehe Bild auf der rechten Seite).</p>
<p><strong>Nicht vergessen im folgenden Dialog die ersten beiden Haken anzukreuzen! Außerdem empfehle ich einen Haken bei &#8220;Verknüpfung auf dem Desktop anlegen&#8221;.</strong> Diese Verknüpfung sollte man immer mit Administratorrechten ausführen (kann man in den Einstellungen derselben auch dauerhaft festlegen).</p>
<div style="clear:both;"></div>
<h3>Fazit</h3>
<p>Backups mit WinRAR sind schnell, klein, übersichtlich, leicht zu konfigurieren und sicher. Mit Hilfe der Einstellung <strong>&#8220;Archivnamen aus folgender Maske erzeugen&#8221;</strong> kann man zudem eine automatische Konsolidierung der Backups umsetzen.</p>
<p>Was will man mehr?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertnitsch.de/2010/01/11/datei-backups-leicht-gemacht-mit-winrar/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Virtual server / VPS vs. Java: &#8220;Could not reserve enough space for object heap&#8221;</title>
		<link>http://www.robertnitsch.de/2009/12/18/virtual-server-vps-vs-java-could-not-reserve-enough-space-for-object-heap/</link>
		<comments>http://www.robertnitsch.de/2009/12/18/virtual-server-vps-vs-java-could-not-reserve-enough-space-for-object-heap/#comments</comments>
		<pubDate>Thu, 17 Dec 2009 22:44:17 +0000</pubDate>
		<dc:creator>Robert</dc:creator>
				<category><![CDATA[Informatik]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[PC]]></category>

		<guid isPermaLink="false">http://www.robertnitsch.de/?p=375</guid>
		<description><![CDATA[Today I encountered the following error message on my virtual server: Error occurred during initialization of VM Could not reserve enough space for object heap Could not create the Java virtual machine. This error message occurred every single time Java was involved in something&#8230; Even &#8220;java -version&#8221; crashed&#8230; After several hours I figured out it [...]]]></description>
			<content:encoded><![CDATA[<p>Today I encountered the following error message on my virtual server:</p>
<blockquote><p>Error occurred during initialization of VM<br />
Could not reserve enough space for object heap<br />
Could not create the Java virtual machine.</p></blockquote>
<p>This error message occurred every single time Java was involved in something&#8230; Even &#8220;java -version&#8221; crashed&#8230;</p>
<p>After several hours I figured out it was not a problem of having too less memory but instead a problem of having too much free memory. In particular, my system (a <em>virtual</em> server) always seems to have a lot of free memory, which is in fact used by the other virtual server instances on the same physical machine. Thus, Java attempts to allocate a very big part of the memory (expecting it is not used otherwise). The memory allocation fails and Java crashes with the deceptive message &#8220;Could not reserve enough space for object heap&#8221;. At least this is my explanation so far&#8230;</p>
<h3>The solution</h3>
<p>The problem can be fixed by manually specifying the <strong>maximum</strong> heapsize. E.g., execute &#8220;java -Xmx128m -version&#8221; instead of &#8220;java -version&#8221;.</p>
<p>Since it is a pain and sometimes almost impossible to enable this commandline parameter (think of applications making use of java indirectly) you can make it the default by changing the environment variable <strong>_JAVA_OPTIONS</strong>. Either edit <em>/etc/environment</em> (persistent solution) or execute</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">export _JAVA_OPTIONS=&quot;-Xmx128m&quot;</pre></div></div>

<p>(solves the issue only for the current session).</p>
<p>It worked for me and I&#8217;m running Ubuntu 8.04 on a VPS hosted by Hosteurope.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertnitsch.de/2009/12/18/virtual-server-vps-vs-java-could-not-reserve-enough-space-for-object-heap/feed/</wfw:commentRss>
		<slash:comments>0</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>Trafficshaping mit cFosSpeed &#8211; Die ultimative Internet-Optimierung</title>
		<link>http://www.robertnitsch.de/2009/02/07/trafficshaping-mit-cfosspeed-die-ultimative-internet-optimierung/</link>
		<comments>http://www.robertnitsch.de/2009/02/07/trafficshaping-mit-cfosspeed-die-ultimative-internet-optimierung/#comments</comments>
		<pubDate>Sat, 07 Feb 2009 12:51:31 +0000</pubDate>
		<dc:creator>Robert</dc:creator>
				<category><![CDATA[Erfahrungsberichte]]></category>
		<category><![CDATA[Informatik]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[PC]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://www.robertnitsch.de/?p=193</guid>
		<description><![CDATA[Neulich habe ich durch Zufall von cFosSpeed gehört, einer Software, die sogenanntes Trafficshaping betreibt. Das Trafficshaping von cFosSpeed ermöglicht die Priorisierung von Protokollen und/oder Anwendungen bei dem Zugriff auf das Internet. Das führt dazu, dass man auch während größerer Downloads mit gefühlter voller Bandbreite surfen kann (habe ich selbst getestet und kann ich zu 100% [...]]]></description>
			<content:encoded><![CDATA[<p>Neulich habe ich durch Zufall von <a href="http://www.cfos.de/speed/cfosspeed.htm" class="liexternal">cFosSpeed</a> gehört, einer Software, die sogenanntes Trafficshaping betreibt. Das Trafficshaping von cFosSpeed ermöglicht die Priorisierung von Protokollen und/oder Anwendungen bei dem Zugriff auf das Internet.</p>
<p>Das führt dazu, dass man auch während größerer Downloads mit gefühlter voller Bandbreite surfen kann (habe ich selbst getestet und kann ich zu 100% bestätigen). Man merkt dann kaum noch, dass die Leitung in Wirklichkeit voll ausgereizt ist (= optimal).</p>
<p>Ich habe es gestern auch mal auf die Spitze getrieben: Ich habe eine sehr große Datenmenge heruntergeladen und <em>währenddessen</em> über das Internet ein Strategiespiel gespielt (bei diesem Spiel kommt es v.a. auf gute Reaktionszeiten an, d.h. auf eine gute Internet-Verbindung). Normalerweise wäre das nicht möglich gewesen, da das Spiel dauernd geruckelt hätte usw. Da ich aber cFosSpeed klargemacht habe, dass der Download nicht so wichtig ist wie das Spiel, habe ich den Download im Hintergrund <em>nicht</em> beim Zocken gespürt. Dabei war die Leitung die ganze Zeit zu 100% ausgereizt. Die Bandbreite wurde von cFosSpeed einfach geschickt zwischen den Anwendungen aufgeteilt &#8211; entsprechend meiner Einstellungen.</p>
<p>Ganz ehrlich&#8230; für DSL 1000 &#8211; Kuhkaff &#8211; Menschen wie mich ist cFosSpeed eine erstklassige, wenn auch leider nicht kostenlose Software. Ich überlege mir ernsthaft, mir diese Software nach Ablauf der 30 Tage &#8211; Demo zuzulegen (zudem man lebenslang zu allen Updates/Upgrades Zugang hat).<br />
Die Bedienung von cFosSpeed ist zwar etwas gewöhnungsbedürftig, aber immerhin sind die populären Anwendungen/Prokotolle bereits vorkonfiguriert. So wird bspw. das Surfen und das Zocken von Anfang an mit einer hohen Priorität bedacht. Filesharing-Prokotolle werden auch schon von Haus aus &#8220;gedrosselt&#8221;. Sollte man doch mal eine Anwendung hinzufügen wollen, die nicht bereits in cFosSpeed eingetragen ist, dann ist das problemlos möglich.</p>
<p>Alles in allem kann ich cFosSpeed nur uneingeschränkt weiterempfehlen und hoffe, dass auch ihr von meiner &#8220;Entdeckung&#8221; profitiert. Probiert es einfach aus, es ist wirklich herrlich!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertnitsch.de/2009/02/07/trafficshaping-mit-cfosspeed-die-ultimative-internet-optimierung/feed/</wfw:commentRss>
		<slash:comments>2</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>
		<item>
		<title>Motivationskurve beim Erlernen einer Programmiersprache</title>
		<link>http://www.robertnitsch.de/2008/09/19/motivationskurve-beim-erlernen-einer-programmiersprache/</link>
		<comments>http://www.robertnitsch.de/2008/09/19/motivationskurve-beim-erlernen-einer-programmiersprache/#comments</comments>
		<pubDate>Fri, 19 Sep 2008 15:31:36 +0000</pubDate>
		<dc:creator>Robert</dc:creator>
				<category><![CDATA[Freaky]]></category>
		<category><![CDATA[Informatik]]></category>
		<category><![CDATA[Lustiges]]></category>
		<category><![CDATA[PC]]></category>
		<category><![CDATA[Programmieren]]></category>

		<guid isPermaLink="false">http://www.robertnitsch.de/?p=115</guid>
		<description><![CDATA[Peter Kroener hat eine geniale Grafik / Motivationskurve veröffentlicht, die die Motivation beim Erlernen einer neuen Programmiersprache beschreibt. Ich musste herzhaft lachen, weil mich die Kurve so sehr an meine eigenen Erfahrungen erinnert.]]></description>
			<content:encoded><![CDATA[<p>Peter Kroener hat eine <a href="http://www.peterkroener.de/die-neue-programmiersprache-lernen/" class="liexternal">geniale Grafik / Motivationskurve veröffentlicht</a>, die die Motivation beim Erlernen einer neuen Programmiersprache beschreibt. Ich musste herzhaft lachen, weil mich die Kurve so sehr an meine eigenen Erfahrungen erinnert. <img src='http://www.robertnitsch.de/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p><img style="margin-left:20px;" src="http://www.peterkroener.de/wp-content/uploads/2008/08/die-neue-programmiersprache-lernen-359x477.png" alt="Motivationskurve" border="1" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertnitsch.de/2008/09/19/motivationskurve-beim-erlernen-einer-programmiersprache/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Veröffentlichung der Lernleistung</title>
		<link>http://www.robertnitsch.de/2008/07/07/veroffentlichung-der-lernleistung/</link>
		<comments>http://www.robertnitsch.de/2008/07/07/veroffentlichung-der-lernleistung/#comments</comments>
		<pubDate>Mon, 07 Jul 2008 10:46:10 +0000</pubDate>
		<dc:creator>Robert</dc:creator>
				<category><![CDATA[Freaky]]></category>
		<category><![CDATA[Informatik]]></category>
		<category><![CDATA[Mathematik]]></category>
		<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Real Life]]></category>
		<category><![CDATA[Schule]]></category>

		<guid isPermaLink="false">http://www.robertnitsch.de/?p=99</guid>
		<description><![CDATA[Ich habe nun endlich meine Lernleistung veröffentlicht. Das Ganze hat sich wegen eines Festplattenfehlers verzögert. Außerdem fehlen nun einige ergänzende Texte, die ich speziell für die Veröffentlichung erstellt hatte. Jetzt muss erstmal das reichen, was in den Backups zu finden war, auch wenn es nun teilweise besonders schwer verdaulich ist.]]></description>
			<content:encoded><![CDATA[<p>Ich habe nun endlich <a href="http://www.robertnitsch.de/projekte/lernleistung/" class="liinternal">meine Lernleistung veröffentlicht</a>.<br />
Das Ganze hat sich wegen eines Festplattenfehlers verzögert. Außerdem fehlen nun einige ergänzende Texte, die ich speziell für die Veröffentlichung erstellt hatte. Jetzt muss erstmal das reichen, was in den Backups zu finden war, auch wenn es nun teilweise besonders schwer verdaulich ist.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertnitsch.de/2008/07/07/veroffentlichung-der-lernleistung/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Ideenklau 2.0</title>
		<link>http://www.robertnitsch.de/2008/05/19/ideenklau-20/</link>
		<comments>http://www.robertnitsch.de/2008/05/19/ideenklau-20/#comments</comments>
		<pubDate>Mon, 19 May 2008 11:37:49 +0000</pubDate>
		<dc:creator>Robert</dc:creator>
				<category><![CDATA[Freaky]]></category>
		<category><![CDATA[Informatik]]></category>
		<category><![CDATA[Real Life]]></category>

		<guid isPermaLink="false">http://www.robertnitsch.de/?p=93</guid>
		<description><![CDATA[Ich musste kürzlich mit Erstaunen feststellen, dass ich innerhalb kurzer Zeit zum wiederholten Male nicht der erste war, dem eine mehr oder weniger geniale Idee zugeflogen ist. Durch Zufall bin ich nämlich auf OpenID gestoßen, ein Single Sign-on-System, das ziemlich genau einem System entspricht, an dessen Entwicklung ich selbst schon gearbeitet habe und das dasselbe [...]]]></description>
			<content:encoded><![CDATA[<p>Ich musste kürzlich mit Erstaunen feststellen, dass ich innerhalb kurzer Zeit zum wiederholten Male nicht der erste war, dem eine mehr oder weniger geniale Idee zugeflogen ist.</p>
<p>Durch Zufall bin ich nämlich auf <a href="http://de.wikipedia.org/wiki/OpenID" rel="nofollow" class="liwikipedia">OpenID</a> gestoßen, ein <a href="http://de.wikipedia.org/wiki/Single_Sign-On" rel="nofollow" class="liwikipedia">Single Sign-on</a>-System, das ziemlich genau einem System entspricht, an dessen Entwicklung ich selbst schon gearbeitet habe und das dasselbe Ziel hat: Das Problem der vielen Accounts/Logins auf etlichen verschiedenen Webseiten zu lösen&#8230;</p>
<p>Das würde mich ja gar nicht stören (bis auf die Arbeit, die ja jetzt quasi umsonst war, weil der OpenID-Standard sich offenbar bereits durchgesetzt hat), wenn da nicht noch dieser andere Vorfall wäre:<br />
Als ich vor kurzem eine Variante des <a href="http://de.wikipedia.org/wiki/Transportproblem" rel="nofollow" class="liwikipedia">Transportproblems</a> lösen musste, ist mir ein schier genialer Algorithmus eingefallen, der bereits verdammt gute Näherungslösungen und in den meisten Fällen sogar optimale Ergebnisse lieferte. Damals wusste ich gar nicht, dass das Problem in der Wissenschaft bereits abgehandelt wurde und ich wusste auch nicht, dass es &#8220;Transportproblem&#8221; genannt wird. Aber es handelt sich in der Tat um eine <em>Variante</em> des eigentlichen Problems (für die, die es interessiert: eine Lagerstätte/Quelle kann bei dieser Variante immer nur genau <strong>eine</strong> Ware liefern und somit nur <strong>einen</strong> Bedarf decken). Dennoch: Der Algorithmus, den ich entwickelt habe, entspricht der <a href="http://de.wikipedia.org/wiki/Vogelsche_Approximationsmethode" rel="nofollow" class="liwikipedia"><em>Vogelschen Approximationsmethode</em></a>&#8230; der Ansatz, der dahinter steckt, den gibt es also schon länger. <img src='http://www.robertnitsch.de/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> </p>
<p>Fazit: Ich lebe in der falschen Zeit! (Kommt mir auch aus ganz anderen Gründen häufig so vor.)<br />
PS: Den Titel bitte nicht falsch verstehen, ich käme im Leben nicht darauf, irgendwem vorzuwerfen, er hätte mir meine Idee geklaut, nur weil er sie vor mir hatte! Das ist eigentlich eine Selbstverständlichkeit, aber hier lesen ja immer noch Juristen mit und da erkläre ich es lieber nochmal.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertnitsch.de/2008/05/19/ideenklau-20/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>bin-layer.de &#8211; ein negativer Erfahrungsbericht</title>
		<link>http://www.robertnitsch.de/2008/04/20/bin-layerde-ein-negativer-erfahrungsbericht/</link>
		<comments>http://www.robertnitsch.de/2008/04/20/bin-layerde-ein-negativer-erfahrungsbericht/#comments</comments>
		<pubDate>Sun, 20 Apr 2008 11:54:30 +0000</pubDate>
		<dc:creator>Robert</dc:creator>
				<category><![CDATA[Erfahrungsberichte]]></category>
		<category><![CDATA[Informatik]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[PC]]></category>
		<category><![CDATA[account]]></category>
		<category><![CDATA[ads]]></category>
		<category><![CDATA[bin]]></category>
		<category><![CDATA[bin-layer]]></category>
		<category><![CDATA[bin-layer.de]]></category>
		<category><![CDATA[erfahrungsbericht]]></category>
		<category><![CDATA[internetwerbung]]></category>
		<category><![CDATA[layer]]></category>
		<category><![CDATA[negativ]]></category>
		<category><![CDATA[sperrung]]></category>
		<category><![CDATA[test]]></category>
		<category><![CDATA[werbung]]></category>

		<guid isPermaLink="false">http://www.robertnitsch.de/?p=89</guid>
		<description><![CDATA[Anlass zu diesem Artikel ist die meiner Meinung nach unrechtmäßige Sperrung meines Accounts bei bin-layer.de. Der Artikel ist ein bisschen länger geworden, aber wer sich dafür interessiert, wird sich die Zeit hoffentlich nehmen. Ich bitte darum! Ich sammle am Ende des Artikels übrigens einige Links, die zeigen, dass ich mit meiner Kritik lange nicht alleine [...]]]></description>
			<content:encoded><![CDATA[<p>Anlass zu diesem Artikel ist die meiner Meinung nach unrechtmäßige Sperrung meines Accounts bei <strong>bin-layer.de</strong>. Der Artikel ist ein bisschen länger geworden, aber wer sich dafür interessiert, wird sich die Zeit hoffentlich nehmen. Ich bitte darum!<br />
Ich sammle am Ende des Artikels übrigens einige <strong>Links</strong>, die zeigen, dass ich mit meiner Kritik lange nicht alleine bin.</p>
<p>[UPDATE am 12.11.2008: Inzwischen bin ich bei layer-ads.de angekommen. <del datetime="2009-10-10T16:30:58+00:00">Sie haben mir jetzt schon 5 Monate lang keinen Grund gegeben mich zu beklagen, das danke ich ihnen mit diesem Hinweis.</del> Update 10.10.2009: Inzwischen ist aber auch Layer-ads.de mit seinen Auszahlungen in Verzug. Was ich damit meine erfahrt ihr <a href="http://www.robertnitsch.de/2008/11/12/layer-adsde-bisher-der-einzige-seriose-layerad-anbieter/" class="liinternal">hier</a>.]</p>
<p>Vorneweg: Ich habe mich juristisch beraten lassen und mir wurde versichert, dass es vollkommen legal ist, wenn man einen Sachverhalt aus der eigenen Perspektive wahrheitsgemäß wiedergibt.</p>
<p>An die Juristen, denen man alles zwei Mal erklären muss: Dieser Artikel gibt meine persönliche Wahrnehmung wieder und den Eindruck, den <strong>bin-layer.de</strong> auf mich gemacht hat.</p>
<h3>bin-layer.de</h3>
<p><strong>bin-layer.de</strong> ist eine Webseite, die sogenannte Sponsoren an Webmaster vermittelt, ohne dass die Webmaster selbst Kontakte knüpfen müssen. Es handelt sich also um ein ganz normales Unternehmen für Internetwerbung, genauso wie beispielsweise das bekanntere <strong>layer-ads.de</strong>.</p>
<h3>Die Anmeldung bei bin-layer.de am 14.03.</h3>
<p><strong>Seit dem 14. März</strong> war ich bei bin-layer.de angemeldet und habe nach deren Anweisungen (Einbau von bestimmtem Javascript-Code) auf meiner Webseite <a href="http://np.bmaker.net" class="liexternal"><strong>DS NoPaste</strong></a> Layer eingeblendet, d.h. diese großen und zugegeben lästigen &#8220;Popups&#8221;, die meist die Hälfte der Webseite überdecken. Aber immerhin konnte man die Layer auf normalem Wege schließen und sie sind dann auch wirklich verschwunden. Außerdem steht mir ein finanzieller Ausgleich als Betreiber meiner stark frequentierten Seite einfach zu &#8211; meiner Meinung nach. (Zudem hätte ich die Layer-Einblendungen in Zukunft nur noch zu bestimmten Zeiten aktiviert, sodass die Benutzer von NoPaste die meiste Zeit über ungestört surfen können.)</p>
<p>Es ist nun so, dass <strong>DS NoPaste</strong>, eine Tool-Seite für das Browsergame <a href="http://www.die-staemme.de" class="liexternal">DieStämme</a>, sehr beliebt ist und pro Tag durchschnittlich etwa 1000-1500 &#8220;echte&#8221; Besucher hat. Das hatte zur Folge, dass ich pro Tag sage und schreibe mindestens 2€ eingenommen habe. Denn für 1000 gewertete Layer-Einblendungen erhält man &#8211; das wird von bin-layer.de garantiert &#8211; mindestens 4€, manchmal auch mehr (Maximum: 8€). Ein Layer zählt übrigens dann als gewertet, wenn er vollständig angezeigt und frühestens nach 3 Sekunden geschlossen wird.</p>
<p>Vor der Sperrung meines Accounts habe ich durch diese Vergütung pro Woche locker 18€ eingenommen! Für den gesamten Webspace inkl. Domains bezahle ich pro Monat nur 8€! D.h. ich hätte meine Kosten um ein Vielfaches decken können und einen Taschengeld-Bonus von etwa 60€ / Monat gehabt!</p>
<h3>Die Sperrung meines Accounts am 17.04.</h3>
<p>Das war natürlich zu schön um wahr zu sein. Die erste Auszahlung von 15€ habe ich zwar erhalten, aber die restlichen bis heute angesammelten 65€ verbleiben bei bin-layer.de. Als ich mich nämlich heute bei bin-layer.de einloggen wollte um die nächste Auszahlung zu beantragen (es waren übrigens bereits 4 Auszahlungen in der Warteschleife) erhielt ich folgende Fehlermeldung:</p>
<blockquote><p><strong>Hinweis: Sie wurden am 17.04.2008 Gesperrt! Grund:<br />
<span style="color: red;">Fake</span></p>
<p>Bei eventuellen Fragen wenden Sie sich bitte an den Support</strong></p></blockquote>
<h3>Die Auskunft des offiziellen Supports</h3>
<p>Ich habe mich natürlich dann umgehend beim Support gemeldet, per ICQ. Nach etwa 10 Minuten hieß es, mein Account wurde gesperrt, weil meine viele tausend Besucher bei den Sponsoren nichts gekauft hätten. Bei &#8220;echten&#8221; Besuchern wäre das unmöglich, deshalb müsse man von Manipulationen (&#8220;zusätzliche[n] Tools oder [von] Proxynutzung&#8221; o.ä.) ausgehen.</p>
<p>Dazu muss man sich folgendes klar machen: bin-layer.de vermittelt Sponsoren an die Webmaster, die für bestimmte Produkte werben. Zum Beispiel werden dann Layer eingeblendet, die für bestimmte Handys o.ä. werben. Offenbar kann bin-layer.de zurückverfolgen, ob über die Werbeeinblendungen meiner Webseite solche Produkte gekauft wurden. Und das ist <em>angeblich</em> nicht der Fall.</p>
<p>Jetzt kommt aber das, was mich wirklich in Rage bringt: Bei bin-layer.de wird man für gottverdammte Werbeeinblendungen bezahlt und nicht dafür, ob die Werbung dann tatsächlich einen Effekt hat oder nicht. Davon kann sich auf der bin-layer.de-Webseite jeder selbst überzeugen.</p>
<p>Ich habe dann erstmal freundlicherweise diesen logischen Fehler übergangen und forderte Einblick in die Verkaufs-Daten, die belegen sollen, dass über meine Webseite nichts gekauft wurde. Die unbefriedigende Antwort:</p>
<blockquote><p>&#8220;Das ist natürlich nicht möglich, das sind interne Geschäftsdaten.&#8221;</p></blockquote>
<p>Anschließend kam ich auf obiges Argument zu sprechen: Webmaster werden für Werbeeinblendungen bezahlt und nicht für tatsächlich verkaufte Produkte. Und ich habe deutlich gemacht, dass auf meiner Webseite die Werbung ordnungsgemäß (nach AGB usw.) eingeblendet wird.</p>
<p>Dann kam wieder das Totschlag-Argument:</p>
<blockquote><p>&#8220;Aufgrund unserer Daten müssen wir eben davon ausgehen, dass das nicht der Fall ist.&#8221;</p></blockquote>
<p>Also aufgrund ihrer Daten müssen sie davon ausgehen, dass die Werbeeinblendungen auf meiner Webseite NICHT ordnungsgemäß eingeblendet werden. Eine andere Erklärung außer Manipulation meinerseits sei nicht möglich:</p>
<blockquote><p>&#8220;(&#8230;), Ihre Daten lassen nur auf Manipulation schließen, aufgrund der Verkaufsstatistik.&#8221;</p></blockquote>
<p>Oder nochmal anders:</p>
<blockquote><p>&#8220;Ich hab nun mehrfach die Verkaufsstatistik angeführt, das ist ein konkreter Beweis dafür, dass nur Manipulation erfolgt sein kann.&#8221;</p></blockquote>
<p>Das ist meiner Meinung nach eine lachhafte und unseriöse Begründung. Es ist einfach eine falsche Aussage, <strong>weil ich nichts manipuliert <em>habe</em>!</strong> Und es ist mir vollkommen egal, ob meine Besucher etwas von den Sponsoren kaufen, solange das nicht ansatzweise in den AGB von bin-layer.de oder sonst irgendwo erwähnt wird.</p>
<p>Natürlich habe ich nicht aufgegeben und weiterhin widersprochen und wollte den guten Mann erleuchten, aber dagegen war er resistent. Wenn ich davon überzeugt wäre im Recht zu sein, dann solle ich doch den Rechtsweg gehen und dann werde man vor Gericht alles beweisen. Natürlich wurde der Gute dabei auch immer unfreundlicher &#8211; zumindest ist das mein persönlicher Eindruck.</p>
<h3>Fazit</h3>
<p><strong>Meiner Meinung nach wurde ich zu Unrecht gesperrt.</strong> bin-layer.de hat m.E. gegen seine eigenen AGB verstoßen. Die Existenz einer &#8220;Verkaufsstatistik&#8221; halte ich für fragwürdig.<br />
Ich denke, dass sie einfach einen Grund gesucht haben, mich loszuwerden und die 65€, die sie mir noch nicht ausgezahlt haben, selbst einzustreichen. Das kann ich natürlich nicht mit Bestimmtheit sagen, deshalb nochmal für die Juristen: Das ist meine persönliche Vermutung. Ich hoffe, das ist verständlich. (Ich könnte es natürlich nochmal für diejenigen aufmalen, die besonders schwer von Begriff sind. Oder besser noch: Wie wäre es mit Vortanzen? Oder nicht doch besser ein Gedicht drüber schreiben?)</p>
<p>Als erste Konsequenz dieses Vorfalls habe ich diesen negativen Erfahrungsbericht geschrieben. Mit bestem Gewissen kann ich sagen, dass er der Wahrheit entspricht und dass ich weder über- noch untertrieben habe.<br />
Außerdem wechsele ich nun zu der Konkurrenz: <a href="http://euros4click.de/" class="liexternal"><strong>euros4click.de</strong></a>. Ich hoffe, dass die so seriös und zuverlässig sind, wie sie versprechen.<br />
Abschließend noch ein paar Dinge:</p>
<ul>
<li>man sieht sich immer 2x im Leben (Rache ist süß)</li>
<li>ich hoffe, dass dieser Artikel von möglichst vielen Menschen gelesen wird, auf dass sie nicht zu Unrecht bei bin-layer.de gesperrt werden, wie es mir meiner Meinung nach passiert ist</li>
<li>ich werde versuchen, diesen Artikel bei Google so gut wie möglich zu platzieren</li>
<li><strong>wer ähnliche Erfahrungen gemacht hat, der soll das bitte in den Kommentaren schreiben oder diesen Artikel auf seiner eigenen Webseite verlinken!</strong></li>
</ul>
<h3>Links</h3>
<p>Diese Links sollen zeigen, dass ich mit meiner Kritik lange nicht alleine stehe:</p>
<ul>
<li><a href="http://jollyroger.cc/newsflash/bin-layer-quo-vadis.html" class="liexternal">http://jollyroger.cc/newsflash/bin-layer-quo-vadis.html</a></li>
<li><a href="http://jollyroger.cc/newsflash/binlayer-gehts-noch.html" class="liexternal">http://jollyroger.cc/newsflash/binlayer-gehts-noch.html</a></li>
<li><a href="http://jollyroger.cc/newsflash/bin-layer-am-rande-der-legalit-t.html" class="liexternal">http://jollyroger.cc/newsflash/bin-layer-am-rande-der-legalit-t.html</a></li>
<li><a href="http://board.raidrush.ws/archive/t-314183.html" class="liexternal">http://board.raidrush.ws/archive/t-314183.html</a></li>
<li><a href="http://forum.layer-ads.de/partnerprogramme/6313-bin-layer-fuer-mich-pleite.html" class="liexternal">http://forum.layer-ads.de/partnerprogramme/6313-bin-layer-fuer-mich-pleite.html</a></li>
<li><a href="http://www.affiliate.de/forum/viewtopic.php?t=12078" class="liexternal">http://www.affiliate.de/forum/viewtopic.php?t=12078</a></li>
<li><a href="http://www.affiliate.de/forum/ftopic12452.html" class="liexternal">http://www.affiliate.de/forum/ftopic12452.html</a></li>
<li><a href="http://blog.darksoft-projects.de/2007/09/26/bin-layer-erstickt-im-agb-sumpf/" class="liexternal">http://blog.darksoft-projects.de/2007/09/26/bin-layer-erstickt-im-agb-sumpf/</a></li>
<li><a href="http://blog.darksoft-projects.de/2007/10/07/bin-layer-will-nun-regelmasig-auszahlen/" class="liexternal">http://blog.darksoft-projects.de/2007/10/07/bin-layer-will-nun-regelmasig-auszahlen/</a></li>
<li><a href="http://www.google.de/search?hl=de&#038;q=bin+layer&#038;btnG=Suche&#038;meta=" class="liexternal">und viele mehr</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.robertnitsch.de/2008/04/20/bin-layerde-ein-negativer-erfahrungsbericht/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
		</item>
		<item>
		<title>Letzte schriftliche Abitur-Prüfung: Biologie</title>
		<link>http://www.robertnitsch.de/2008/03/18/letzte-schriftliche-abitur-prufung-biologie/</link>
		<comments>http://www.robertnitsch.de/2008/03/18/letzte-schriftliche-abitur-prufung-biologie/#comments</comments>
		<pubDate>Tue, 18 Mar 2008 20:22:39 +0000</pubDate>
		<dc:creator>Robert</dc:creator>
				<category><![CDATA[Informatik]]></category>
		<category><![CDATA[Schule]]></category>

		<guid isPermaLink="false">http://www.robertnitsch.de/2008/03/18/letzte-schriftliche-abitur-prufung-biologie/</guid>
		<description><![CDATA[Heute hat meine letzte schriftliche Abitur-Prüfung stattgefunden: Biologie. Biologie ist neben Mathe mein zweiter Leistungskurs, also hat es sich um eine relativ wichtige Prüfung für mich gehandelt. Zum Glück ist alles gut gelaufen, denn ich konnte genau wie in Mathe alle Aufgaben lösen. Bei einer Aufgabe sind mir zwar mittlerweile noch mehr Lösungsmöglichkeiten eingefallen, aber [...]]]></description>
			<content:encoded><![CDATA[<p>Heute hat meine letzte schriftliche Abitur-Prüfung stattgefunden: <strong>Biologie</strong>. Biologie ist neben Mathe mein zweiter Leistungskurs, also hat es sich um eine relativ wichtige Prüfung für mich gehandelt. Zum Glück ist alles gut gelaufen, denn ich konnte genau wie in Mathe alle Aufgaben lösen. Bei einer Aufgabe sind mir zwar mittlerweile noch mehr Lösungsmöglichkeiten eingefallen, aber in der Aufgabe war nur nach einer Lösung gefragt. So gesehen müsste das Ergebnis eigentlich ganz gut werden. Aber ein gutes Gefühl hat mir in Biologie noch nie viel eingebracht&#8230; naja, ich hoffe auf 10+ Punkte.</p>
<p>Abgesehen davon: Die <strong>Deutsch</strong>-Prüfung am 10. war eher mäßig. Ich habe mich für einen Vorschlag mit zwei Gedichten zum Thema &#8220;Abend&#8221; entschieden. Das eine Gedicht war expressionistisch und das andere Gedicht war romantisch. Da das expressionistische Gedicht aber überhaupt keine expressionistischen Merkmale hatte, habe ich mir anfangs schwer getan. Irgendwie habe ich es dann gerettet, indem ich um 2 Ecken gedacht und damit doch noch ein Merkmal entdeckt habe. (Man muss mir ja erstmal das Gegenteil beweisen.) Trotzdem rechne ich alles in allem nur mit 5-10 Punkten. Sollte es mehr geben, ist die Freude dann umso größer.</p>
<p>Über eine andere Sache bin ich hingegen besonders (haha Wortspiel) froh: Meine <strong>besondere Lernleistung</strong> habe ich vorhin fertiggestellt und ausgedruckt. Es handelt sich um schätzungsweise 60-70 Seiten, wovon 31 Seiten normaler Text und die restlichen Seiten <strong>Python</strong>-Quelltext sind. Um den Quelltext farbig ausdrucken zu können, habe ich mir übrigens <a href="http://scintilla.org/SciTE.html" class="liexternal">SciTE</a> heruntergeladen&#8230; mit Openoffice oder MS Word war mir das leider nicht möglich.<br />
Mit der besonderen Lernleistung fällt auf jeden Fall eine große Last von mir ab, denn ich gebe zu, dass ich in den letzten Wochen deswegen doch ordentlich im Stress war. Wenn man während der schriftlichen Abiturprüfungen noch eine besondere Lernleistung fertigstellen muss (die BeLL muss am letzten Tag der schriftlichen Abiturprüfungen abgegeben werden), dann geht es halt rund.</p>
<p>Die besondere Lernleistung inkl. Quelltext werde ich dann, wenn sich das Abitur dem Ende zuneigt, hier in meinem Blog veröffentlichen. Ich habe zwei umfangreiche evolutionäre Algorithmen programmiert, von denen ich zumindest den Algorithmus für das Traveling-Salesman-Problem niemandem vorenthalten möchte. Der hat nämlich einige sehr geile Funktionen&#8230; der andere Algorithmus ist natürlich auch sehr umfangreich, aber beim TSP geht es auch auf dem Bildschirm zur Sache (dank <a href="http://www.pygame.org" class="liexternal">PyGame</a>)&#8230;</p>
<p>Das Abitur besteht für mich jetzt nur noch aus 2 <em>mündlichen</em> Prüfungen: 1. Politik- und Wirtschaft-Prüfung irgendwann im Mai. 2. Präsentation zur besonderen Lernleistung Anfang Mai + Kolloquium.</p>
<p>Alles andere ist Kleinkram&#8230; ich bin also quasi fast ein freier Mensch! <strong>*JUBEL*</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertnitsch.de/2008/03/18/letzte-schriftliche-abitur-prufung-biologie/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Besondere Lernleistung: Evolutionäre Algorithmen und das Traveling-Salesman-Problem</title>
		<link>http://www.robertnitsch.de/2008/01/06/besondere-lernleistung-evolutionare-algorithmen-und-das-traveling-salesman-problem/</link>
		<comments>http://www.robertnitsch.de/2008/01/06/besondere-lernleistung-evolutionare-algorithmen-und-das-traveling-salesman-problem/#comments</comments>
		<pubDate>Sat, 05 Jan 2008 23:11:51 +0000</pubDate>
		<dc:creator>Robert</dc:creator>
				<category><![CDATA[Freaky]]></category>
		<category><![CDATA[Informatik]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Real Life]]></category>
		<category><![CDATA[Schule]]></category>

		<guid isPermaLink="false">http://www.robertnitsch.de/2008/01/06/besondere-lernleistung-evolutionare-algorithmen-und-das-travelling-salesman-problem/</guid>
		<description><![CDATA[Das offizielle Thema meiner besonderen Lernleistung lautet &#8220;Spieltheorie&#8221; mit Schwerpunkt auf &#8220;evolutionären Algorithmen&#8221;. Ich bringe die Lernleistung zusammen mit einem Freund als Ersatz für das 5. Prüfungsfach ins Abitur, das ich dieses Jahr mache, ein. Der Freund hat natürlich einen anderen thematischen Schwerpunkt, das Hauptthema (Spieltheorie) ist jedoch dasselbe. Für das sogenannte Traveling-Salesman-Problem soll ich [...]]]></description>
			<content:encoded><![CDATA[<p>Das offizielle Thema meiner besonderen Lernleistung lautet &#8220;Spieltheorie&#8221; mit Schwerpunkt auf &#8220;evolutionären Algorithmen&#8221;. Ich bringe die Lernleistung zusammen mit einem Freund als Ersatz für das 5. Prüfungsfach ins Abitur, das ich dieses Jahr mache, ein. Der Freund hat natürlich einen anderen thematischen Schwerpunkt, das Hauptthema (Spieltheorie) ist jedoch dasselbe. <img src='http://www.robertnitsch.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Für das sogenannte <em>Traveling-Salesman-Problem</em> soll ich außerdem im Rahmen dieser Lernleistung einen evolutionären Algorithmus schaffen.</p>
<h3>Das Traveling-Salesman-Problem</h3>
<p>Das <em>Traveling-Salesman-Problem</em> (TSP) ist einfach formuliert: Ein Handlungsreisender muss <em>n</em> Städte besuchen und am Ende zu seinem Ausgangsort zurückkehren. Gesucht ist die kürzeste Rundreise.</p>
<p>Viele schlaue und dumme Menschen haben sich auf der Suche nach einem effizienten Algorithmus jahrzehntelang den Kopf darüber zerbrochen. Einen Ansatz stellen die sogenannten evolutionären Algorithmen dar, die die <a href="http://de.wikipedia.org/wiki/Evolution" rel="nofollow" class="liwikipedia">Evolution</a> als Vorbild haben.</p>
<h3>Was ist ein evolutionärer Algorithmus?</h3>
<p>Zitat <a href="http://de.wikipedia.org/wiki/Evolution%C3%A4rer_Algorithmus" rel="nofollow" class="liwikipedia">Wikipedia</a>:</p>
<blockquote><p>&#8220;Ein Evolutionärer Algorithmus (EA) ist ein Optimierungsverfahren, das als Vorbild die biologische Evolution hat.&#8221;</p></blockquote>
<p>Prinzipiell prozessiert ein evolutionärer Algorithmus eine <em>Population</em> mit <em>n</em> <em>Individuen</em> nach dem Vorbild der Evolution: <em>&#8220;survival of the fittest&#8221;</em>. Jedes Individuum stellt eine mögliche Lösung des jeweiligen Problems dar. Im Falle des TSP entspricht also jedes Individuum einer möglichen Rundreise.</p>
<p>Im Laufe des Algorithmus pflanzen sich außerdem je zwei Individuen fort und erzeugen ein Kind-Individuum nach Vorbild der Natur mittels <a href="http://de.wikipedia.org/wiki/Rekombination" rel="nofollow" class="liwikipedia">Rekombination</a>. Zusätzlich finden &#8211; ebenfalls nach Vorbild der Natur &#8211; mit einer bestimmten Wahrscheinlichkeit <a href="http://de.wikipedia.org/wiki/Mutation" rel="nofollow" class="liwikipedia">Mutationen</a> statt, also z.B. (normalerweise) zufällige Veränderungen der Route.</p>
<p>Jeder Durchlauf eines evolutionären Algorithmus&#8217; sieht also mehr oder weniger so aus:</p>
<ul>
<li>Entferne <em>x</em> Individuen aus der Population. (Zum Beispiel die beiden schlechtesten Routen.)</li>
<li>Rekombiniere <em>x</em>-Mal zwei Individuen aus der Population. (Zum Beispiel die beiden besten Routen.)</li>
<li>Wende mit einer bestimmten Wahrscheinlichkeit eine Mutation auf die Individuen an. (Zum Beispiel mit einer Wahrscheinlichkeit von 15%.)</li>
<li>Wenn die maximale Anzahl von Durchläufen (Generationen) erreicht ist, beende den Vorgang, ansonsten starte einen neuen Durchlauf.</li>
</ul>
<p>Die Güte bzw. Qualität eines evolutionären Algorithmus hängt vor allem von folgenden Faktoren ab:</p>
<ul>
<li>Populationsgröße</li>
<li>Rekombinationsmethode</li>
<li>Mutationsmethode</li>
<li>Mutationswahrscheinlichkeit</li>
<li>&#8230;</li>
</ul>
<h3>Ein evolutionärer Algorithmus für das Travelling-Salesman-Problem</h3>
<p>Wie oben gesagt ist es meine Aufgabe für das TSP einen evolutionären Algorithmus zu programmieren. Als Programmiersprache habe ich mich für <a href="http://python.org/" class="liexternal">Python</a> und als Entwicklungsumgebung für <a href="http://www.eclipse.org" class="liexternal">eclipse</a> mit <a href="http://pydev.sourceforge.net/" class="liexternal">PyDev</a> entschieden. (Damit lässt sich super arbeiten!)<br />
Mit der Arbeit am evolutionären Algorithmus habe ich heute begonnen, und ich muss sagen: Ich bin bereits jetzt sehr zufrieden. Da die Güte des evolutionären Algorithmus &#8211; siehe oben &#8211; von vielen Faktoren abhängt, habe ich mich für eine Umsetzung entschieden, bei der ich all diese Faktoren leicht ändern kann.</p>
<p>Das ist mir ganz gut gelungen: Alle Parameter und Komponenten des evolutionären Algorithmus sind ganz einfach austauschbar. (Leider werde ich bis zum Erhalt meines Abiturs keine Quelltexte veröffentlichen. Der menschlichen Dummheit sind einfach keine Grenzen gesetzt und ich könnte mir vorstellen, dass man mir vorwirft, meine Arbeit aus dem Internet von einem &#8220;Robert Nitsch&#8221; kopiert zu haben.)</p>
<p>Nun folgt der schwierigste, aber wohl auch spannendste Teil meiner besonderen Lernleistung. Ich werde prüfen welche Parameter den besten evolutionären Algorithmus ausmachen und verschiedene Konfigurationen miteinander vergleichen. Natürlich wird auch eine Begründung nicht fehlen &#8211; also warum Konfiguration A besser ist als Konfiguration B.</p>
<p>Meine Arbeit und meine Ergebnisse muss ich abschließend in einem Skript dokumentieren und in einer Präsentation vorstellen. Meine Ergebnisse werde ich natürlich auch hier auf meiner Homepage festhalten, damit Schüler, die eine ähnliche Lernleistung erbringen, davon vielleicht profitieren können.</p>
<p>Für Tipps und Ratschläge bezüglich meiner besonderen Lernleistung bin ich natürlich jederzeit offen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertnitsch.de/2008/01/06/besondere-lernleistung-evolutionare-algorithmen-und-das-traveling-salesman-problem/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Künstliche Intelligenzen gegeneinander kämpfen lassen&#8230;</title>
		<link>http://www.robertnitsch.de/2007/05/18/kunstliche-intelligenzen-gegeneinander-kampfen-lassen/</link>
		<comments>http://www.robertnitsch.de/2007/05/18/kunstliche-intelligenzen-gegeneinander-kampfen-lassen/#comments</comments>
		<pubDate>Fri, 18 May 2007 21:09:47 +0000</pubDate>
		<dc:creator>Robert</dc:creator>
				<category><![CDATA[Informatik]]></category>
		<category><![CDATA[Spiele]]></category>

		<guid isPermaLink="false">http://robertnitsch.de/2007/05/18/kunstliche-intelligenzen-gegeneinander-kampfen-lassen/</guid>
		<description><![CDATA[&#169; Microsoft Heute morgen habe ich von &#8220;AntMe!&#8221; gelesen, einer Programmierumgebung, die man innerhalb von Microsoft&#174;s .NET-Programmierumgebungen (IDEs) nutzen kann. Anscheinend kann man die zur Nutzung von &#8220;AntMe!&#8221; nötige Funktionalität nachträglich in eine beliebgie .NET-IDE integrieren (als Plugin o.ä.). Dann kann man offenbar (ich habe es noch nicht selbst probiert) die &#8220;Programmierung&#8221; eines Ameisenvolkes vornehmen, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.microsoft.com/germany/msdn/coding4fun/antme/default.mspx" title='AntMe!' class="liimagelink"><img src='http://robertnitsch.de/wp-content/uploads/2007/05/antme_logo.jpg' alt='AntMe! Logo' /></a><br />
<em>&copy; Microsoft</em></p>
<p>Heute morgen habe ich von <a href="http://www.microsoft.com/germany/msdn/coding4fun/antme/default.mspx" class="liexternal">&#8220;AntMe!&#8221;</a> gelesen, einer Programmierumgebung, die man innerhalb von Microsoft&reg;s .NET-Programmierumgebungen (IDEs) nutzen kann. Anscheinend kann man die zur Nutzung von &#8220;AntMe!&#8221; nötige Funktionalität nachträglich in eine beliebgie .NET-IDE integrieren (als Plugin o.ä.). Dann kann man offenbar (ich habe es noch nicht selbst probiert) die &#8220;Programmierung&#8221; eines Ameisenvolkes vornehmen, das im Anschluss gegen beliebige andere Ameisenvölker unterschiedlicher Programmierung antreten kann. Es gilt, Nahrung zu sammeln und ggf. zu kämpfen &#8211; nur einer übersteht auf Dauer die Konkurrenz. Der &#8220;Kampf&#8221; wird natürlich visuell veranschaulicht und man kann seinen Ameisen live beim Kampf zusehen:</p>
<p><a href="http://robertnitsch.de/wp-content/uploads/2007/05/antme_visualisierung.gif" title='AntMe! Visualisierung' class="liimagelink"><img src='http://robertnitsch.de/wp-content/uploads/2007/05/antme_visualisierung.gif' alt='AntMe! Visualisierung' /></a><br />
<em>&copy; Microsoft</em></p>
<p>Was mich daran besonders fasziniert, ist die Idee, gegen die Ameisenvölker anderer Programmierer anzutreten und das eigene Ameisenvolk von mal zu mal zu perfektionieren. Im Moment bin ich deswegen dabei, <a href="http://www.microsoft.com/germany/msdn/vstudio/products/express/visualcsharp/default.mspx" class="liexternal">Microsoft&reg; Visual C#&reg; 2005 Express</a> <a href="http://www.microsoft.com/germany/msdn/vstudio/products/express/download.mspx" class="liexternal">herunterzuladen</a> und zu installieren.</p>
<h3>Alternativen zu AntMe!</h3>
<p>Bis gerade eben habe ich Alternativen zu AntMe! ausprobiert &#8211; für Linux. Erstmal war es aufwändig, welche zu finden&#8230; dann fand ich Seed7 bzw. <a href="http://de.wikipedia.org/wiki/Dnafight" rel="nofollow" class="liwikipedia">DNA Fight</a>, <strike>konnte es aber leider trotz mehrerer Versuche nicht kompilieren (typisches Problem)</strike> konnte es aber erst nach dem Fertigstellen dieses Artikels erfolgreich kompilieren. Siehe dazu Kommentar 3 und folgende&#8230;<br />
Nebenbei fand ich allerdings auch <a href="http://de.wikipedia.org/wiki/Nero_(Computerspiel)" rel="nofollow" class="liwikipedia">NERO</a>, womit nicht das allseits bekannte Brennprogramm, sondern ein Spiel mit ähnlichen Funktionen und einem ähnlichen Spielziel, wie dem von AntMe!. Allerdings konnte ich auch hier die Linux-Version nicht zum Laufen bringen (diesmal konnte mein Packer das Archiv nicht entpacken)&#8230;</p>
<blockquote><p>Wikipedia:</p>
<p>Im Spiel trainiert man Roboter, die für ihr Handeln vom Spieler entweder eine positive oder eine negative Bewertung bekommen. Gut bewertete virtuelle Genkonfigurationen haben eine höhere Chance, bei der simulierten Evolution mit einem anderen Gen verschmolzen zu werden.</p></blockquote>
<p><a href="http://www.nerogame.org/" class="liexternal">&gt; Offizielle Website von NERO</a></p>
<h3>KI-Schlachtfelder mit dem Warcraft&reg; 3 &#8211; Welteneditor&#8230;</h3>
<p>Zum Abschluss hatte ich die Idee, ein Strategiespiel für mein Ziel zu zweckentfremden &#8230; dazu nahm ich <strong>Warcraft&reg; 3</strong> (bzw. die Erweiterung TFT) und erstellte mir im <strong>Welten-Editor</strong> eine sehr triviale Karte mit dem Titel &#8220;AI Wars&#8221; (deutsch: Krieg der künstlichen Intelligenzen), auf der 2 Spieler gegeneinander antreten konnten. Die 2 &#8220;Spieler&#8221; sind in Wirklichkeit die beiden künstlichen &#8220;Intelligenzen&#8221;. Man selbst kann nur zusehen (dafür gibt es 3 weitere Spielerslots).</p>
<p>Das Hauptfenster des Editors:<br />
<a href="http://robertnitsch.de/wp-content/uploads/2007/05/aiwars_editor.jpg" title='AI Wars - Editor' class="liimagelink"><img src='http://robertnitsch.de/wp-content/uploads/2007/05/aiwars_editor.thumbnail.jpg' alt='AI Wars - Editor' /></a></p>
<p>Damit auch überhaupt ein Kampf stattfinden kann, starten die KIs mit jeweils 15 Gold. Alle 15 Sekunden wird das vorhandene Gold in neue Einheiten umgesetzt. Die erste KI hat dabei ihr Lager in der oberen linken Ecke der Karte, die zweite KI genau gegenüber. Überdies hinaus haben beide KIs in ihrem Lager einen Brunnen der Gesundheit, an dem Einheiten sehr schnell geheilt werden können, falls sie verletzt sind.</p>
<p>Die KIs agieren hauptsächlich über einen Code, der alle 15 Sekunden ausgeführt wird. Dieser Code veranlasst z.B. alle Einheiten in der jeweiligen Basis zum aggressiven Vorrücken zur Basis des jeweiligen Gegners. Am Anfang rennen also sofort alle 15 Soldaten los und treffen sich in der Mitte mit den Einheiten des Kontrahenten. Da ein einzelner Code, der alle 15 Sekunden aufgerufen wird, allerdings weder eine ordentliche Programmierung zulässt, noch sehr viele Möglichkeiten zulässt, kann man natürlich jeder KI auch weitere &#8220;Auslöser&#8221; verpassen.</p>
<p>Ein Auslöser im Welten-Editor ist eine Einheit von Ereignissen, Bedingungen und Aktionen &#8230; als Ereignis kann z.B. ein Timer gelten, der alle X Sekunden ausgelöst wird. Im Welten-Editor von Warcraft&reg; sind aber schier unendlich viele Möglichkeiten vorhanden&#8230; so kann man auch auf das &#8220;Angegriffenwerden&#8221; einer Einheit reagieren&#8230; und diese Einheit dann zum Gegenangriff oder Fliehen veranlassen. Wann immer ich also in diesem Artikel von einem &#8220;Code&#8221; rede, meine ich in Wirklichkeit einen oder mehrere Auslöser&#8230;</p>
<p>Der Auslöser-Editor:<br />
<a href="http://robertnitsch.de/wp-content/uploads/2007/05/aiwars_ausloeser.jpg" title='AI Wars - Auslöser' class="liimagelink"><img src='http://robertnitsch.de/wp-content/uploads/2007/05/aiwars_ausloeser.thumbnail.jpg' alt='AI Wars - Auslöser' /></a></p>
<p>Übrigens erhält eine KI für jeden feindlichen Soldaten, den sie tötet, 1 Gold, d.h. für jeden Soldaten, der getötet wird, erhält die KI einen eigenen Soldaten dazu. Damit eine KI deswegen nicht allzu schnell gewinnt, haben beide KIs in ihrem Lager einen starken Wachturm, der auf feindliche Einheiten schiesst und selbst sehr viel Leben (&#8220;Trefferpunkte&#8221;) hat. Es dauert also ein paar Minuten, bis sich das Spiel entschieden hat. Außerdem wird diese Karte von mir noch stark erweitert werden, sodass die KIs sich dann nicht nur bekämpfen müssen, sondern auch eine kleine Wirtschaft steuern müssen können. Dann relativieren sich die kleinen Vorteile beim Spielbeginn (wer zuerst zuschlägt usw.).</p>
<h3>Das erste Anzeichen von Intelligenz&#8230;</h3>
<p>Damit auch ich als Programmierer meinen Spaß habe, habe ich mir sogleich eine etwas überlegene KI geschaffen. Sie verfährt nicht mehr nur nach dem &#8220;Haudrauf&#8221;-Prinzip &#8230; jedes Mal, wenn eine Einheit einen Schlag kassiert, wird überprüft, ob diese Einheit noch mindestens 20% ihrer Trefferpunkte besitzt. Falls nicht, so rennt sie sofort zurück in die Basis zum &#8220;Brunnen des Lebens&#8221;, wo sie dann eine sehr hohe Regenerationsrate genießt. Sobald ihre Trefferpunkte auf über 90% der maximalen TP angestiegen sind, nimmt sie wieder an der Schlacht teil.<br />
Dadurch werden gleich zwei Dinge erreicht: in der Basis steht immer eine kleine &#8220;Reserve&#8221;, die im Falle des Angriffes &#8211; obwohl sie natürlich geschwächt ist &#8211; dem Gegner etwas Kontra geben kann &#8230;<br />
Außerdem, und das ist viel wichtiger, gelingt es der gegnerischen KI nun fast überhaupt nicht mehr, irgendwelche Soldaten zu töten. Damit versiegt also, zumindest in der jetzigen Version von &#8220;AI Wars&#8221;, die Hauptgeldquelle des Gegners&#8230;</p>
<h3>Vorteile und Nachteile des Welteneditors für KI-Schlachten</h3>
<p>Vorteile:</p>
<ul>
<li>nahezu unendlich viele Möglichkeiten der KI-Programmierung</li>
<li>ebenfalls unendlich viele Möglichkeiten beim Gestalten der Umgebung/der Umstände</li>
<li>eine äußerst schöne grafische Darstellung der Schlachten <img src='http://www.robertnitsch.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </li>
</ul>
<p>Nachteile:</p>
<ul>
<li>beide Programmierer benötigen das Originalspiel</li>
<li>das Spiel ist nicht plattformunabhängig (es läuft aber dennoch nativ sowohl auf Windows&reg;- als auch Mac-Systemen)</li>
<li>das Antreten zweier KIs ist etwas schwerfällig: man muss jedes Mal, wenn man 2 KIs gegeneinander kämpfen lassen möchte, die Karte editieren (die Auslöser des anderen Programmierers importieren und die eigene KI hineinepfriemeln&#8230;)</li>
</ul>
<p>Solange es keine bessere Lösung gibt, werde ich diese Methode weiter ausfeilen und die Möglichkeiten des Warcraft &#8211; Welteneditors so gut es geht ausschöpfen. Da ich bisher nicht eine einzige Karte mit diesem Editor erstellt habe, ist das auch gleich eine gute Gelegenheit für mich, mich damit auseinanderzusetzen. Und wie man an den Screenshots und meinem Gerede erkennt, ist es gar nicht so schwer, wenn man sich ein paar Stunden Zeit nimmt (oder sie einfach hat).</p>
<h3>Download der Karte</h3>
<p>Für diejenigen, die bis hierher gelesen haben und sich trotzdem im Besitz von Warcraft 3 (+Erweiterung TFT!) befinden, biete ich meine Warcraft-Karte zum Download an. So könnt ihr auch gleich sehen, wie ich bestimmte Dinge realisiert habe. Ich würde mir sowas als Leser auf jeden Fall wünschen. <img src='http://www.robertnitsch.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><a href="http://robertnitsch.de/wp-content/uploads/2007/05/ai-wars-100.zip" title='Download: AI Wars 1.00' class="lizip">Download: AI Wars 1.00</a></p>
<p>Wer eine KI schreibt, die gegen meine KI gewinnt (&#8220;KI 1&#8243; bzw. Spieler 11 stellt meine KI dar, KI 2 ist die dumme &#8220;Haudrauf&#8221;-Truppe), der darf mir seine KI natürlich gerne zukommen lassen. Dann werde ich meinerseits eine bessere KI schreiben und sie zurückschicken. <img src='http://www.robertnitsch.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<h3>AI Wars mit Python</h3>
<p>Ich träume im Moment von einem Python-Modul, mit dem man AI Wars ausführen kann &#8211; 2 ambitionierte Pythonprogrammierer lassen dann ihre künstlichen Intelligenzen gegeneinander antreten &#8211; das Modul gibt lediglich die Schnittstelle und damit auch die Spielregeln vor&#8230; außerdem ermöglicht es auch gleich die grafische Ansicht des &#8220;Kampfes&#8221;.</p>
<p>Innerhalb der nächsten Tage werde ich mich diesem noch nicht existenten Modul mal annehmen &#8230; zuerst überlege ich mir aber ein geeignetes Szenario für meine &#8220;AI Wars&#8221;. <img src='http://www.robertnitsch.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  Für Vorschläge bin ich jederzeit offen &#8211; ich würde mich sehr über Ideen und Ratschläge freuen!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertnitsch.de/2007/05/18/kunstliche-intelligenzen-gegeneinander-kampfen-lassen/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
