Files
tilman.de/www/uni/ws03/alp/greedy.php
T
2011-10-26 10:11:42 +02:00

108 lines
4.9 KiB
PHP

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<link rel="stylesheet" type="text/css" media="all" href="stylesheet.css">
<title>Greedy-Algorithmen</title>
</head>
<body>
<span id="menu"><a href="index.php">zurück zur Liste</a></span>
<div id="buttons">
<form action="edit.php" method="POST">
<input type="hidden" name="filename" value="<?php echo $_SERVER['SCRIPT_FILENAME']?>">
<p>
<input type="submit" value="Seite bearbeiten">
</p>
</form>
</div>
<h1>Greedy-Algortihmen</h1>
Das Prinzip eines <b>Greedy-Algorithmus (gieriger Algorithmus)</b> ist es, in jedem Teilschritt so viel wie möglich zu erreichen.<br><br>
Eine Anwendung des Greedy-Algorithmus im täglichen Leben ist die z.B. die <b>Herausgabe von Wechselgeld</b>. <br>
<b>Greedy:</b> Nimm jeweils immer die größte Münze unter dem Zielwert und ziehe sie von diesem ab. Verfahre derart bis Zielwert gleich null.<br>
<table>
<tr>
<td>Beispiel:</td>
<td>Rückgabe von 79 Cent</td>
</tr>
<tr>
<td></td>
<td>79 = 50 + 20 + 5 + 2 + 2</td>
</tr>
</table>
<br>
Bei diesem Beispiel berechnet der Greedy-Algorithmus immer die optimale Geldrückgabe. Die muss allerdings nicht immer gelten. Greedy-Algorithmen berechnen jeweils ein <b>lokales Optimum</b> in jedem Schritt und können daher eventuell ein <b>globales Optimum</b> verpassen.<br>
<table>
<tr>
<td>Beispiel:</td>
<td>Zielwert ist 15. Es stehen Münzen mit den Werten 1, 5 und 11 zu Verfügung.</td>
</tr>
<tr>
<td></td>
<td>15 = 5 + 5 + 5 ist globales Optimum</td>
</tr>
<tr>
<td></td>
<td>15 = 11 + 1 + 1 + 1 + 1 mit Greedy kein globales Optimum</td>
</tr>
</table>
<br>
<h3>Dijkstras Algorithmus - Zum Finden kürzester Wege</h3>
Der Dijkstra-Algorithmus kann als eine auf dem Greedy-Prinzip basierende Weiterentwicklung der Breitensuchen für gewichtete Kanten aufgefasst werden. Allerdings funktioniert diese Weiterentwicklung nur für nichtnegative Gewichte.<br><br>
<b>Verfahren</b><br>
Pro Knoten wird der Distanzwert D zum Startknoten in einer Prioritätswarteschlange Q gespeichert. Zu Beginn ist für den Startknoten 0 und für alle anderen Knoten unendlich &#8734; eingetragen.<br><br>
<b>Schleifendurchlauf</b><br>
Der erste Knoten k<sub>1</sub> wird aus Q genommen. Der entgültige Distanzwert von k<sub>1</sub> ist das aktuelle D. <br>
Nun wird Q verändert. Bei allen Knoten k<sub>i</sub>, die direkte Nachbarn von k<sub>1</sub> sind, wird nun überprüft, ob das aktuelle D größer ist als D(k<sub>1</sub>) + das Gewicht der Kante k<sub>1</sub>k<sub>i</sub>. Also wenn D(k<sub>i</sub>) > (D(k<sub>1</sub>) + k<sub>1</sub>k<sub>i</sub>), dann D(k<sub>i</sub>) = D(k<sub>1</sub>) + k<sub>1</sub>k<sub>i</sub>.<br><br>
<b>Beispiel</b><br>
<table>
<tr>
<td><img src="dijkstra.gif"></td>
<td>
<ol>
<li>Q = &#9001;(s:0), (u:&#8734;), (v:&#8734;), (x:&#8734;), (y:&#8734;)&#9002;</li>
<li>Q = &#9001;(x:5), (u:10), (v:&#8734;), (y:&#8734;)&#9002;</li>
<li>Q = &#9001;(y:7), (u:8), (v:&#8734;)&#9002;</li>
<li>Q = &#9001;(u:8), (v:13)&#9002;</li>
<li>Q = &#9001;(v:9)&#9002;</li>
<li>Q = &#9001;&#9002;</li>
</ol>
</td>
<td>
<br>
D(s) = 0<br>
D(x) = 5<br>
D(y) = 7<br>
D(u) = 8<br>
D(v) = 9<br>
</td>
</tr>
</table>
<div class="quelle">Beispiel entnommen aus Saake, Sattler: &quot;Algorithmen &amp; Datenstrukturen&quot;</div>
<br>
<h3>Algorithmus von Prim - Zum Finden des kleinsten aufspannenden Baums</h3>
<b>Verfahren</b><br>
Wähle einen beliebigen Knoten als Startgraph T.<br>
Solange T noch nicht alle Knoten enthält, suche eine Kante minimalen Gewichts, die einen Knoten, der nicht in T ist, mit T verbindet und füge diese Kante und den damit verbundenen Knoten zu T hinzu.<br><br>
<a href="http://www.fmi.uni-passau.de/~blochg/mst/prim.html">Animation für Prim</a>
<h3>Algorithmus von Kruskal - Zum Finden des kleinsten aufspannenden Baums</h3>
Die Grundidee ist, die Kanten in der Reihenfolge aufsteigender Kantengewichte zu durchlaufen und jede Kante zu wählen, die mit allen zuvor gewählten Kanten keinen Kreis schließt.<br><br>
<b>Verfahren</b><br>
Die Menge der Kanten werden sortiert in einer Liste L gespeichert.<br>
Wähle die erste Kante in L als Startgraph T und lösche sie aus der Liste.<br>
Solange T noch nicht alle Knoten enthält, gehe L der Reihe nach durch. Füge die erste Kante in T ein, die keinen Kreis mit den den Kanten, die bereits in T liegen, bilden. Die gewählte Kante und die Kanten, die einen Kreis bilden, können aus L gelöscht werden.<br><br>
<a href="http://www.fmi.uni-passau.de/~blochg/mst/kruskal.html">Animation für Kruskal</a>
</body>
</html>