From 4a4bb60218769553f0bc7a66962d5e14438a1777 Mon Sep 17 00:00:00 2001 From: "duaraghav8@gmail" Date: Sat, 28 May 2016 14:40:15 +0530 Subject: [PATCH] PageRank Algorithm: Version 1 --- algorithm/category.json | 3 +- .../graph_search/page_rank/basic/code.js | 106 ++++++++++++++++++ .../graph_search/page_rank/basic/data.js | 21 ++++ algorithm/graph_search/page_rank/desc.json | 17 +++ 4 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 algorithm/graph_search/page_rank/basic/code.js create mode 100644 algorithm/graph_search/page_rank/basic/data.js create mode 100644 algorithm/graph_search/page_rank/desc.json diff --git a/algorithm/category.json b/algorithm/category.json index 40bac64f..5827a2e4 100644 --- a/algorithm/category.json +++ b/algorithm/category.json @@ -8,7 +8,8 @@ "bellman_ford": "Bellman-Ford", "floyd_warshall": "Floyd-Warshall", "topological_sort": "Topological-Sort", - "bridges": "Find-Bridges" + "bridges": "Find-Bridges", + "page_rank": "PageRank Algorithm" } }, "cryptography": { diff --git a/algorithm/graph_search/page_rank/basic/code.js b/algorithm/graph_search/page_rank/basic/code.js new file mode 100644 index 00000000..608351b7 --- /dev/null +++ b/algorithm/graph_search/page_rank/basic/code.js @@ -0,0 +1,106 @@ +/* + PageRank Algorithm Version 1 + Equation: + PR (X) = (1 - D) + D (Summation i->X (PR (I) / Out (i))) + NOTE: Algorithm uses the recommended damping factor (D). Number of iterations is small because only a small Web of 5 Pages is simulated +*/ + +function arraySum (array) { + return array.reduce (function (sum, curr) { + return sum + (curr ? 1 : 0); //if curr is 0 (no edge) or undefined (loop not allowed), sum remains unchanged + }, 0); +} + +function showOutgoingEdges (i) { + G [i].forEach (function (edgeExists, j) { + edgeExists && graphTracer._visit (j, i)._wait () && graphTracer._leave (j, i)._wait (); + }); +} + +//PRECOMPUTATIONS + +logger._print ('Calculate Outgoing Edge Count for each Node'); +(function calculateOEC () { + var count = 0; + G.forEach (function (relations, i) { + outgoingEdgeCounts [i] = arraySum (relations); + showOutgoingEdges (i); + + oecTracer._notify (i, outgoingEdgeCounts [i])._wait (); + oecTracer._denotify (i)._wait (); + }); +}) (); + +logger._print ('determine incoming nodes for each node'); +(function determineIN () { + for (var i = 0; i < G.length; i++) { + for (var j = 0; j < G.length; j++) { + if (G [i] [j]) { + //there's an edge FROM i TO j + graphTracer._visit (j, i)._wait (); + + var nextPos = incomingNodes [j].indexOf (-1); + incomingNodes [j] [nextPos] = i; + inTracer._notify (j, nextPos, i)._wait (); + inTracer._denotify (j, nextPos)._wait (); + + graphTracer._leave (j, i)._wait (); + } + } + } + + //logger._print ('All -1s will be removed from incoming node records, they are irrelevant'); + incomingNodes.forEach (function (arr) { + arr.splice (arr.indexOf (-1)); + }); +}) (); + +function updateRank (nodeIndex) { + var inNodeSummation = 0, result; + + logger._print ('Updating rank of ' + nodeIndex); + logger._print ('The incoming Nodes of ' + nodeIndex + ' are being highlighted'); + + incomingNodes [nodeIndex].forEach (function (incoming, i) { + inTracer._select (nodeIndex, i)._wait (); + logger._print ('Outgoing edge count of ' + incoming + ' is ' + outgoingEdgeCounts [incoming]); + oecTracer._select (incoming)._wait (); + + inNodeSummation += (ranks [incoming] / outgoingEdgeCounts [incoming]); + + oecTracer._deselect (incoming)._wait (); + inTracer._deselect (nodeIndex, i)._wait (); + }); + logger._print ('In-Node summation of ' + nodeIndex + ' = ' + inNodeSummation); + + result = (1 - damping) + (damping * inNodeSummation); + logger._print ('Therefore, using Equation, new rank of ' + nodeIndex + ' = ' + result); + return result; +} + +var damping = 0.85, + iterations = 7; +var initialRank = 1.0; + +logger._print ('Initialized all Page ranks to ' + initialRank); +ranks = filledArray (G.length, initialRank); + +rankTracer._setData (ranks); +logger._print ('Begin execution of PageRank Version #1'); +logger._print ('Equation used: PR (X) = (1 - D) + D (In-Node-Summation i->X (PR (I) / Out (i)))'); +logger._print ('D = Damping Factor, PR (X) = Page rank of Node X, i = the ith In-Node of X, Out (i) = outgoing Edge Count of i'); +logger._print (''); + +while (iterations--) { + for (var node = 0; node < ranks.length; node++) { + ranks [node] = updateRank (node); + rankTracer._notify (node, ranks [node])._wait (); + rankTracer._notify (node)._wait (); + } +} + +logger._print ('Page Ranks have been converged to.') +ranks.forEach (function (rank, node) { + logger._print ('Rank of Node #' + node + ' = ' + rank); +}); +logger._print ('Done'); \ No newline at end of file diff --git a/algorithm/graph_search/page_rank/basic/data.js b/algorithm/graph_search/page_rank/basic/data.js new file mode 100644 index 00000000..97623181 --- /dev/null +++ b/algorithm/graph_search/page_rank/basic/data.js @@ -0,0 +1,21 @@ +function filledArray (length, value) { + return Array.apply (null, Array (length)).map (Number.prototype.valueOf, value); +} + +var G = new DirectedGraph.random (5, 0.4), + ranks, + outgoingEdgeCounts = filledArray (G.length, 0), + incomingNodes; + +var graphTracer = new DirectedGraphTracer ('Web Page inter-connections'), + rankTracer = new Array1DTracer ('Web Page Ranks'), + oecTracer = new Array1DTracer ('Outgoing Edge Counts'), + inTracer = new Array2DTracer ('Incoming Nodes'); + +var logger = new LogTracer (); + +graphTracer._setData (G); +oecTracer._setData (outgoingEdgeCounts); + +for (incomingNodes = []; incomingNodes.length < G.length; incomingNodes.push (filledArray (G.length, -1))); +inTracer._setData (incomingNodes); \ No newline at end of file diff --git a/algorithm/graph_search/page_rank/desc.json b/algorithm/graph_search/page_rank/desc.json new file mode 100644 index 00000000..e9833312 --- /dev/null +++ b/algorithm/graph_search/page_rank/desc.json @@ -0,0 +1,17 @@ +{ + "PageRank-Algorithm": "PageRank is an algorithm used by Google Search to rank websites in their search engine results.", + "Applications": [ + "Web Page Indexing for refining search results" + ], + "Complexity": { + "time": "worst O(|V|+|E|)", + "space": "worst O(|V|)" + }, + "References": [ + "Princeton university", + "E-Factory" + ], + "files": { + "basic": "Version #1 of PageRank Algorithm (does not take into account the total number of nodes in the graph, i.e., number of pages on web)." + } +}