-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathCircuitSwitchingDP.java
293 lines (269 loc) · 11.2 KB
/
CircuitSwitchingDP.java
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
/** PROJECT DETAILS
* Author : Soham Kapur
* Year : 2023
* Title : Circuit Switching using Dynamic Programming
* Purpose : Undergraduate Graded Project
* Course : Computer Networks
* Desc : Simulation of Circuit Switching in Java to find optimal set of paths for multiple data transfers using Dynamic Programming.
*/
import java.util.*;
public class CircuitSwitchingDP
{
ArrayList<Integer>[] adjList;
static int n=0, k=0, s[], d[], min=Integer.MAX_VALUE;
/* VARIABLES:
* n: Number of data transfers
* k: Counter for current Source and Destination pair being checked
* s: Array to store all Souce nodes.
* d: Array to store all Destination nodes.
* min: Stores the minimum Longest path distance of the checked combinations ofpaths.
*/
/*
* This is the Graph (Network) consisting of nodes and edges expressed as an Adjacency Matrix, using a DDA.
* The index value represents the nodes and the array elements at the coordinates represent the Edge weight between the 2 nodes.
* The edge with direction from node u to node v will be at Graph[u][v].
* The sample graph used here is an Undirected Graph, but a Directed Graph can also be used without any other change in the code.
*/
int Graph[][] = { { 0, 4, 0, 0, 0, 0, 0, 8, 0 },
{ 4, 0, 8, 0, 0, 0, 0, 11, 0 },
{ 0, 8, 0, 7, 0, 4, 0, 0, 2 },
{ 0, 0, 7, 0, 9, 14, 0, 0, 0 },
{ 0, 0, 0, 9, 0, 10, 0, 0, 0 },
{ 0, 0, 4, 14, 10, 0, 2, 0, 0 },
{ 0, 0, 0, 0, 0, 2, 0, 1, 6 },
{ 8, 11, 0, 0, 0, 0, 1, 0, 7 },
{ 0, 0, 2, 0, 0, 0, 6, 7, 0 } };
//This copy of the graph is created so that the user can use this code in a loop (not present in this code) without changing the original Graph.
int altGraph[][] = Graph;
//The mpdifications to the original Graph present in the Alternate Graph (altGraph) will be explained later in the code.
int v = Graph[0].length;
boolean visited[] = new boolean[v];
static ArrayList<ArrayList<Integer>>[] allPaths; //Data structure to store all possible paths between 2 nodes
static ArrayList<Integer>[] distances; //Data structure to store total distance or weight of each path between 2 given nodes
static ArrayList<Integer>[] FinalPaths; //Data Structure to store the final set of paths that should be chosen
// Constructor to initialise 'v', the number of nodes
public CircuitSwitchingDP()
{
this.v = v;
initAdjList();
}
// utility method to initialise adjacency lists
void initAdjList()
{
int i;
adjList = new ArrayList[v];
for (i = 0; i < v; i++)
adjList[i] = new ArrayList<>();
allPaths = new ArrayList[n];
for(i=0; i<n; i++)
allPaths[i] = new ArrayList<>();
distances = new ArrayList[n];
FinalPaths = new ArrayList[n];
for(i=0; i<n; i++)
FinalPaths[i] = new ArrayList<>();
}
/* The graph is transferred from a DDA to an Array of ArrayLists.
* This prevents checking of pairs of nodes that do not have any edge, thus improving speed in the following operations.
*/
public void addEdges()
{
int n=v;
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
if(Graph[i][j]>0)
adjList[i].add(j);
}
/* In the alternate graph, all incoming edges of every Source node and all outgoing edges of every Destination node are eliminated.
* This reduces the number of edges that the program has to check, thus improving speed and efficiency.
*/
public void AltGraph()
{
for(int i=0; i<n; i++)
for(int j=0; j<9; j++)
{
altGraph[j][s[i]] = 0;
altGraph[d[i]][j] = 0;
}
}
// Parts of this function have been taken from the code for finding All Paths in a Graph, available on "Geeks For Geeks"
public void getAllPaths(int s, int d)
{
boolean[] isVisited = new boolean[v];
ArrayList<Integer> pathList = new ArrayList<>();
// add source to path[]
pathList.add(s);
// Call utility function
getAllPathsUtil(s, d, isVisited, pathList, 0);
}
// Parts of this function have been taken from the code for finding All Paths in a Graph, available on "Geeks For Geeks"
private void getAllPathsUtil(Integer u, Integer d, boolean[] isVisited, ArrayList<Integer> localPathList, int distance)
{
/* An if condition that prevents the checking of some extra paths by terminating the recursion if the destination node is adjacent to the current node.
* This prevents the checking of some useless paths and saves time.
* It assumes that the direct edge between any two nodes is the shortest possible path between them.
* This condition is only useful when all edges have positive weights.
*/
if(altGraph[u][d]>0)
{
localPathList.add(d);
allPaths[k].add(new ArrayList<>(localPathList));
distances[k].add(distance + altGraph[u][d]);
localPathList.remove(d);
return;
}
isVisited[u] = true;
// This loop having recursion checks the possibility of creating a path between the Source and Destination using every node.
for (Integer i : adjList[u])
{
if (!isVisited[i])
{
// store current node in path
localPathList.add(i);
distance += altGraph[u][i];
getAllPathsUtil(i, d, isVisited, localPathList, distance);
distance -= altGraph[u][i];
// remove current node in path
localPathList.remove(i);
}
}
isVisited[u] = false;
}
//This function uses Bubble Sort to sort the paths between every pair of Source and Destination nodes with respect to total distance/weight.
void sortPaths()
{
for(int h=0; h<n; h++)
{
int l = allPaths[h].size();
for (int i = 0; i < l-1; i++)
for (int j = 0; j < l-i-1; j++)
if (distances[h].get(j) > distances[h].get(j+1))
{
Collections.swap(allPaths[h], j, j+1);
Collections.swap(distances[h], j, j+1);
}
}
}
//This function prints all the paths between every pair of Source and Destination nodes and their respective total distances.
public void printPaths()
{
for(int i=0; i<n; i++)
{
System.out.println("\nAll paths from " + s[i] + " to " + d[i] + " are:");
System.out.println("\tDistance\tPaths");
for(int j=0; j<allPaths[i].size(); j++)
System.out.println("\t " + distances[i].get(j) + "\t\t" + allPaths[i].get(j));
}
}
/* This is the function where the Dynamic Programming takes place.
* This function iterates through all possible combinations of paths.
* It returns the combination in which the Longest path is the smallest as compared to the Longest Paths in other combinations.
* Other conditions, such as Smallest Mean, Smallest Median or other statistical values using all paths in a combination, can also be used as required.
* The program will have to be modified to accomodate other or more conditions.
* The purpose of this function is to find the most optimal combination of paths as per the set condition for optimality.
*/
void AltPaths(int p, int max, ArrayList<Integer>[] finalPath)
{
if(p==n)
{
// This is the if statement that finalises the combination based on the set condition.
if(min>max)
{
System.out.println();
min = max;
finalise(finalPath);
System.out.println(finalPath);
}
return;
}
int i, j, l = allPaths[p].size();
//This loop recursively creates all combinations of paths to ultimately check the optimality condition.
for(i=0; i<l; i++)
{
if(checkIntersect(allPaths[p].get(i)))
continue;
visit(allPaths[p].get(i), p);
max = Math.max(max, distances[p].get(i));
finalPath[p] = new ArrayList<>();
finalPath[p] = allPaths[p].get(i);
AltPaths(p+1, max, finalPath);
unvisit(finalPath[p], p);
finalPath[p].clear();
}
}
//This function checks if any node in the selected path is already present in a previously selected path.
boolean checkIntersect(ArrayList<Integer> path)
{
for(int i=1; i<path.size()-1; i++)
if(visited[path.get(i)])
return true;
return false;
}
// This functions visits all nodes in a path so that they can be checked for intersection of another path.
void visit(ArrayList<Integer> path, int p)
{
for(int i=1; i<path.size()-1; i++)
visited[path.get(i)] = true;
}
// This function 'unvisits' all nodes in a path once that paths is deleted from the current combination.
void unvisit(ArrayList<Integer> path, int p)
{
for(int i=1; i<path.size()-1; i++)
visited[path.get(i)] = false;
}
// This function adds the selected combination to a global variable to be accessed later on.
void finalise(ArrayList<Integer>[] finalPath)
{
for(int i=0; i<n; i++)
FinalPaths[i] = new ArrayList<>(finalPath[i]);
}
// This funciton prints the finalised combination, and if there is no data then prints the appropriate message.
void printFinal()
{
System.out.println("Max distance: " + min + "\nFinal list of paths is: ");
for(int i=0; i<n; i++)
{
if(FinalPaths[i].size()==0)
{
System.out.println("The given data transfers cannot occur simultaneously.");
break;
}
else
System.out.println(FinalPaths[i]);
}
}
// Driver code
public static void main()
{
Scanner sc = new Scanner(System.in);
System.out.println("Enter no. of paths to travel:");
n = sc.nextInt();
s = new int[n];
d = new int[n];
ArrayList <Integer>[] finalPath = new ArrayList[n];
int i, j;
for(i=0; i<n; i++)
finalPath[i] = new ArrayList<>();
CircuitSwitchingDP g = new CircuitSwitchingDP();
for(i=0; i<n;i++)
{
System.out.println("Enter Source " + (i+1) + ":");
s[i] = sc.nextInt();
System.out.println("Enter Destination " + (i+1) + ":");
d[i] = sc.nextInt();
}
g.AltGraph();
g.addEdges();
for(i=0; i<n; i++)
{
k=i;
distances[i] = new ArrayList<>();
g.getAllPaths(s[i], d[i]);
}
System.out.println("\n\nSorted Paths: ");
g.sortPaths();
g.printPaths();
System.out.println("\n");
g.AltPaths(0, 0, finalPath);
g.printFinal();
}
}