-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGraphAlgorithms.java
More file actions
135 lines (124 loc) · 5.19 KB
/
GraphAlgorithms.java
File metadata and controls
135 lines (124 loc) · 5.19 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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import java.util.*;
public class GraphAlgorithms {
private static int time;
// Performs breadth-first search
public static <V, E> Set<Vertex<V>> BFS(Graph<V, E> g, Vertex<V> s) {
s.setPredecessor(null);
s.setDistFromSource(0.0);
Queue<Vertex<V>> frontier = new LinkedList<>();
Set<Vertex<V>> discovered = new HashSet<>();
frontier.add(s);
discovered.add(s);
while (!frontier.isEmpty()) {
Vertex<V> u = frontier.remove();
for (Edge<V, E> e : g.neighbors(u)) {
Vertex<V> v = e.getV();
if (!discovered.contains(v)) {
v.setPredecessor(u);
v.setDistFromSource(u.getDistFromSource() + 1);
frontier.add(v);
discovered.add(v);
}
}
}
return discovered;
}
// Prints breadth-first tree
public static <V> void predecessorSubgraphBFS(Vertex<V> s, Vertex<V> v) {
if (s == v) {
System.out.print(s);
} else if (v.getPredecessor() == null) {
System.out.println("There is no path from s to v.");
} else {
predecessorSubgraphBFS(s, v.getPredecessor());
System.out.print(" -> " + v);
}
}
// Performs top-level depth-first search iterating over the choices of vertex u
public static <V,E> Map<Vertex<V>,Edge<V, E>> DFS(Graph<V, E> g) {
Set<Vertex<V>> discovered = new HashSet<>();
Map<Vertex<V>, Edge<V, E>> forest = new HashMap<>();
time = 0;
for (Vertex<V> u : g.vertices()) {
if (!discovered.contains(u)) {
DFS(g, u, discovered, forest);
}
}
return forest;
}
// Performs depth-first search iterating over outgoing edges from vertex u
private static <V, E> void DFS(Graph<V, E> g, Vertex<V> u, Set<Vertex<V>> discovered, Map<Vertex<V>,Edge<V, E>> forest) {
discovered.add(u);
time += 1;
u.setDiscoveredTimestamp(time);
for (Edge<V, E> e : g.neighbors(u)) {
Vertex<V> v = e.getV();
if (!discovered.contains(v)) {
forest.put(v, e);
DFS(g, v, discovered, forest);
}
}
time += 1;
u.setFinishedTimestamp(time);
}
// Prints discovered and finished timestamps from depth-first search for each vertex in graph
public static <V, E> void startFinishTimesDFS(Graph<V, E> g) {
for (Vertex<V> u : g.vertices()) {
System.out.println(u + ": " + u.getDiscoveredTimestamp() + ", " + u.getFinishedTimestamp());
}
}
/* strongly connected components
// Call DFS(G)
// Compute G transpose
// call DFS(GT) consider vertices in order of decreasing u.f
// output vertices in each tree as separate strongly connected component
public static<V, E> void stronglyConnectedComponents(Graph<V, E> g) {
DFS(g);
Graph<V, E> gt = graphTranspose(g);
} */
// Computes the transpose of given graph
public static<V, E> void graphTranspose(Graph<V, E> g) {
throw new UnsupportedOperationException("not implemented yet");
}
// Performs Kruskal's algorithm on given graph
// Returns a set of least-weight edges that form the minimum spanning tree
public static <V, E> Set<Edge<V, E>> kruskalMST(Graph<V, E> g) {
Set<Edge<V, E>> A = new HashSet<>();
DisjointSet<V> s = new DisjointSet<>();
for (Vertex<V> v : g.vertices()) {
s.makeSet(v);
}
for (Edge<V, E> edge : g.edges()) {
if (s.findSet(edge.getU()) != s.findSet(edge.getV())) {
// Safe edge added to A is least-weight edge connecting two distinct components
A.add(edge);
s.union(edge.getU(), edge.getV());
}
}
return A;
}
// Performs Prim's algorithm on given graph and takes as an additional parameter a start vertex
// Returns a set of least-weight edges that form the minimum spanning tree
public static <V, E> Set<Edge<V, E>> primMST(Graph<V, E> g, Vertex<V> r) {
Set<Edge<V, E>> B = new HashSet<>();
r.setMinWeight(0.0);
g.vertices().remove(r);
PriorityQueue<Vertex<V>> Q = new PriorityQueue<>(g.vertices());
while (!Q.isEmpty()) {
Vertex<V> u = Q.remove();
for (Edge<V, E> e : g.neighbors(u)) { // for each v in G.Adj[u]
if (Q.contains(e.getV()) && e.getWeight() < e.getV().getMinWeight()) { // if v in Q and w(u,v) < v.key
e.getV().setPredecessor(u); // v.pi = u
e.getV().setMinWeight(e.getWeight()); // v.key = w(u,v)
System.out.println(e);
}
}
}
for (Edge<V, E> e : g.edges()) {
if (e.getWeight().equals(e.getV().getMinWeight())) {
B.add(e);
}
}
return B;
}
}