Sie sind auf Seite 1von 8

Fachhochschule Kiel Fachbereich Informatik und Elektrotechnik Leitung: Prof. Dr. rer. nat. Nils Gruschka Dozent: Louis Jorswieck Sommersemester 13/14

Labor Algorithmen und Datenstrukturen

AUD-INI-2014-14

Abgegeben am:

24.06.2014

Tim Niklas Jahn – MatrNr: 922381 tim.n.jahn@student.fh-kiel.de

Tobias Sandmeier – MatrNr: 922534 tobias.sandmeier@student.fh-kiel.de

Tim Jannes Bedey – MatrNr 922386 tim.j.bedey@student.fh-kiel.de

Inhaltsverzeichnis

  • 1. Programmverhalten..........................................................................................................................3

Problemstellung...............................................................................................................................3

Festlegung der Dialogführung.........................................................................................................3 Reaktion auf Bedienfehler...............................................................................................................3

  • 2. Testplan.............................................................................................................................................4

  • 3. Algorithmus......................................................................................................................................4

Illustration der Tiefensuche.............................................................................................................5

  • 4. Systemstruktur..................................................................................................................................6

Datenstrukturen................................................................................................................................6

Logischer Programmablauf..............................................................................................................7 Struktur des Programms...................................................................................................................7

Schnittstellen....................................................................................................................................8

Testlauf ............................................................................................................................................8

1. Programmverhalten

Problemstellung

Das Programm liest eine Struktur ein, welches verschiedene Pfade für den Weg eines Fahrzeugs über mehrere Knotenpunkte aufweist. Alle Pfade entspringen hierbei dem Ursprung A. Nach der Angabe eines Zieles wird die Struktur traversiert und anschließend auf Zyklen geprüft. Das Programm gibt daraufhin Wege und Zwischenknoten aus, die auf dem Weg/den Wegen zum Ziel liegen. Alle gefundenen Wege werden in aufsteigender Reihe ausgegeben, der kürzeste Pfad wird zuerst ausgegeben.

Festlegung der Dialogführung

Eingabe des Filenamen:

„Bitte geben Sie den Dateinamen eingeben:“ Eingabe des Startknoten:

„Bitte geben Sie den gewünschten Startknoten ein:“ Beispiel: A Eingabe des Zielknoten:

„Bitte geben Sie den gewünschten Zielknoten ein:“ Beispiel: D

Ausgabe der Wege und Länge (Start-, Zwischen- und Zielknoten):

„Die Wege zum Ziel D sind:“

Länge

2: A ->

C -> D

Länge

2: A ->

B -> D

Länge 3: A -> F -> C -> D Länge 3: A -> E -> B -> D

Reaktion auf Bedienfehler

Der Benutzer gibt einen ungültigen Zielknoten ein:

„Der eingegebene Zielknoten ist ungültig. Bitte geben Sie ein neuen Zielknoten an:“

2.

Testplan

Test

1. Leere Datei

  • 2. Graph enthält Zyklus

  • 3. Ziel ist von mehreren Knoten/ Wegen aus

erreichbar

  • 4. Ziel ist nur über einen Weg erreichbar

  • 5. Ziel existiert nicht

  • 6. Ziel ist bereits der Startpunkt

  • 7. Systemfunktionalität

  • 3. Algorithmus

Erwartetes Verhalten

Fehlermeldung

Abbruch der Traversierung/ Fehlermeldung

Ausgabe aller Wege (Start-, Zwischen- und Zielknoten)

Ausgabe des Weges (Start- und Zielknoten)

Traversierung des Graphen/ Fehlermeldung

Siehe Reaktion auf Bedienfehler

Windows, MAC OS, Linux

Wird ein Graph ausgehend von einem Startknoten traversiert, lassen sich entweder die Algorithmen Breiten- oder Tiefensuche anwenden.

Die Breitensuche besucht alle direkten Nachbarknoten vom Wurzelknoten. Diese Knoten werden in eine Liste eingefügt. Daraufhin werden die Nachbarknoten der in dieser Liste gespeicherten Knoten besucht. Noch nicht entdeckte Nachbarn dieser Knoten werden wiederum in die Liste eingefügt. Der Prozess wiederholt sich solange, bis die Liste leer ist. Die Laufzeit für die Breitensuche wird bestimmt durch die Anzahl der Knoten sowie für jeden Knoten die Zeit, alle ausgehenden Kanten zu prüfen. Die Laufzeit setzt sich zusammen aus der Anzahl der Knoten V und Kanten E also:

O(V + E).

Bei der Tiefensuche werden für jeden Knoten im Graphen alle Kanten ausgehend vom Startknoten getestet. Der erste Nachbarknoten, der noch nicht entdeckt wurde, wird als nächstes besucht. Von diesem Knoten aus wird wieder der erste Nachbarknoten ausgewählt, sofern er zuvor noch nicht besucht wurde. Falls ein Knoten keine unbesuchten Kinder mehr besitzt, wandert die Tiefensuche zurück zum vorherigen Knoten und testet, ob dieser schon abgearbeitet wurde. Falls noch unbesuchte Nachbarknoten existieren, werden wiederum die nächsten nicht besuchten Nachbarn abgearbeitet. Der Prozess endet, wenn alle erreichbaren Knoten im Graphen besucht wurden. Die Laufzeit der Tiefensuche ist O(V + E), wenn der Graph als Adjazenzliste gespeichert wird. Die Funktionalität des gewünschten Programms kommt diesem Algorithmus am nächsten, jedoch gibt es einen schwerwiegenden Nachteil. Wenn eine Verzweigung unendlich lang ist, kann kein Ziel gefunden werden. Deshalb ist es nötig den Graphen auf Zyklen zu prüfen und möglicherweise die Tiefe zu beschränken.

Illustration der Tiefensuche

Illustration der Tiefensuche Abbildung 1 Abbildung 2 Abbildung 3 Abbildung 5 Abbildung 7 Abbildung 8
Illustration der Tiefensuche Abbildung 1 Abbildung 2 Abbildung 3 Abbildung 5 Abbildung 7 Abbildung 8

Abbildung 1

Abbildung 2

Illustration der Tiefensuche Abbildung 1 Abbildung 2 Abbildung 3 Abbildung 5 Abbildung 7 Abbildung 8

Abbildung 3

Illustration der Tiefensuche Abbildung 1 Abbildung 2 Abbildung 3 Abbildung 5 Abbildung 7 Abbildung 8

Abbildung 4

Illustration der Tiefensuche Abbildung 1 Abbildung 2 Abbildung 3 Abbildung 5 Abbildung 7 Abbildung 8

Abbildung 5

Abbildung 6

Illustration der Tiefensuche Abbildung 1 Abbildung 2 Abbildung 3 Abbildung 5 Abbildung 7 Abbildung 8
Illustration der Tiefensuche Abbildung 1 Abbildung 2 Abbildung 3 Abbildung 5 Abbildung 7 Abbildung 8
Illustration der Tiefensuche Abbildung 1 Abbildung 2 Abbildung 3 Abbildung 5 Abbildung 7 Abbildung 8
Abbildung 9 Abbildung 10 4. Systemstruktur Datenstrukturen Es werden Strukturen sowohl für die Knoten als auch
Abbildung 9 Abbildung 10 4. Systemstruktur Datenstrukturen Es werden Strukturen sowohl für die Knoten als auch

Abbildung 9

Abbildung 10

4. Systemstruktur

Datenstrukturen

Es werden Strukturen sowohl für die Knoten als auch für den Graphen selbst benötigt. Um den Aufbau des Graphen zu speichern, lässt sich entweder eine Adjazenzmatrix oder -liste implementieren. Obwohl Adjazenzlisten aufwendiger zu verwalten sind, bieten sie hier eine Reihe von Vorteilen. Bei „dünnen“ Graphen, welche wenige Kanten besitzen, verbrauchen sie stets nur linear viel Speicherplatz. In Bezug auf die Knotenanzahl besitzt die Adjazenzmatrix quadratischen Platzbedarf. Zudem ist es nicht nötig Werte der Kanten zu speichern, da ein ungewichteter Graph betrachtet wird.

Logischer Programmablauf

Logischer Programmablauf Struktur des Programms #define MAX_NAME 50 #define MAX_NODES 10000 path structure struct Path {

Struktur des Programms

#define MAX_NAME 50 #define MAX_NODES 10000

path structure struct Path { int num_nodes; int nodes[MAX_NODES]; };

node stucture struct Node { char name[MAX_NAME]; int num_adj; int *adj; };

struct Node graph[MAX_NODES]; int num_nodes; char used[MAX_NODES];

struct Path *sorted_paths; int num_sorted_paths;

Schnittstellen

int compare_paths(const void *a, const void *b) void sort_paths() qsort(sorted_paths, num_sorted_paths, sizeof(struct Path), compare_paths) void add_path(struct Path *p) void print_path(struct Path *p) void print_sorted_paths() void dfs(int A, int B) void add_adj(int _u, int _v) int addnode(char *name) int findnode(char *name) void add_nodes(char *namea, char *nameb) void parse_dot_input(char *fname) int main(int argc, char *argv[])

Testlauf

Bitte geben Sie den Dateinamen ein: input.dot Bitte geben Sie den gewuenschten Startknoten ein: A Bitte geben Sie den gewuenschten Zielknoten ein D

  • 2 A ->

C -> D

  • 2 A ->

B -> D

  • 3 A -> F -> C -> D

  • 3 A -> E -> B -> D

--------------------------------

Process exited with return value 0

Press any key to continue

. .

.