-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathDijkstra.cpp
154 lines (113 loc) · 4.26 KB
/
Dijkstra.cpp
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include "Dijkstra.h"
#include "Graph.h"
#include "Node.h"
#include "Edge.h"
#include "ListPriorityQueue.h"
#include "HeapPriorityQueue.h"
#include <list>
#include <set>
#include <queue>
#include <iterator>
double findEdgeWeight(Node v, list<Edge> uEdges) { //find the destination node v containing edge from u
for(list<Edge>::iterator itr = uEdges.begin(); itr != uEdges.end(); itr++) {
Edge e = *itr;
if(e.v_id() == v.id())
return e.weight();
}
cerr << "findEdgeWeight: should never reach here!" << endl;
return -1;
}
void Dijkstra_list(Graph & g, Node & s) {
ListPriorityQueue q(g);
g.resetAllDist();
g.setDist(s, 0); //s is the root
q.insert(g, s);
while ( !q.empty() ) {
Node u = q.remove_min(g);
set<Node> uAdjNodes = g.getAdjNodes(u);
list<Edge> uEdges = g.getEdges(u);
// for every adjacent node v: (u)--->(v)
for(set<Node>::iterator v = uAdjNodes.begin(); v != uAdjNodes.end(); v++) {
int edgeWeight = findEdgeWeight(*v, uEdges);
if(g.dist(*v) > g.dist(u) + edgeWeight || g.dist(*v) == M_INFINITY) { //if v has not been visited
g.setDist(*v, g.dist(u) + edgeWeight); //v.dist == u.dist + 1
q.change_priority(g, *v); //push the adjacent node to back of the queue
}
} //end adjNodes loop
} //end while
}
void Dijkstra_heap(Graph & g, Node & s) {
HeapPriorityQueue q(g);
g.resetAllDist();
g.setDist(s, 0); //s is the root
q.insert(g, s);
while ( !q.empty() ) {
Node u = q.remove_min(g);
//instead of using a decrease-key operation on the heap,
//we will simply insert redundant nodes and skip visited nodes;
//this means more nodes will be inserted, but since heap is already logarithmic,
//the increase in runtime will not be significant
if (g.visited(u)) continue; //skip already visited nodes
g.setVisited(u);
set<Node> uAdjNodes = g.getAdjNodes(u);
list<Edge> uEdges = g.getEdges(u);
// for every adjacent node v: (u)--->(v)
for(set<Node>::iterator v = uAdjNodes.begin(); v != uAdjNodes.end(); v++) {
int edgeWeight = findEdgeWeight(*v, uEdges);
if(g.dist(*v) > g.dist(u) + edgeWeight || g.dist(*v) == M_INFINITY) {
g.setDist(*v, g.dist(u) + edgeWeight);
q.insert(g, *v);
}
} //end adjNodes loop
} //end while
}
void Dijkstra_tmg(Graph & g, Node & s, Node & e) {
HeapPriorityQueue q(g);
list<int> path;
g.resetAllDist();
g.setDist(s, 0); //s is the root
q.insert(g, s);
while ( !q.empty() ) {
Node u = q.remove_min(g);
if (g.visited(u)) continue; //skip previously visited nodes
if (g.visited(e)) break; //don't bother continuing once we've hit destination
g.setVisited(u);
set<Node> uAdjNodes = g.getAdjNodes(u);
list<Edge> uEdges = g.getEdges(u);
// for every adjacent node v: (u)--->(v)
for(set<Node>::iterator v = uAdjNodes.begin(); v != uAdjNodes.end(); v++) {
double edgeWeight = findEdgeWeight(*v, uEdges);
if(g.dist(*v) > g.dist(u) + edgeWeight || g.dist(*v) == M_INFINITY) {
g.setDist(*v, g.dist(u) + edgeWeight);
g.setParent(*v, u.id());
q.insert(g, *v);
}
} //end adjNodes loop
} //end while
/**** dijkstra has been run on source waypoint, check if destination visited ****/
if(!g.visited(e)) {
cout << "No path from start waypoint to destination waypoint." << endl;
return; //print error and return
}
/**** path has been found ****/
cout << "Path found!\nStart waypoint id: " << s.id() << " name:" << s.name() << endl;
cout << "End waypoint id: " << e.id() << " name:" << e.name() << endl;
int rover_prev;
Node rover = g.getNode(e.id());
while( rover.parent() != -1) {
rover_prev = g.parent(rover);
path.push_front(rover.id());
if(rover_prev == -1 || rover_prev == rover.id())
break;
rover = g.getNode(rover_prev);
}
// cin.ignore();
cout << "Origin: " << endl;
for(list<int>::iterator i = path.begin(); i != path.end(); i++) {
Node n = g.getNode(*i);
if(n.name() == e.name()) cout << "Destination: " << endl;
cout << n.edgeRoads() << endl;
cout << n.name() << " " << n.latitude() << " " << n.longitude() << endl;
}
cout << "Total distance: " << g.dist(e) << endl;
}