108 lines
4.9 KiB
PHP
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 ∞ 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 = 〈(s:0), (u:∞), (v:∞), (x:∞), (y:∞)〉</li>
|
|
<li>Q = 〈(x:5), (u:10), (v:∞), (y:∞)〉</li>
|
|
<li>Q = 〈(y:7), (u:8), (v:∞)〉</li>
|
|
<li>Q = 〈(u:8), (v:13)〉</li>
|
|
<li>Q = 〈(v:9)〉</li>
|
|
<li>Q = 〈〉</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: "Algorithmen & Datenstrukturen"</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> |