diff --git a/algorithm/graph_search/bridges/desc.json b/algorithm/graph_search/bridges/desc.json index 63fa7f8e..42490f1a 100644 --- a/algorithm/graph_search/bridges/desc.json +++ b/algorithm/graph_search/bridges/desc.json @@ -1,5 +1,5 @@ { - "Bridges": "An edge in an undirected connected graph is a bridge iff removing it disconnects the graph. A naive solution to finding bridges in a graph is to:
1.Delete an edge E
2.Perform DFS Exploration to check if the Graph is still connected
3.Restore Edge E. E is a bridge only if DFS exploration determines that the graph is disconnected without E. An efficient solution also exists, which uses the idea that edge U-V (U is parent) is a bridge if no subtree rooted at V has a back edge to U or one of its ancestors.", + "Bridges": "An edge in an undirected connected graph is a bridge iff removing it disconnects the graph. A naive solution to finding bridges in a graph is to:
1.Delete an edge E
2.Perform DFS Exploration to check if the Graph is still connected
3.Restore Edge E. E is a bridge only if DFS exploration determines that the graph is disconnected without E. An efficient solution also exists, which uses the idea that edge U-V (U is parent) is a bridge if no subtree rooted at V has a back edge to U or one of its ancestors.

A more efficient solution, which can find bridges in linear time, is to perform a DFS (depth-first-search) on the graph. At each step:
1. Number the vertex with a counter. The first vertex visited should be labelled 0, the second vertex labelled 1, etc.
2. Each vertex should also keep track of the lowest numbered vertex that can be reached with the DFS. This can be done recursively by looking at the smallest \"low\" of its children
3. If the lowest vertex that can be reached with the DFS is greater than its own label, that means the edge with its parent is a bridge. This is because the vertex cannot reach its parent with the DFS, implying that the edge is not part of a cycle. ", "Applications": [ "Finding vulnerabilities in Graphs and Electrical Circuits" ], diff --git a/algorithm/graph_search/bridges/efficient/code.js b/algorithm/graph_search/bridges/efficient/code.js index c2c20448..58860b1b 100644 --- a/algorithm/graph_search/bridges/efficient/code.js +++ b/algorithm/graph_search/bridges/efficient/code.js @@ -4,61 +4,76 @@ var timer = 0, bridges = [], adj = []; //adj keeps track of the neighbors of each node -var util = function (u, visited, disc, low, parent) { +var util = function (u, disc, low, parent) { logger._print (''); logger._print ('Visiting node ' + u); graphTracer._visit (u)._wait (); graphTracer._leave (u)._wait (); - visited [u] = true; - disc [u] = low [u] = ++timer; + //visited [u] = true; + disc [u] = low [u] = timer++; logger._print ('Nodes adjacent to ' + u + ' are: [ ' + adj [u] + ' ]'); - adj [u].forEach (function (v) { + /*adj [u].forEach (function (v) { graphTracer._visit (v, u)._wait (); graphTracer._leave (v, u)._wait (); - }); + });*/ + var trace = function(v) { + graphTracer._visit (v, u)._wait (); + graphTracer._leave (v, u)._wait (); + } adj [u].forEach (function (v) { - if (visited [v]) { - logger._print (u + '\'s neighbor ' + v + ' has already been visited. Not visiting it.'); + if (disc [v] > -1 && v == parent) { + trace(v); + logger._print (u + '\'s neighbor ' + v + ' is u\'s parent. Not visiting it.'); + + } + else if (disc[v] > -1 && v != parent) { + trace(v); + logger._print(u + '\'s neighbor ' + v + ' is not u\'s parent. Comparing low[u] with disc[v]') + if(low[u] > disc[v]) { + logger._print('low[' + u + '] is greater than disc[' + v + ']. Setting low[' + u + '] to disc[' + v + ']') + low[u] = disc[v] + } } - if (!visited [v]) { + if (disc[v] == -1) { + trace(v); logger._print (u + '\'s neighbor ' + v + ' has not been visited yet'); - logger._print ('Setting parent of ' + v + ' to ' + u + ' (parent [v] = u)'); + //logger._print ('Setting parent of ' + v + ' to ' + u + ' (parent [v] = u)'); - parent [v] = u; + //parent [v] = u; - logger._print ('recursively calling util (' + v + ', [' + visited + '], [' + disc + '], [' + low + '], [' + parent + '])'); - util (v, visited, disc, low, parent); + logger._print ('recursively calling util (' + v + ', [' + disc + '], [' + low + '],' + u + ')'); + util (v, disc, low, u); logger._print ('--------------------------------------------------------------------'); - logger._print ('Returned from util (' + v + ', [' + visited + '], [' + disc + '], [' + low + '], [' + parent + '])'); - logger._print ('notice that the values of visited, disc, low and parent might have changed'); + //logger._print ('Returned from util (' + v + ', [' + visited + '], [' + disc + '], [' + low + '], [' + parent + '])'); + //logger._print ('notice that the values of visited, disc, low and parent might have changed'); logger._print ('Setting low [' + u + '] to ' + Math.min (low [u], low [v])); low [u] = Math.min (low [u], low [v]); - if (low [v] > disc [u]) { - logger._print ('low [v] > disc [u], v=' + v + ', u=' + u + ', (' + low [v] + ' > ' + low [u] + ')'); + if (low [v] == disc [v]) { + logger._print ('low [' + v + '] == disc [' + v + '], low[v]=' + low[v] + ', disc[v]=' + disc[v]); logger._print (u + ' -> ' + v + ' is a bridge. Adding u->v to the set of bridges found'); bridges.push ([u, v]); } } - else if (v !== parent [u]) { - logger._print (v + ' does not equal parent [' + u + '] (' + parent [u] + ')'); + /*else if (low[v] < disc[v]) { + logger._print ('low[' + v + '] is less than disc[' + v + '], so u--v is not a bridge'); logger._print ('Setting low [' + u + '] to ' + Math.min (low [u], disc [v])); - low [u] = Math.min (low [u], disc [v]); - } + low[u] = Math.min (low [u], disc [v]); + }*/ }); }; (function findBridges (graph) { - var visited = filledArray (graph.length, 0); - var parent = filledArray (graph.length, -1); - var disc = filledArray (graph.length, 0); - var low = filledArray (graph.length, 0); + //var visited = filledArray (graph.length, 0); + //var parent = filledArray (graph.length, -1); + var disc = filledArray (graph.length, -1); + var low = filledArray (graph.length, -1); function filledArray (length, value) { return Array.apply (null, Array (length)).map (Number.prototype.valueOf, value); @@ -75,20 +90,20 @@ var util = function (u, visited, disc, low, parent) { }); }) (); - for (var i = 0; i < visited.length; i++) { visited [i] = false; } + //for (var i = 0; i < visited.length; i++) { visited [i] = false; } - logger._print ('Initializing visited: ' + visited + ', parent: ' + parent + ', disc: ' + disc + ' low: ' + low); + logger._print ('Initializing: disc: ' + disc + ' low: ' + low); logger._print (''); logger._print ('Beginning efficient Bridge Finding'); - logger._print ('NOTE: call to util () follows pattern: util (nodeToVisit, visited, disc, low, parent). See code for clarity'); + logger._print ('NOTE: call to util () follows pattern: util (nodeToVisit, disc, low, parent). See code for clarity'); logger._print (''); logger._print ('Starting the main for loop (for each node)'); for (var v = 0; v < graph.length; v++) { - if (!visited [v]) { - logger._print (v + ' has not been visited yet. Calling util (' + v + ', [' + visited + '], [' + disc + '], [' + low + '], [' + parent + ']) from the for loop'); - util (v, visited, disc, low, parent); - logger._print ('Returned in for loop after util (' + v + ', [' + visited + '], [' + disc + '], [' + low + '], [' + parent + '])'); + if (disc[v] == -1) { + logger._print (v + ' has not been visited yet. Calling util (' + v + ', [' + disc + '], [' + low + '],' + v + ') from the for loop'); + util (v, disc, low, v); + logger._print ('Returned in for loop after util (' + v + ', [' + disc + '], [' + low + '], [' + v + '])'); } } }) (G); diff --git a/index.html b/index.html index a58a262e..20854cc1 100644 --- a/index.html +++ b/index.html @@ -121,8 +121,13 @@

+<<<<<<< HEAD + + +======= +>>>>>>> refs/remotes/parkjs814/gh-pages