Skip to content

Commit 9b86c3c

Browse files
committed
2 parents 5184971 + f4351a4 commit 9b86c3c

File tree

11 files changed

+212
-5
lines changed

11 files changed

+212
-5
lines changed

LICENSE

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ Copyright (c) 2016 Jason Park
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal
7-
in the Software without restriction, including without limitation the rights
7+
in the Software without restriction, including without limiting the rights
88
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
99
copies of the Software, and to permit persons to whom the Software is
10-
furnished to do so, subject to the following conditions:
10+
furnished to do so, subjected to the following conditions:
1111

1212
The above copyright notice and this permission notice shall be included in
1313
all copies or substantial portions of the Software.

algorithm/category.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"dijkstra": "Dijkstra",
88
"bellman_ford": "Bellman-Ford",
99
"floyd_warshall": "Floyd-Warshall",
10-
"topological_sort": "Topological-Sort"
10+
"topological_sort": "Topological-Sort",
11+
"bridges": "Find-Bridges"
1112
}
1213
},
1314
"mst": {

algorithm/etc/dp/desc.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"sliding_window": "Finding the largest sum of three contiguous number",
1313
"max_sum_path": "Finding the maximum sum in a path from (0, 0) to (N-1, M-1) when can only move to right or down",
1414
"longest_increasing_subsequence": "Find the length of the longest subsequence of a given sequence such that all elements of the subsequence are sorted in increasing order",
15-
"max_subarray": "Find the sum of the maximum Subarray in the given Array"
15+
"max_subarray": "Find the sum of the maximum Subarray in the given Array",
16+
"knapsack_problem": "Given a set of items, each with a weight and a value, determine the number of each item to include in a collection so that the total weight is less than or equal to a given limit and the total value is as large as possible."
1617
}
1718
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
2+
for ( var i = 0; i <= N; i++ ) {
3+
for( var j = 0; j <= W; j++ ) {
4+
if( i === 0 || j === 0 ) {
5+
/*
6+
If we have no items or maximum weight we can take in collection is 0
7+
then the total weight in our collection is 0
8+
*/
9+
DP[i][0] = 0;
10+
tracer._notify( i, j, DP[i][j])._wait();
11+
tracer._denotify( i, j);
12+
} else if ( wt[i-1] <= j ) { // take the current item in our collection
13+
14+
dataViewer1._select(i-1)._wait();
15+
dataViewer2._select(i-1)._wait();
16+
tracer._select( i-1, j)._wait();
17+
18+
var A = val[i - 1] + DP[i - 1][j - wt[i - 1]];
19+
var B = DP[i - 1][j];
20+
/*
21+
find the maximum of these two values
22+
and take which gives us a greater weight
23+
*/
24+
if (A > B) {
25+
DP[i][j] = A;
26+
tracer._notify( i, j, DP[i][j])._wait();
27+
} else {
28+
DP[i][j] = B;
29+
tracer._notify( i, j, DP[i][j])._wait();
30+
}
31+
32+
tracer._deselect( i-1, j);
33+
tracer._denotify( i, j);
34+
dataViewer2._deselect(i-1);
35+
dataViewer1._deselect(i-1);
36+
37+
} else { // leave the current item from our collection
38+
39+
DP[i][j] = DP[i - 1][j];
40+
tracer._notify( i, j, DP[i][j])._wait();
41+
tracer._denotify( i, j);
42+
}
43+
}
44+
}
45+
46+
logger._print(' Best value we can achieve is ' + DP[N][W]);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
var val = [1,4,5,7]; // The value of all available items
2+
var wt = [1,3,4,5]; // The weights of available items
3+
var W = 7; // The maximum weight we can carry in our collection
4+
var N = val.length;
5+
var DP = new Array(N+1);
6+
7+
for (var i = 0; i < N + 1; i++) {
8+
DP[i] = new Array(W+1);
9+
for (var j = 0; j < W + 1; j++) {
10+
DP[i][j] = 0;
11+
}
12+
}
13+
14+
var tracer = new Array2DTracer()._setData(DP);
15+
var dataViewer1 = new Array1DTracer()._setData(val);
16+
var dataViewer2 = new Array1DTracer()._setData(wt);
17+
var logger = new LogTracer();
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"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:<br />1.Delete an edge E<br />2.Perform DFS Exploration to check is Graph is connected<br />3.Restore Edge E. E is a bridge only if DFS explore determines that the graph is disconnected without E",
3+
"Applications": [
4+
"Find vulnerabilities in Graphs and Electrical Circuits"
5+
],
6+
"Complexity": {
7+
"time": "worst O(|E|.(|V|+|E|))",
8+
"space": "worst O(|V|.|E|)"
9+
},
10+
"References": [
11+
"<a href='https://en.wikipedia.org/wiki/Bridge_(graph_theory)'>Wikipedia</a>"
12+
],
13+
"files": {
14+
"naive": "Find all the bridges in an Undirected Graph"
15+
}
16+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
//Depth First Search Exploration Algorithm to test connectedness of the Graph (see Graph Algorithms/DFS/exploration), without the tracer & logger commands
2+
function DFSExplore (graph, source) {
3+
var stack = [ [source, null] ], visited = {};
4+
var node, prev, i, temp;
5+
6+
while (stack.length > 0) {
7+
temp = stack.pop ();
8+
node = temp [0];
9+
prev = temp [1];
10+
11+
if (!visited [node]) {
12+
visited [node] = true;
13+
//logger._print (node);
14+
15+
/*
16+
if (prev !== undefined && graph [node] [prev]) { tracer._visit (node, prev)._wait (); console.log ('tracer ' + prev + ', ' + node); }
17+
else { tracer._visit (node)._wait (); console.log ('tracer ' + node); }
18+
*/
19+
20+
for (i = 0; i < graph.length; i++) {
21+
if (graph [node] [i]) {
22+
stack.push ([i, node]);
23+
}
24+
}
25+
}
26+
}
27+
28+
return visited;
29+
}
30+
31+
function findBridges (graph) {
32+
var tempGraph, bridges = [], visited;
33+
34+
for (var i = 0; i < graph.length; i++) {
35+
for (var j = 0; j < graph.length; j++) {
36+
if (graph [i] [j]) { //check if an edge exists
37+
logger._print ('Deleting edge ' + i + '->' + j + ' and calling DFSExplore ()');
38+
tracer._visit (j, i)._wait ();
39+
tracer._leave (j, i)._wait ();
40+
41+
tempGraph = JSON.parse (JSON.stringify (graph));
42+
tempGraph [i] [j] = 0;
43+
tempGraph [j] [i] = 0;
44+
visited = DFSExplore (tempGraph, 0);
45+
46+
if (Object.keys (visited).length === graph.length) {
47+
logger._print ('Graph is CONNECTED. Edge is NOT a bridge');
48+
}
49+
else {
50+
logger._print ('Graph is DISCONNECTED. Edge IS a bridge');
51+
bridges.push ([i,j]);
52+
}
53+
}
54+
}
55+
}
56+
57+
return bridges;
58+
}
59+
60+
var bridges = findBridges (G);
61+
62+
logger._print ('The bridges are: ');
63+
for (var i in bridges) {
64+
logger._print (bridges [i] [0] + ' to ' + bridges [i] [1]);
65+
}
66+
logger._print ('NOTE: A bridge is both ways, i.e., from A to B and from B to A, because this is an Undirected Graph');
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
var tracer = new UndirectedGraphTracer ();
2+
var logger = new LogTracer ();
3+
var G = [
4+
[0,1,0,0,0,0],
5+
[1,0,0,1,1,0],
6+
[0,0,0,1,0,0],
7+
[0,1,1,0,1,1],
8+
[0,1,0,1,0,0],
9+
[0,0,0,1,0,0]
10+
];
11+
12+
tracer._setData (G);

algorithm/graph_search/dfs/desc.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"tree": "Searching a tree",
2525
"all_paths": "Going through all possible paths without making any circuit",
2626
"weighted_graph": "DFS of Weighted Graph",
27-
"shortest_path": "Finding the shortest path"
27+
"shortest_path": "Finding the shortest path",
28+
"exploration": "Explore an undirected graph to see if it is connected"
2829
}
2930
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
function DFSExplore (graph, source) {
2+
var stack = [ [source, null] ], visited = {};
3+
var node, prev, i, temp;
4+
5+
while (stack.length > 0) {
6+
temp = stack.pop ();
7+
node = temp [0];
8+
prev = temp [1];
9+
10+
if (!visited [node]) {
11+
visited [node] = true;
12+
logger._print (node);
13+
14+
if (prev !== undefined && graph [node] [prev]) { tracer._visit (node, prev)._wait (); console.log ('tracer ' + prev + ', ' + node); }
15+
else { tracer._visit (node)._wait (); console.log ('tracer ' + node); }
16+
17+
for (i = 0; i < graph.length; i++) {
18+
if (graph [node] [i]) {
19+
stack.push ([i, node]);
20+
}
21+
}
22+
}
23+
}
24+
25+
return visited;
26+
}
27+
28+
29+
var visited = DFSExplore (G, 0);
30+
if (G.length === Object.keys (visited).length) {
31+
logger._print ('The Graph is CONNECTED');
32+
}
33+
else {
34+
logger._print ('The Graph is NOT CONNECTED');
35+
}

0 commit comments

Comments
 (0)