Aufgabe 1: Dijkstras Algorithmus
Aufgabe 1: Dijkstras Algorithmus
Aufgabe 1: Dijkstras Algorithmus
Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.
YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.
Christoph Garbe: Algorithmen und Datenstrukturen, SS 09 Übungsblatt 10<br />
Abgabe: bis 12.06.2009, 12:00 Uhr<br />
<strong>Aufgabe</strong> 1: <strong>Dijkstras</strong> <strong>Algorithmus</strong><br />
25 Punkte<br />
Gehen Sie bei der Lösung dieser <strong>Aufgabe</strong> von folgendem Dijkstra‐<strong>Algorithmus</strong> nach Cormen aus und<br />
verwenden Sie entsprechende Bezeichnungen!<br />
Dijkstra(G=(V,E), w(), s) { // s: Ausgangsknoten, w: Gewichtsfunktion, G: Graph<br />
for each v V {<br />
d[v] = ;<br />
// Kürzester Pfad Schätzer<br />
[v] = NULL; // Vorgänger Pointer<br />
}<br />
d[s] = 0;<br />
S = ;<br />
Q = V; // Minimum Prioritätswarteschlange<br />
while Q {<br />
u = EXTRACT-MIN(Q); // kleinstes Element aus Q holen (bezüglich d)<br />
S = S {u};<br />
for each v AdjList[u] {<br />
if d[v] > d[u] + w(u,v) {<br />
d[v] = d[u] + w(u,v);<br />
[v] = u;<br />
}<br />
}<br />
}<br />
}<br />
a) Führen Sie den Dijkstra‐<strong>Algorithmus</strong> auf dem unten dargestellten Graph aus. Starten Sie einmal bei s<br />
und einmal bei w. Geben Sie dann jeweils den kürzesten Pfad für s w bzw. w s an! Zeichnen<br />
Sie jeweils den Graph nach jedem Durchlauf der while‐Schleife. In den Knoten sind die d[v]<br />
anzugeben. Markieren Sie auch jeweils (z.B. farbig) die Kante, die von jedem Knoten zu seinem<br />
Vorgänge [v] führt!<br />
(10 Punkte)<br />
s<br />
<br />
3<br />
<br />
<br />
6<br />
<br />
1 2 3 7 2<br />
5 3<br />
2<br />
<br />
6 w<br />
b) Dijkstra’s <strong>Algorithmus</strong> lässt sich auf potentiell unzuverlässige Netzwerke anwenden (z.B. das<br />
Internet). Angenommen ein solches Netzwerk wird durch einen gerichteten Graphen G(V, E)<br />
beschrieben, dessen Kanten eE ein Wert 0 ≤ r(e) ≤ 1 zugeordnet wird. Dabei entspricht r(e) der<br />
Ausfallwahrscheinlichkeit einer Verbindung zwischen zwei Knoten (je größer r(e), desto verlässlicher<br />
ist die Verbindung). Die <strong>Aufgabe</strong> ist nun Dijkstra’s <strong>Algorithmus</strong> so zu modifizieren, dass er
Christoph Garbe: Algorithmen und Datenstrukturen, SS 09 Übungsblatt 10<br />
Abgabe: bis 12.06.2009, 12:00 Uhr<br />
}<br />
1. den verlässlichsten und p min r ( e )<br />
verlässlic<br />
hst<br />
Pfade<br />
i<br />
{ e }<br />
2. den unverlässlichsten p max r(<br />
e )<br />
unverlässlichst<br />
Pfad<br />
ei<br />
Pfad<br />
Pfad e 1 , ...,e n zwischen zwei gegebenen Knoten s und w in einem solchen Netzwerk findet, also<br />
jeweils den Pfad mit der größten bzw. kleinsten Gesamtausfallswahrscheinlichkeit<br />
<br />
p r(<br />
e).<br />
Ausfall<br />
ePfad<br />
(Tipp: Überlegen Sie, ob es eine Transformation gibt, die einen oben beschriebenen Graphen auf<br />
einen Standard‐Graphen für den Dijkstra‐<strong>Algorithmus</strong> abbildet)<br />
(10+5 Punkte)<br />
i<br />
i<br />
i<br />
0<br />
<strong>Aufgabe</strong> 2: Bellman‐Ford‐<strong>Algorithmus</strong><br />
10 Punkte<br />
Wenden Sie den <strong>Algorithmus</strong> von Bellman‐Ford auf folgende Graphen an. Jeweils mit dem grau<br />
markierten Knoten als Startknoten. Geben Sie nach jedem der vier Durchläufe der äußeren for‐Scheife<br />
die Distanzen d(v) in den Knoten an (also wie bei <strong>Aufgabe</strong> 1a).<br />
(5+5 Punkte)<br />
6<br />
6<br />
3<br />
<br />
1 2<br />
3 7<br />
<br />
0<br />
1<br />
<br />
‐2 5 ‐5<br />
2<br />
<br />
5<br />
<br />
2<br />
6<br />
3<br />
<br />
7<br />
<br />
2<br />
6
Christoph Garbe: Algorithmen und Datenstrukturen, SS 09 Übungsblatt 10<br />
Abgabe: bis 12.06.2009, 12:00 Uhr<br />
<strong>Aufgabe</strong> 3: Arbitrage<br />
20 Punkte<br />
Arbitrage bezeichnet das Ausnutzen von Preisunterschieden für gleiche Waren auf verschiedenen<br />
Märkten. Ein einfaches Beispiel ist das Ausnutzen von Wechselkursen, also das handeln mit Währungen.<br />
Angenommen ein Händler startet mit 1$. Damit kauft er zunächst 95,739¥. Pro Yen erhält man 0,0063<br />
britische Pfund. Schließlich kauft man zum Kurs 1,6583 $/Pfund wieder Dollar und hat jetzt:<br />
95,739 0,0063 1,6583 = 1,0002131 Dollar (Wechselkurse vom 2.6.2009). Ingesamt ergab sich also ein<br />
Gewinn von 0,021%, nicht viel aber immerhin ;‐)<br />
Für diese <strong>Aufgabe</strong> gilt nun: Es gebe n Währungen c 1 ,...,c n . Außerdem seien die nn‐n Wechselkurse R(i,j)<br />
vorgegeben.<br />
Die allgemeine Fragestellung ist: Wie kann man bei den oben gegebenen Daten Wechselzyklen c 1 , c 2<br />
...,c k‐1 , c 1 von Währungen finden, sodass folgende Ungleichung gilt und das dortige Produkt maximal ist:<br />
R(c 1 , c 2 ) R(c 2 , c 3 ) ... R(c k‐1 , c 1 ) > 1.<br />
a) Finden Sie einen möglichst effizienten <strong>Algorithmus</strong>, der angibt, ob mit den gegebenen Daten<br />
Arbitrage‐Geschäfte möglich sind. Geben Sie die Laufzeit ihres <strong>Algorithmus</strong> an.<br />
(10 Punkte)<br />
b) Geben Sie einen <strong>Algorithmus</strong> an, der ein solches Arbitrage Geschäft ausdruckt, falls eines existiert!<br />
Geben Sie die Laufzeit ihres <strong>Algorithmus</strong> an.<br />
(10 Punkte)<br />
<strong>Aufgabe</strong> 4: Routenplanung<br />
25+10 Punkte<br />
<strong>Dijkstras</strong> <strong>Algorithmus</strong> für kürzeste Pfade kann auch für die Routenplanung in einem Navigationssystem<br />
eingesetzt werden. In dieser <strong>Aufgabe</strong> sollen Sie ein solches Routenplanungssystem in C++<br />
implementieren. Dazu gehen wir von einer List von 154 deutschen Städten aus, die mit jeweils den<br />
Distanzen zu einigen Umliegenden Städten in der Datei entfernungen.txt gespeichert sind (keine Angst,<br />
für das Einlesen der Datei wird Code zur Verfügung gestellt). Daraus lässt sich ein Graph dieser Städte<br />
mit den Entfernungen als Gewichten erzeugen. Ein Code‐Template finden Sie auf der Homepage. Da<br />
diese <strong>Aufgabe</strong> viele Klassen der C++‐Standardbibliothek nutzt, seien hier noch einmal einige Links zu<br />
deren Dokumentation angegeben:<br />
std::list: http://www.cplusplus.com/reference/stl/list/<br />
std::map: http://www.cplusplus.com/reference/stl/map/<br />
std::vector: http://www.cplusplus.com/reference/stl/vector/<br />
Gehen Sie bei der Bearbeitung dieser <strong>Aufgabe</strong> wieder von dem <strong>Algorithmus</strong> in <strong>Aufgabe</strong> 1 aus!<br />
a) Implementieren Sie nun im gegebenen Code‐Template Dijkstra’s <strong>Algorithmus</strong> in der Funktion<br />
dijkstra() und eine Methode zum Ausgeben des kürzesten Pfades zu einer gegebenen Stadt nach<br />
dem Aufruf von dijkstra() in print_route(). Zum extrahieren des kleinsten Elements aus der Schlange<br />
Q können Sie die Funktion getMinimum() benutzen (siehe <strong>Aufgabe</strong> b).<br />
Geben Sie mit ihrem Programm in main() die kürzesten Routen für folgende Städte‐Paare zusammen<br />
mit der Gesamtstrecke der Route aus (rufen Sie dijkstra() so selten wie möglich auf):<br />
München – Hamburg<br />
München – Augsburg<br />
Ulm – Rostock<br />
Heidelberg – Stuttgart
Christoph Garbe: Algorithmen und Datenstrukturen, SS 09 Übungsblatt 10<br />
Abgabe: bis 12.06.2009, 12:00 Uhr<br />
<br />
<br />
Heidelberg – Karlsruhe<br />
Mannheim – Schweinfurt<br />
(20 Punkte)<br />
b) In obiger Implementation sollten Sie eine ineffiziente Methode getMinimum() verwenden. Erläutern<br />
Sie kurz (!!!), wie diese implementiert ist und geben Sie ihre Laufzeit an. Wie könnte man die<br />
Implementation verbessern? Beschreiben Sie an welchen Stellen welche Änderungen am Code<br />
vorgenommen werden müssen und welche Datenstruktur Sie evtl. anwenden würden. (1+4 Punkte)<br />
c) Bonusaufgabe: Implementieren Sie ein effizienteres getMinimum() Verfahren (10 Bonuspunkte)