Skip to content

Commit e53fce7

Browse files
committed
Changed the efficient bridge-finding algorithm
Got rid of the unnecessary visited and parent array to make it more space efficient. I also used the idea that the low array is the lowest numbered vertex that can be reached, so a depth first search can initiate at a connected component by passing the vertex itself in as its parent.
1 parent 61099e2 commit e53fce7

File tree

1 file changed

+42
-35
lines changed
  • algorithm/graph_search/bridges/efficient

1 file changed

+42
-35
lines changed

algorithm/graph_search/bridges/efficient/code.js

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,61 +4,70 @@
44

55
var timer = 0, bridges = [], adj = []; //adj keeps track of the neighbors of each node
66

7-
var util = function (u, visited, disc, low, parent) {
7+
var util = function (u, disc, low, parent) {
8+
//u is the node that is currently being processed in the DFS (depth-first search)
9+
//disc is the numbering of the vertices in the DFS, starting at 0
10+
//low[v] is the lowest numbered vertex that can be reached from vertex v along the DFS
11+
//parent is the node that u came from
812
logger._print ('');
913
logger._print ('Visiting node ' + u);
1014
graphTracer._visit (u)._wait ();
1115
graphTracer._leave (u)._wait ();
1216

13-
visited [u] = true;
14-
disc [u] = low [u] = ++timer;
17+
//visited [u] = true;
18+
disc [u] = low [u] = timer++;
1519

1620
logger._print ('Nodes adjacent to ' + u + ' are: [ ' + adj [u] + ' ]');
17-
adj [u].forEach (function (v) {
21+
/*adj [u].forEach (function (v) {
1822
graphTracer._visit (v, u)._wait ();
1923
graphTracer._leave (v, u)._wait ();
20-
});
24+
});*/
25+
var trace = function(v) {
26+
graphTracer._visit (v, u)._wait ();
27+
graphTracer._leave (v, u)._wait ();
28+
}
2129

2230
adj [u].forEach (function (v) {
23-
if (visited [v]) {
24-
logger._print (u + '\'s neighbor ' + v + ' has already been visited. Not visiting it.');
31+
if (disc [v] > -1 && v == parent) {
32+
trace(v);
33+
logger._print (u + '\'s neighbor ' + v + ' is u\'s parent. Not visiting it.');
34+
35+
}
36+
else if (disc[v] > -1 && v != parent) {
37+
trace(v);
38+
logger._print(u + '\'s neighbor ' + v + ' is not u\'s parent. Comparing low[u] with disc[v]')
39+
if(low[u] > disc[v]) {
40+
logger._print('low[' + u + '] is greater than disc[' + v + ']. Setting low[' + u + '] to disc[' + v + ']')
41+
low[u] = disc[v]
42+
}
2543
}
2644

27-
if (!visited [v]) {
45+
if (disc[v] == -1) {
46+
trace(v);
2847
logger._print (u + '\'s neighbor ' + v + ' has not been visited yet');
29-
logger._print ('Setting parent of ' + v + ' to ' + u + ' (parent [v] = u)');
30-
31-
parent [v] = u;
3248

33-
logger._print ('recursively calling util (' + v + ', [' + visited + '], [' + disc + '], [' + low + '], [' + parent + '])');
34-
util (v, visited, disc, low, parent);
49+
logger._print ('recursively calling util (' + v + ', [' + disc + '], [' + low + '],' + u + ')');
50+
util (v, disc, low, u);
3551

3652
logger._print ('--------------------------------------------------------------------');
37-
logger._print ('Returned from util (' + v + ', [' + visited + '], [' + disc + '], [' + low + '], [' + parent + '])');
38-
logger._print ('notice that the values of visited, disc, low and parent might have changed');
3953

4054
logger._print ('Setting low [' + u + '] to ' + Math.min (low [u], low [v]));
4155
low [u] = Math.min (low [u], low [v]);
4256

43-
if (low [v] > disc [u]) {
44-
logger._print ('low [v] > disc [u], v=' + v + ', u=' + u + ', (' + low [v] + ' > ' + low [u] + ')');
45-
logger._print (u + ' -> ' + v + ' is a bridge. Adding u->v to the set of bridges found');
57+
if (low [v] == disc [v]) {
58+
logger._print ('low [' + v + '] == disc [' + v + '], low[' + v + ']=' + low[v] + ', disc[' + v + ']=' + disc[v]);
59+
logger._print (u + ' -> ' + v + ' is a bridge. Adding ' + u + '->' + v + 'to the set of bridges found');
4660
bridges.push ([u, v]);
4761
}
4862
}
49-
else if (v !== parent [u]) {
50-
logger._print (v + ' does not equal parent [' + u + '] (' + parent [u] + ')');
51-
logger._print ('Setting low [' + u + '] to ' + Math.min (low [u], disc [v]));
52-
low [u] = Math.min (low [u], disc [v]);
53-
}
63+
5464
});
5565
};
5666

5767
(function findBridges (graph) {
58-
var visited = filledArray (graph.length, 0);
59-
var parent = filledArray (graph.length, -1);
60-
var disc = filledArray (graph.length, 0);
61-
var low = filledArray (graph.length, 0);
68+
69+
var disc = filledArray (graph.length, -1);
70+
var low = filledArray (graph.length, -1);
6271

6372
function filledArray (length, value) {
6473
return Array.apply (null, Array (length)).map (Number.prototype.valueOf, value);
@@ -75,20 +84,18 @@ var util = function (u, visited, disc, low, parent) {
7584
});
7685
}) ();
7786

78-
for (var i = 0; i < visited.length; i++) { visited [i] = false; }
79-
80-
logger._print ('Initializing <b>visited</b>: ' + visited + ', <b>parent</b>: ' + parent + ', <b>disc</b>: ' + disc + ' <b>low</b>: ' + low);
87+
logger._print ('Initializing: <b>disc</b>: ' + disc + ' <b>low</b>: ' + low);
8188
logger._print ('');
8289
logger._print ('Beginning efficient Bridge Finding');
83-
logger._print ('NOTE: call to util () follows pattern: util (nodeToVisit, visited, disc, low, parent). See code for clarity');
90+
logger._print ('NOTE: call to util () follows pattern: util (nodeToVisit, disc, low, parent). See code for clarity');
8491
logger._print ('');
8592

8693
logger._print ('Starting the main for loop (for each node)');
8794
for (var v = 0; v < graph.length; v++) {
88-
if (!visited [v]) {
89-
logger._print (v + ' has not been visited yet. Calling util (' + v + ', [' + visited + '], [' + disc + '], [' + low + '], [' + parent + ']) from the for loop');
90-
util (v, visited, disc, low, parent);
91-
logger._print ('Returned in for loop after util (' + v + ', [' + visited + '], [' + disc + '], [' + low + '], [' + parent + '])');
95+
if (disc[v] == -1) {
96+
logger._print (v + ' has not been visited yet. Calling util (' + v + ', [' + disc + '], [' + low + '],' + v + ') from the for loop');
97+
util (v, disc, low, v);
98+
logger._print ('Returned in for loop after util (' + v + ', [' + disc + '], [' + low + '], [' + v + '])');
9299
}
93100
}
94101
}) (G);

0 commit comments

Comments
 (0)