1+ #-*-coding:utf-8-*- 
2+ ''' 
3+ Created on 2016年6月16日 
4+ 
5+ @author: Gamer Think 
6+ ''' 
7+ 
8+ ''' 
9+ G:二分图   alpha:随机游走的概率   root:游走的初始节点     max_step;最大走动步数 
10+ ''' 
11+ def  PersonalRank (G , alpha , root , max_step ):
12+     rank  =  dict ()  
13+     rank  =  {x :0  for  x  in  G .keys ()}
14+     rank [root ] =  1   
15+     #开始迭代   
16+     for  k  in  range (max_step ):  
17+         tmp  =  {x :0  for  x  in  G .keys ()}  
18+         #取节点i和它的出边尾节点集合ri   
19+         for  i , ri  in  G .items ():  #i是顶点。ri是与其相连的顶点极其边的权重 
20+             #取节点i的出边的尾节点j以及边E(i,j)的权重wij, 边的权重都为1,在这不起实际作用   
21+             for  j , wij  in  ri .items ():   #j是i的连接顶点,wij是权重 
22+                 #i是j的其中一条入边的首节点,因此需要遍历图找到j的入边的首节点,   
23+                 #这个遍历过程就是此处的2层for循环,一次遍历就是一次游走   
24+                 tmp [j ] +=  alpha  *  rank [i ] /  (1.0  *  len (ri ))  
25+         #我们每次游走都是从root节点出发,因此root节点的权重需要加上(1 - alpha)   
26+         #在《推荐系统实践》上,作者把这一句放在for j, wij in ri.items()这个循环下,我认为是有问题。   
27+         tmp [root ] +=  (1  -  alpha )  
28+         rank  =  tmp   
29+   
30+         #输出每次迭代后各个节点的权重   
31+         print  'iter:  '  +  str (k ) +  "\t " ,  
32+         for  key , value  in  rank .items ():  
33+             print  "%s:%.3f, \t " % (key , value ),  
34+         print   
35+   
36+     return  rank   
37+   
38+ 
39+ ''' 
40+ 主函数,G表示二分图,‘A’表示节点,后边对应的字典的key是连接的顶点,value表示边的权重 
41+ ''' 
42+ if  __name__  ==  '__main__' :
43+     G  =  {'A'  : {'a'  : 1 , 'c'  : 1 },  
44+          'B'  : {'a'  : 1 , 'b'  : 1 , 'c' :1 , 'd' :1 },  
45+          'C'  : {'c'  : 1 , 'd'  : 1 },  
46+          'a'  : {'A'  : 1 , 'B'  : 1 },  
47+          'b'  : {'B'  : 1 },  
48+          'c'  : {'A'  : 1 , 'B'  : 1 , 'C' :1 },  
49+          'd'  : {'B'  : 1 , 'C'  : 1 }}  
50+   
51+     PersonalRank (G , 0.85 , 'A' , 100 )  
0 commit comments