<?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; Mathematik</title>
	<atom:link href="http://www.robertnitsch.de/category/mathematik/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>Mathematiker stehlen Lebenszeit</title>
		<link>http://www.robertnitsch.de/2009/02/21/mathematiker-stehlen-lebenszeit/</link>
		<comments>http://www.robertnitsch.de/2009/02/21/mathematiker-stehlen-lebenszeit/#comments</comments>
		<pubDate>Sat, 21 Feb 2009 20:39:55 +0000</pubDate>
		<dc:creator>Robert</dc:creator>
				<category><![CDATA[Informatik]]></category>
		<category><![CDATA[Mathematik]]></category>
		<category><![CDATA[Real Life]]></category>
		<category><![CDATA[Studium]]></category>

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

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

		<guid isPermaLink="false">http://robertnitsch.de/2007/04/04/python-das-turtle-modul-und-fraktale/</guid>
		<description><![CDATA[Ich hätte ja nicht gedacht, dass es so lustig sein kann, mit Fraktalen herumzuexperimentieren &#8230; aber das kann es doch. Ein bisschen Interesse natürlich vorrausgesetzt. Mit Hilfe des Lehrmaterials &#8220;Turtle-Grafik und Fraktale Geometrie&#8221; (http://miami.uni-muenster.de/servlets/DocumentServlet?id=1522) konnte ich auch recht schnell einsteigen. Die Schilderungen und die Quelltexte sind auf das Modul turtle bezogen und sind somit grundsätzlich [...]]]></description>
			<content:encoded><![CDATA[<p>Ich hätte ja nicht gedacht, dass es so lustig sein kann, mit Fraktalen herumzuexperimentieren &#8230; aber das kann es doch. Ein bisschen Interesse natürlich vorrausgesetzt.</p>
<p>Mit Hilfe des Lehrmaterials &#8220;Turtle-Grafik und Fraktale Geometrie&#8221; (<a href="http://miami.uni-muenster.de/servlets/DocumentServlet?id=1522" class="liexternal">http://miami.uni-muenster.de/servlets/DocumentServlet?id=1522</a>) konnte ich auch recht schnell einsteigen. Die Schilderungen und die Quelltexte sind auf das Modul turtle bezogen und sind somit grundsätzlich plattformunabhängig. Dennoch empfehle ich Python für diese Experimente, denn dort ist das turtle-Modul bereits integriert und lässt sich phänomenal einfach verwenden.</p>
<h3>Das turtle-Modul</h3>
<p>Das turtle-Modul ist eine Sammlung an Funktionen, mit deren Hilfe sich ein &#8220;Malstift&#8221; bzw. &#8220;turtle&#8221; steuern lässt. Mit Anweisungen wie left(), right(), forward() und backward() kann man einfachste Bewegungen koordinieren. Packt man derartige Anweisungen in rekursive Funktionen, so ergibt sich mit etwas Glück ein immerwiederkehrendes selbstähnliches Gebilde &#8211; ein Fraktal.</p>
<p>Die Dokumentation des pythoneigenen turtle-Moduls ist hier zu finden:</p>
<p><a href="http://docs.python.org/lib/module-turtle.html" class="liexternal">http://docs.python.org/lib/module-turtle.html</a></p>
<h3>Die Kochkurve</h3>

<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
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># coding=UTF-8</span>
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">turtle</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> kochkurve<span style="color: black;">&#40;</span>t, s<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span><span style="color: black;">&#40;</span>t==<span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>:
        <span style="color: #808080; font-style: italic;"># wenn die gewünschte rekursionstiefe (sprich: feinheit der bewegungen) erreich ist,</span>
        <span style="color: #808080; font-style: italic;"># soll das ganze auf dem bildschirm umgesetzt werden</span>
        forward<span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        <span style="color: #808080; font-style: italic;"># die bewegungen der &quot;turtle&quot; werden rekursiv verfeinert</span>
        kochkurve<span style="color: black;">&#40;</span>t-<span style="color: #ff4500;">1</span>, s/<span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>
        left<span style="color: black;">&#40;</span><span style="color: #ff4500;">60</span><span style="color: black;">&#41;</span>
        kochkurve<span style="color: black;">&#40;</span>t-<span style="color: #ff4500;">1</span>, s/<span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>
        left<span style="color: black;">&#40;</span>-<span style="color: #ff4500;">120</span><span style="color: black;">&#41;</span>
        kochkurve<span style="color: black;">&#40;</span>t-<span style="color: #ff4500;">1</span>, s/<span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>
        left<span style="color: black;">&#40;</span><span style="color: #ff4500;">60</span><span style="color: black;">&#41;</span>
        kochkurve<span style="color: black;">&#40;</span>t-<span style="color: #ff4500;">1</span>, s/<span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;"># koch'sche schneeflocke, zusammengesetzt aus mehreren kochkurven</span>
kochkurve<span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">100</span><span style="color: black;">&#41;</span>
left<span style="color: black;">&#40;</span>-<span style="color: #ff4500;">90</span><span style="color: black;">&#41;</span>
color<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>,<span style="color: #ff4500;">0</span>,<span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
kochkurve<span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">100</span><span style="color: black;">&#41;</span>
left<span style="color: black;">&#40;</span>-<span style="color: #ff4500;">90</span><span style="color: black;">&#41;</span>
color<span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>,<span style="color: #ff4500;">1</span>,<span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
kochkurve<span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">100</span><span style="color: black;">&#41;</span>
left<span style="color: black;">&#40;</span>-<span style="color: #ff4500;">90</span><span style="color: black;">&#41;</span>
color<span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>,<span style="color: #ff4500;">0</span>,<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
kochkurve<span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">100</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># die methode done(), die die hauptschleife betritt, ist offenbar nicht verfügbar :-(</span>
<span style="color: #dc143c;">time</span>.<span style="color: black;">sleep</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span>
done<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<hr />
<p>Die Rekursionstiefe (t) bestimmt die Feinheit der Bewegungen. Der Parameter s definiert die Gesamtlänge der Kochkurve.</p>
<p>Ich habe die Funktion am Ende mehrfach aufgerufen, sodass eine sogenannte Koch&#8217;sche Schneeflocke entsteht. Eine Koch&#8217;sche Schneeflockte besteht aus mehreren Kochkurven, die man aneinandergehängt hat. Und hängt man 4 Kochkurven im Winkel von 90° aneinander, so ergibt sich folgendes Gebilde:</p>
<p><a href="http://robertnitsch.de/wp-content/uploads/2007/04/kochsche_schneeflocke.jpg" title='Koch’sche Schneeflocke' class="liimagelink"><img src='http://robertnitsch.de/wp-content/uploads/2007/04/kochsche_schneeflocke.jpg' alt='Koch’sche Schneeflocke' /></a></p>
<h3>Der fraktale Baum</h3>
<p>Fraktale Bäume haben mich irgendwie schon immer beschäftigt. Man stelle sich einen Körper vor, von dem etliche Zweige und Äste abgehen. Von jedem Zweig und jedem Ast gehen erneut ebensoviele Zweige und Äste ab &#8211; diesmal nur wesentlich kleiner. Und von diesen kleinen Ästen gehen wieder Äste ab &#8230; immer wieder &#8230; und jedes Mal werden sie kleiner. Ich hatte meinen Spaß daran mir den kleinsten denkbaren Ast vorzustellen. Natürlich hatte dieser Gedankengang nie ein Ende. Aber wenn man jung ist&#8230; <img src='http://www.robertnitsch.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Mit dem turtle-Modul lassen sich natürlich auch fraktale Bäume erzeugen.</p>
<p>Z.Bsp. hiermit:</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
15
16
17
18
19
20
21
22
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># coding=UTF-8</span>
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">turtle</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> baum<span style="color: black;">&#40;</span>s,t<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span><span style="color: black;">&#40;</span>t <span style="color: #66cc66;">&gt;</span>= <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>:
        forward<span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span>
        left<span style="color: black;">&#40;</span><span style="color: #ff4500;">30</span><span style="color: black;">&#41;</span>
        baum<span style="color: black;">&#40;</span>s<span style="color: #66cc66;">*</span><span style="color: #ff4500;">0.6</span>, t-<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
        right<span style="color: black;">&#40;</span><span style="color: #ff4500;">75</span><span style="color: black;">&#41;</span>
        baum<span style="color: black;">&#40;</span>s<span style="color: #66cc66;">*</span><span style="color: #ff4500;">0.7</span>, t-<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
        left<span style="color: black;">&#40;</span><span style="color: #ff4500;">45</span><span style="color: black;">&#41;</span>
        backward<span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
sety<span style="color: black;">&#40;</span>-<span style="color: #ff4500;">100</span><span style="color: black;">&#41;</span>
baum<span style="color: black;">&#40;</span><span style="color: #ff4500;">100</span>,<span style="color: #ff4500;">7</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># die methode done(), die die hauptschleife betritt, ist offenbar nicht verfügbar :-(</span>
<span style="color: #dc143c;">time</span>.<span style="color: black;">sleep</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span>
done<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<hr />
<p>Mit Hilfe des Parameters t lässt sich auch hier die Rekursionstiefe festlegen.</p>
<p>Der Code ergibt, wenn man ihn mit dem Python-Compiler aufruft, folgendes:</p>
<p><a href="http://robertnitsch.de/wp-content/uploads/2007/04/fraktaler_baum_klein.jpg" title='Fraktaler Baum' class="liimagelink"><img src='http://robertnitsch.de/wp-content/uploads/2007/04/fraktaler_baum_klein.jpg' alt='Fraktaler Baum' /></a></p>
<p>Selbstverständlich lassen sich Winkel und Streckenlängen variieren. In diesem konkreten Fall ist der linke Ast um 30° (nach links), der rechte um 45° (nach rechts) abgewinkelt. Der linke Ast hat die Länge 0,6*s &#8211; das entspricht 60% der Länge des Mutterastes. Der rechte Ast hat jeweils die Länge 0,7*s &#8211; also 70% der Länge des Mutterastes.</p>
<h3>Weitere Anregungen</h3>
<p><a href="http://www.herr-rau.de/wordpress/2007/03/meine-erste-fischpopulation.htm" class="liexternal">Fischpopulationen im Lehrerzimmer</a> mit Tkinter (kleine Andeutung am Rande <img src='http://www.robertnitsch.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  )</p>
<p><a href="http://miami.uni-muenster.de/servlets/DocumentServlet?id=1522" class="liexternal">Turtle-Grafik und fraktale Geometrie</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertnitsch.de/2007/04/04/python-das-turtle-modul-und-fraktale/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
