1+ // import visualization libraries {
12const { Tracer, Array1DTracer, Array2DTracer, GraphTracer, LogTracer, Randomize, Layout, VerticalLayout } = require ( 'algorithm-visualizer' ) ;
3+ // }
24
35function filledArray ( length , value ) {
46 return Array ( ...Array ( length ) ) . map ( Number . prototype . valueOf , value ) ;
57}
68
9+ // define tracer variables {
710const G = Randomize . Graph ( { N : 5 , ratio : .4 } ) ;
811let ranks ;
912const outgoingEdgeCounts = filledArray ( G . length , 0 ) ;
@@ -22,6 +25,7 @@ oecTracer.set(outgoingEdgeCounts);
2225for ( incomingNodes = [ ] ; incomingNodes . length < G . length ; incomingNodes . push ( filledArray ( G . length , - 1 ) ) ) ;
2326inTracer . set ( incomingNodes ) ;
2427Tracer . delay ( ) ;
28+ // }
2529
2630/*
2731 PageRank Algorithm Version 2
@@ -41,47 +45,59 @@ function arraySum(array) {
4145function showOutgoingEdges ( i ) {
4246 G [ i ] . forEach ( ( edgeExists , j ) => {
4347 if ( edgeExists ) {
48+ // visualize {
4449 graphTracer . visit ( j , i ) ;
4550 Tracer . delay ( ) ;
4651 graphTracer . leave ( j , i ) ;
4752 Tracer . delay ( ) ;
53+ // }
4854 }
4955 } ) ;
5056}
5157
5258// PRECOMPUTATIONS
5359
60+ // logger {
5461logger . println ( 'Calculate Outgoing Edge Count for each Node' ) ;
62+ // }
5563( function calculateOEC ( ) {
5664 G . forEach ( ( relations , i ) => {
5765 outgoingEdgeCounts [ i ] = arraySum ( relations ) ;
5866 showOutgoingEdges ( i ) ;
5967
68+ // visualize {
6069 oecTracer . patch ( i , outgoingEdgeCounts [ i ] ) ;
6170 Tracer . delay ( ) ;
6271 oecTracer . depatch ( i ) ;
6372 Tracer . delay ( ) ;
73+ // }
6474 } ) ;
6575} ( ) ) ;
6676
77+ // logger {
6778logger . println ( 'determine incoming nodes for each node' ) ;
79+ // }
6880( function determineIN ( ) {
6981 for ( let i = 0 ; i < G . length ; i ++ ) {
7082 for ( let j = 0 ; j < G . length ; j ++ ) {
7183 if ( G [ i ] [ j ] ) {
7284 // there's an edge FROM i TO j
85+ // visualize {
7386 graphTracer . visit ( j , i ) ;
7487 Tracer . delay ( ) ;
88+ // }
7589
7690 const nextPos = incomingNodes [ j ] . indexOf ( - 1 ) ;
7791 incomingNodes [ j ] [ nextPos ] = i ;
92+ // visualize {
7893 inTracer . patch ( j , nextPos , i ) ;
7994 Tracer . delay ( ) ;
8095 inTracer . depatch ( j , nextPos ) ;
8196 Tracer . delay ( ) ;
8297
8398 graphTracer . leave ( j , i ) ;
8499 Tracer . delay ( ) ;
100+ // }
85101 }
86102 }
87103 }
@@ -96,55 +112,75 @@ function updateRank(nodeIndex) {
96112 let inNodeSummation = 0 ;
97113 let result ;
98114
115+ // logger {
99116 logger . println ( `Updating rank of ${ nodeIndex } ` ) ;
100117 logger . println ( `The incoming Nodes of ${ nodeIndex } are being highlighted` ) ;
118+ // }
101119
102120 incomingNodes [ nodeIndex ] . forEach ( ( incoming , i ) => {
121+ // visualize {
103122 inTracer . select ( nodeIndex , i ) ;
104123 Tracer . delay ( ) ;
105124 logger . println ( `Outgoing edge count of ${ incoming } is ${ outgoingEdgeCounts [ incoming ] } ` ) ;
106125 oecTracer . select ( incoming ) ;
107126 Tracer . delay ( ) ;
127+ // }
108128
109129 inNodeSummation += ( ranks [ incoming ] / outgoingEdgeCounts [ incoming ] ) ;
110130
131+ // visualize {
111132 oecTracer . deselect ( incoming ) ;
112133 Tracer . delay ( ) ;
113134 inTracer . deselect ( nodeIndex , i ) ;
114135 Tracer . delay ( ) ;
136+ // }
115137 } ) ;
138+ // logger {
116139 logger . println ( `In-Node summation of ${ nodeIndex } = ${ inNodeSummation } ` ) ;
117-
140+ // }
141+
118142 result = ( ( 1 - damping ) / G . length ) + ( damping * inNodeSummation ) ; // notice the subtle difference between equations of Basic PR & PR version 2 (divide by N)
143+ // logger {
119144 logger . println ( `Therefore, using Equation, new rank of ${ nodeIndex } = ${ result } ` ) ;
145+ // }
120146 return result ;
121147}
122148
123149let damping = 0.85 ;
124150let iterations = 7 ;
125151const initialRank = 1.0 ;
126152
153+ // logger {
127154logger . println ( `Initialized all Page ranks to ${ initialRank } ` ) ;
155+ // }
128156ranks = filledArray ( G . length , initialRank ) ;
129157
158+ // visualize {
130159rankTracer . set ( ranks ) ;
160+ // }
161+ // logger {
131162logger . println ( 'Begin execution of PageRank Version #1' ) ;
132163logger . println ( 'Equation used: PR (X) = (1 - D) + D (In-Node-Summation i->X (PR (I) / Out (i)))' ) ;
133164logger . println ( 'D = Damping Factor, PR (X) = Page rank of Node X, i = the ith In-Node of X, Out (i) = outgoing Edge Count of i' ) ;
134165logger . println ( '' ) ;
166+ // }
135167
136168while ( iterations -- ) {
137169 for ( let node = 0 ; node < ranks . length ; node ++ ) {
138170 ranks [ node ] = updateRank ( node ) ;
171+ // visualize {
139172 rankTracer . patch ( node , ranks [ node ] ) ;
140173 Tracer . delay ( ) ;
141174 rankTracer . patch ( node ) ;
142175 Tracer . delay ( ) ;
176+ // }
143177 }
144178}
145179
180+ // logger {
146181logger . println ( 'Page Ranks have been converged to.' ) ;
147182ranks . forEach ( ( rank , node ) => {
148183 logger . println ( `Rank of Node #${ node } = ${ rank } ` ) ;
149184} ) ;
150185logger . println ( 'Done' ) ;
186+ // }
0 commit comments