-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGraphLists.java
More file actions
381 lines (312 loc) · 11.2 KB
/
Copy pathGraphLists.java
File metadata and controls
381 lines (312 loc) · 11.2 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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
// Importing necessary libraries for file reading, data structures, and input/output
import java.io.*;
import java.util.Queue;
import java.util.Scanner;
import java.util.LinkedList;
// Definition of the Heap class for efficient implementation of Prim's Algorithm
class Heap {
// Declaring necessary instance variables for the heap
private int[] a; // heap array
private int[] hPos; // hPos[h[k]] == k
private int[] dist; // dist[v] = priority of v
private int N; // heap size
// Constructor for the Heap class
// Takes maximum heap size, reference to the dist[] array, and reference to the
// hPos[] array
public Heap(int maxSize, int[] _dist, int[] _hPos) {
N = 0;
a = new int[maxSize + 1];
dist = _dist;
hPos = _hPos;
}
// Method to check if the heap is empty
public boolean isEmpty() {
return N == 0;
}
// Method to perform sift-up operation in the heap
public void siftUp(int k) {
// Get the vertex at index k
int v = a[k];
// Perform sift-up operation until the vertex's priority is higher than its
// parent's priority
while (dist[v] < dist[a[k / 2]]) {
hPos[a[k]] = k / 2;
a[k] = a[k / 2];
k = k / 2;
}
a[k] = v;
hPos[v] = k;
}
// Method to perform sift-down operation in the heap
public void siftDown(int k) {
int v, j;
v = a[k];
// Perform sift-down operation until the vertex's priority is lower than its
// children's priorities
while (k * 2 < N) {
j = k * 2;
if (j < N && dist[a[j]] > dist[a[j + 1]]) {
++j;
}
if (dist[v] <= dist[a[j]]) {
break;
}
hPos[a[k]] = j;
a[k] = a[j];
k = j;
}
hPos[v] = k;
a[k] = v;
}
// Method to insert a vertex into the heap
public void insert(int x) {
System.out.println("Inserting: " + toChar(x));
a[++N] = x;
siftUp(N);
}
// Method to remove the minimum vertex from the heap
public int remove() {
int v = a[1];
System.out.println("Removing: " + toChar(v));
hPos[v] = 0;
a[1] = a[N--];
siftDown(1);
a[N + 1] = 0;
return v;
}
// Method to convert vertex number to corresponding character
private char toChar(int u) {
return (char) (u + 64);
}
}
// Definition of the Graph class
class Graph {
// Definition of the Node class for adjacency lists
class Node {
public int vert; // Vertex
public int wgt; // Weight
public Node next; // Next node
}
// Instance variables for the graph
private int V, E; // Number of vertices and edges
private Node[] adj; // Adjacency lists array
private Node z; // Sentinel node
private int[] mst; // Minimum Spanning Tree array
// Variables for traversing the graph
private int[] visited; // Array to track visited vertices
private int id; // Identifier for vertices
// Constructor for the Graph class
public Graph(String graphFile) throws IOException {
int u, v; // Vertices
int e, wgt; // Edges and weights
Node t, w; // Temporary nodes for edge creation
// Reading the graph file
FileReader fr = new FileReader(graphFile);
BufferedReader reader = new BufferedReader(fr);
try {
String splits = " +"; // Delimiter for splitting lines
String line = reader.readLine();
String[] parts = line.split(splits);
System.out.println("Parts[] = " + parts[0] + " " + parts[1]);
V = Integer.parseInt(parts[0]); // Extracting number of vertices
E = Integer.parseInt(parts[1]); // Extracting number of edges
// Creating sentinel node
z = new Node();
z.next = z;
// Creating adjacency lists, initialized to sentinel node z
adj = new Node[V + 1];
for (v = 1; v <= V; ++v)
adj[v] = z;
// Reading the edges from the file
System.out.println("Reading edges from text file");
for (e = 1; e <= E; ++e) {
line = reader.readLine();
parts = line.split(splits);
u = Integer.parseInt(parts[0]);
v = Integer.parseInt(parts[1]);
wgt = Integer.parseInt(parts[2]);
System.out.println("Edge " + toChar(u) + "--(" + wgt + ")--" + toChar(v));
// Creating nodes for the edge and adding them to the adjacency lists
t = new Node();
t.vert = v;
t.wgt = wgt;
t.next = adj[u];
adj[u] = t;
w = new Node();
w.vert = u;
w.wgt = wgt;
w.next = adj[v];
adj[v] = w;
}
} finally {
// Closing the reader in the finally block to ensure it gets closed
if (reader != null) {
reader.close();
}
}
}
// Method to convert vertex number to corresponding character
private char toChar(int u) {
return (char) (u + 64);
}
// Method to display the graph representation
public void display() {
int v;
Node n;
System.out.println("Vertex Edge Weight");
for (v = 1; v <= V; ++v) {
System.out.print("\nadj[" + toChar(v) + "] ->");
for (n = adj[v]; n != z; n = n.next)
System.out.print(" |" + toChar(n.vert) + " | " + n.wgt + "| ->");
}
System.out.println("");
}
// Prim's Minimum Spanning Tree Algorithm
public void MST_Prim(int s) {
int v;
int wgt_sum = 0; // Total weight of MST
int[] dist, parent, hPos; // Arrays for distances, parent vertices, and heap positions
Node t;
// Initializing arrays
dist = new int[V + 1];
parent = new int[V + 1];
hPos = new int[V + 1];
for (int i = 1; i <= V; i++) {
dist[i] = Integer.MAX_VALUE;
parent[i] = 0;
hPos[i] = 0;
}
parent[s] = s;
dist[s] = 0;
dist[0] = 0;
// Creating and initializing heap
Heap pq = new Heap(V, dist, hPos);
pq.insert(s);
// Main loop of Prim's algorithm
while (!(pq.isEmpty())) {
v = pq.remove();
// Marking vertex as visited by negating the distance
dist[v] = -dist[v];
System.out.println("Visited: " + toChar(v));
System.out.println("\n");
t = adj[v];
// Iterating through adjacent vertices
while (t.next != t) {
// If the vertex hasn't been visited and its distance is less than the current
// distance
if (t.wgt < dist[t.vert] && dist[t.vert] > 0) {
dist[t.vert] = t.wgt;
parent[t.vert] = v;
// Inserting or updating the vertex in the heap
if (hPos[t.vert] == 0) {
pq.insert(t.vert);
} else {
pq.siftUp(hPos[t.vert]);
}
}
// Moving to the next adjacent vertex
t = t.next;
}
}
// Calculating total weight of MST
for (int i = 0; i <= V; i++) {
wgt_sum += dist[i];
}
// Ensuring result is positive integer for printing the final MST weight
wgt_sum *= -1;
// Printing final MST Weight
System.out.print("\n\n\nTOTAL MST WEIGHT ->> " + wgt_sum + "\n\n");
mst = parent;
}
// Method to display the MST
public void showMST() {
// Displaying MST Parent Array
System.out.print("\n\n\nMinimum Spanning tree parent array ->>\n");
// Traversing the MST and converting the integer values to alphabetical
// characters
for (int v = 1; v <= V; ++v)
if (v == mst[v]) {
// Demarking the starting node with an @ symbol
System.out.println(toChar(v) + " -> @");
} else {
System.out.println(toChar(v) + " -> " + toChar(mst[v]));
}
// Newline for formatting
System.out.print("\n\n");
}
// Depth First Traversal
public void DF(int s) {
id = 0;
visited = new int[V + 1];
System.out.println("");
for (int j = 1; j <= V; j++) {
visited[j] = 0;
}
dfVisit(0, s);
}
// Helper method for Depth First Traversal
private void dfVisit(int prev, int v) {
Node n = new Node();
n = adj[v];
visited[v] = ++id;
System.out.println("Visiting node [" + toChar(v) + "] from node [" + toChar(prev) + "]");
while (n.next != n) {
if (visited[n.vert] == 0) {
dfVisit(v, n.vert); // Recursively call the next vertex
}
n = n.next;
}
}
// Breadth First Traversal
public void BF(int s) {
int id = 0;
Node n;
Queue<Integer> q = new LinkedList<Integer>();
System.out.println();
System.out.println("Breadth First Traversal:");
// Initializing visited array
for (int i = 0; i <= V; i++) {
visited[i] = 0;
}
q.add(s);
while (!(q.isEmpty())) {
int v = q.poll();
if (visited[v] == 0) {
n = adj[v];
visited[v] = ++id;
System.out.println("Currently visiting [" + toChar(v) + "]");
while (n.next != n) {
if (visited[n.vert] == 0) {
q.add(n.vert);
}
n = n.next;
}
}
}
// Newlines for formatting
System.out.print("\n\n");
}
}
// Main class for executing the program
public class GraphLists {
// Main method for execution
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
String fname; // Filename for graph definition
System.out.print("\nInput name of file with graph definition: ");
fname = sc.nextLine(); // Taking filename input from user
System.out.print("\nInput the number of the vertex you want to start at: ");
int s = sc.nextInt(); // Taking starting vertex input from user
Graph g = new Graph(fname); // Creating graph object from the input file
g.display(); // Displaying the graph
System.out.println();
System.out.print("Depth first using recursion:");
g.DF(s); // Performing Depth First Traversal
System.out.println("MST using Prim's Algorithm:\n");
g.MST_Prim(s); // Finding Minimum Spanning Tree using Prim's Algorithm
g.showMST(); // Displaying the MST
System.out.print("Breadth first:");
g.BF(s); // Performing Breadth First Traversal
sc.close(); // Closing scanner object
}
}