-
Notifications
You must be signed in to change notification settings - Fork 0
/
graphAlgorithms-inl.h
157 lines (147 loc) · 5.45 KB
/
graphAlgorithms-inl.h
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
155
156
157
/*
Copyright (c) 2019
Swarthmore College Computer Science Department, Swarthmore PA
J. Brody, A. Danner, M. Gagne, L. Meeden, Z. Palmer, A. Soni, M. Wehar
Distributed as course material for Fall 2019
CPSC 035: Data Structures and Algorithms
*/
#include <stdexcept>
#include <iostream>
#include <string>
#include <utility>
#include "adts/stack.h"
#include "adts/stlStack.h"
#include "adts/queue.h"
#include "adts/stlQueue.h"
#include "adts/stlHashTable.h"
#include "adts/graph.h"
#include "adjacencyListGraph.h"
#include "adts/stlMinPriorityQueue.h"
#include "adts/edge.h"
#include "graphAlgorithms.h"
template <typename V, typename E, typename W>
bool reachableDFS(V src, V dest, Graph<V, E, W>* g) {
// create dictionary to keep track of which vertices have been visited
STLHashTable<V, bool> visits;
// add all vertices to hash table
vector<V> allVertices = g->getVertices();
for(int i = 0; i < allVertices.size(); i++) {
visits.insert(allVertices[i], false);
}
/****************************************************/
// use depth first search to find path through graph
// create stack to hold vertices
Stack<V> *vertices = new STLStack<V>();
// add first vertex, source, to stack
vertices->push(src);
// mark vertex as visited
visits.update(src, true);
// repeat until stack is empty, adding adjacent vertices
while(!vertices->isEmpty()) {
// remove from top of stack
V current = vertices->pop();
// check if current is the destination vertex
if(current == dest) {
delete vertices;
return true; // found a path
} else {
// add adjacent vertices to stack
vector<V> neighbors = g->getNeighbors(current);
// add all neighbors to stack
for(int i = 0; i < neighbors.size(); i++) {
if(visits.get(neighbors[i]) == false) {
vertices->push(neighbors[i]);
// mark vertex as visited
visits.update(neighbors[i], true);
}
}
}
}
delete vertices;
return false; // no path found
}
template <typename V, typename E, typename W>
vector<V> shortestLengthPathBFS(V src, V dest, Graph<V, E, W>* g) {
// create dictionary to keep track of which vertices have been visited
STLHashTable<V, bool> visits;
// add all vertices to hash table
vector<V> allVertices = g->getVertices();
for(int i = 0; i < allVertices.size(); i++) {
visits.insert(allVertices[i], false);
}
// init vector to return path
vector<V> shortestPath;
// init hash table for previous vertices
STLHashTable<V, V> previousSet;
/****************************************************/
// use breadth first search to find path through graph
// create queue to hold vertices
Queue<V> *vertices = new STLQueue<V>();
// add first vertex, source, to queue
vertices->enqueue(src);
// mark vertex as visited
visits.update(src, true);
// repeat until queue is empty, adding adjacent vertices
while(!vertices->isEmpty()) {
// remove from first in queue
V current = vertices->dequeue();
// check if current is the destination vertex
if(current == dest) {
while(current != src) {
shortestPath.push_back(current);
current = previousSet.get(current);
}
// add start vertex
shortestPath.push_back(current);
// make new vector
vector<V> toReturn;
// switch order of path
for(int i = shortestPath.size() - 1; i > -1; i--) {
toReturn.push_back(shortestPath[i]);
}
delete vertices;
return toReturn; // found a path, return vector of vertices
} else {
// add adjacent vertices to queue
vector<V> neighbors = g->getNeighbors(current);
// add all neighbors to queue
for(int i = 0; i < neighbors.size(); i++) {
if(visits.get(neighbors[i]) == false) {
vertices->enqueue(neighbors[i]);
// save neighbor's previous in hash table
previousSet.insert(neighbors[i], current);
// mark vertex as visited
visits.update(neighbors[i], true);
}
}
}
}
delete vertices;
throw runtime_error("No path found."); // no path found
}
template <typename V, typename E, typename W>
Dictionary<V, W>* singleSourceShortestPath(V src, Graph<V, E, W>* g) {
Dictionary<V, W> *vertices = new STLHashTable<V, W>();
STLMinPriorityQueue<W, V> *edgeWeights = new STLMinPriorityQueue<W, V>();
// insert first vertex
edgeWeights->insert(0, src);
// repeat until dictionary is full or until queue is empty
while ((vertices->getSize() != g->getVertices().size()) &&
(!edgeWeights->isEmpty())){
int priority = edgeWeights->peekPriority();
V current = edgeWeights->remove(); // get lowest priority vertex
// if the vertex isn't in the dictionary
if (!vertices->contains(current)) {
vector<Edge<V, E, W>> outgoing = g->getOutgoingEdges(current);
// add vertex to dictionary
vertices->insert(current, priority);
// add all outgoing edges and weights to the priority queue
for (int i = 0; i < outgoing.size(); i++) {
edgeWeights->insert(vertices->get(current) + outgoing[i].getWeight(),
outgoing[i].getDestination());
}
}
}
delete edgeWeights;
return vertices;
}