generated from COP3530/P2-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAlgorithms.cpp
More file actions
114 lines (96 loc) · 4.14 KB
/
Algorithms.cpp
File metadata and controls
114 lines (96 loc) · 4.14 KB
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
#include "Algorithms.h"
#include "GraphAdjList.h"
#include <queue>
#include <limits>
#include <unordered_map>
#include <algorithm>
#include <cmath>
using namespace bridges;
using namespace bridges::dataset;
using namespace bridges::datastructure;
using NodeDistPair = std::pair<double, int>;
// Dijkstra's Algorithm
std::vector<int> dijkstra(const GraphAdjList<int, OSMVertex, double>& graph, int startNode, int goalNode, std::unordered_map<int, double>& distances) {
for (const auto& pair : *graph.getVertices()) {
distances[pair.first] = std::numeric_limits<double>::infinity();
}
distances[startNode] = 0.0;
std::priority_queue<NodeDistPair, std::vector<NodeDistPair>, std::greater<>> priorityQueue;
priorityQueue.push({ 0.0, startNode });
std::unordered_map<int, int> cameFrom;
while (!priorityQueue.empty()) {
double currentDistance = priorityQueue.top().first;
int currentNode = priorityQueue.top().second;
priorityQueue.pop();
if (currentNode == goalNode) {
std::vector<int> path;
while (currentNode != startNode) {
path.push_back(currentNode);
currentNode = cameFrom[currentNode];
}
path.push_back(startNode);
std::reverse(path.begin(), path.end());
return path;
}
if (currentDistance > distances[currentNode]) continue;
for (const auto& edge : graph.outgoingEdgeSetOf(currentNode)) {
int destNode = edge.to();
double newDistance = currentDistance + edge.getEdgeData();
if (newDistance < distances[destNode]) {
distances[destNode] = newDistance;
cameFrom[destNode] = currentNode;
priorityQueue.push({ newDistance, destNode });
}
}
}
return {}; // Return an empty path if there is no solution
}
// Heuristic function for A*
double heuristic(const GraphAdjList<int, OSMVertex, double>& graph,int node1, int node2) {
const OSMVertex& v1 = graph.getVertex(node1)->getValue();
const OSMVertex& v2 = graph.getVertex(node2)->getValue();
double coords1[2], coords2[2];
v1.getCartesianCoords(coords1);
v2.getCartesianCoords(coords2);
double dx = coords1[0] - coords2[0];
double dy = coords1[1] - coords2[1];
return std::sqrt(dx * dx + dy * dy);
}
// A* Algorithm
std::vector<int> aStar(const GraphAdjList<int, OSMVertex, double>& graph, int startNode, int goalNode) {
std::unordered_map<int, double> gScore, fScore;
std::unordered_map<int, int> cameFrom;
for (const auto& pair : *graph.getVertices()) {
gScore[pair.first] = std::numeric_limits<double>::infinity();
fScore[pair.first] = std::numeric_limits<double>::infinity();
}
gScore[startNode] = 0.0;
fScore[startNode] = heuristic(graph, startNode, goalNode);
std::priority_queue<NodeDistPair, std::vector<NodeDistPair>, std::greater<>> openSet;
openSet.push({ fScore[startNode], startNode });
while (!openSet.empty()) {
int currentNode = openSet.top().second;
openSet.pop();
if (currentNode == goalNode) {
std::vector<int> path;
while (cameFrom.find(currentNode) != cameFrom.end()) {
path.push_back(currentNode);
currentNode = cameFrom[currentNode];
}
path.push_back(startNode);
std::reverse(path.begin(), path.end());
return path;
}
for (const auto& edge : graph.outgoingEdgeSetOf(currentNode)) {
int neighbor = edge.to();
double tentativeGScore = gScore[currentNode] + edge.getEdgeData();
if (tentativeGScore < gScore[neighbor]) {
cameFrom[neighbor] = currentNode;
gScore[neighbor] = tentativeGScore;
fScore[neighbor] = gScore[neighbor] + heuristic(graph, neighbor, goalNode);
openSet.push({ fScore[neighbor], neighbor });
}
}
}
return {}; // Return an empty path if there is no solution
}