@@ -31,22 +31,37 @@ def __repr__(self):
3131 return f"<node={ self .name } inbound={ self .inbound } outbound={ self .outbound } >"
3232
3333
34- def page_rank (nodes , limit = 3 , d = 0.85 ):
35- ranks = {}
36- for node in nodes :
37- ranks [node .name ] = 1
34+ def page_rank (nodes , limit = None , d = 0.85 , tol = 1e-8 , max_iter = 100 ):
35+ if not nodes :
36+ return {}
37+
38+ if limit is not None :
39+ max_iter = limit
40+
41+ n = len (nodes )
42+ ranks = {node .name : 1.0 / n for node in nodes }
43+ outbounds = {node .name : len (node .outbound ) for node in nodes }
44+
45+ for _ in range (max_iter ):
46+ new_ranks = {}
47+ dangling_sum = sum (
48+ ranks [node .name ] for node in nodes if outbounds [node .name ] == 0
49+ )
50+
51+ for node in nodes :
52+ inbound_rank = sum (
53+ ranks [inbound_node ] / outbounds [inbound_node ]
54+ for inbound_node in node .inbound
55+ )
56+ new_ranks [node .name ] = (1 - d ) / n + d * (
57+ inbound_rank + dangling_sum / n
58+ )
3859
39- outbounds = {}
40- for node in nodes :
41- outbounds [ node . name ] = len ( node . outbound )
60+ if sum ( abs ( new_ranks [ name ] - ranks [ name ]) for name in ranks ) < tol :
61+ return new_ranks
62+ ranks = new_ranks
4263
43- for i in range (limit ):
44- print (f"======= Iteration { i + 1 } =======" )
45- for _ , node in enumerate (nodes ):
46- ranks [node .name ] = (1 - d ) + d * sum (
47- ranks [ib ] / outbounds [ib ] for ib in node .inbound
48- )
49- print (ranks )
64+ return ranks
5065
5166
5267def main ():
@@ -64,7 +79,8 @@ def main():
6479 for node in nodes :
6580 print (node )
6681
67- page_rank (nodes )
82+ print ("======= Page Rank =======" )
83+ print (page_rank (nodes ))
6884
6985
7086if __name__ == "__main__" :
0 commit comments