1+ #coding=utf-8
2+ #Author:Harold
3+ #Date:2021-1-27
4+ 5+
6+ '''
7+ 有向图:directed_graph.png
8+ 结点数量:7
9+ -----------------------------
10+ 运行结果:
11+ 迭代算法:
12+ 迭代次数:24
13+ PageRank: [[0.17030305]
14+ [0.10568394]
15+ [0.11441021]
16+ [0.10629792]
17+ [0.10568394]
18+ [0.15059975]
19+ [0.24702119]]
20+ 运行时长:0.0010s
21+ 幂法:
22+ 迭代次数:25
23+ PageRank: [[0.18860772]
24+ [0.09038084]
25+ [0.0875305 ]
26+ [0.07523049]
27+ [0.09038084]
28+ [0.15604764]
29+ [0.31182196]]
30+ 运行时长:0.0020s
31+ '''
32+
33+ import numpy as np
34+ import time
35+
36+
37+ #PageRank的迭代算法
38+ def iter_method (n , d , M , R0 , eps ):
39+ t = 0 #用来累计迭代次数
40+ R = R0 #对R向量进行初始化
41+ judge = False #用来判断是否继续迭代
42+ while not judge :
43+ next_R = d * np .matmul (M , R ) + (1 - d ) / n * np .ones ((7 , 1 )) #计算新的R向量
44+ diff = np .linalg .norm (R - next_R ) #计算新的R向量与之前的R向量之间的距离,这里采用的是欧氏距离
45+ if diff < eps : #若两向量之间的距离足够小
46+ judge = True #则停止迭代
47+ R = next_R #更新R向量
48+ t += 1 #迭代次数加一
49+ R = R / np .sum (R ) #对R向量进行规范化,保证其总和为1,表示各节点的概率分布
50+ return t , R
51+
52+
53+ def power_method (n , d , M , R0 , eps ):
54+ t = 0 #用来累计迭代次数
55+ x = R0 #对x向量进行初始化
56+ judge = False #用来判断是否继续迭代
57+ A = d * M + (1 - d ) / n * np .eye (n ) #计算A矩阵,其中np.eye(n)用来创建n阶单位阵E
58+ while not judge :
59+ next_y = np .matmul (A , x ) #计算新的y向量
60+ next_x = next_y / np .linalg .norm (next_y ) #对新的y向量规范化得到新的x向量
61+ diff = np .linalg .norm (x - next_x ) #计算新的x向量与之前的x向量之间的距离,这里采用的是欧氏距离
62+ if diff < eps : #若两向量之间的距离足够小
63+ judge = True #则停止迭代
64+ R = x #得到R向量
65+ x = next_x #更新x向量
66+ t += 1 #迭代次数加一
67+ R = R / np .sum (R ) #对R向量进行规范化,保证其总和为1,表示各节点的概率分布
68+ return t , R
69+
70+
71+ if __name__ == "__main__" :
72+ n = 7 #有向图中一共有7个节点
73+ d = 0.85 #阻尼因子根据经验值确定,这里我们随意给一个值
74+ M = np .array ([[0 , 1 / 4 , 1 / 3 , 0 , 0 , 1 / 2 , 0 ],
75+ [1 / 4 , 0 , 0 , 1 / 5 , 0 , 0 , 0 ],
76+ [0 , 1 / 4 , 0 , 1 / 5 , 1 / 4 , 0 , 0 ],
77+ [0 , 0 , 1 / 3 , 0 , 1 / 4 , 0 , 0 ],
78+ [1 / 4 , 0 , 0 , 1 / 5 , 0 , 0 , 0 ],
79+ [1 / 4 , 1 / 4 , 0 , 1 / 5 , 1 / 4 , 0 , 0 ],
80+ [1 / 4 , 1 / 4 , 1 / 3 , 1 / 5 , 1 / 4 , 1 / 2 , 0 ]]) #根据有向图中各节点的连接情况写出转移矩阵
81+ R0 = np .full ((7 , 1 ), 1 / 7 ) #设置初始向量R0,R0是一个7*1的列向量,因为有7个节点,我们把R0的每一个值都设为1/7
82+ eps = 0.000001 #设置计算精度
83+
84+ start = time .time () #保存开始时间
85+ t , R = iter_method (n , d , M , R0 , eps )
86+ end = time .time () #保存结束时间
87+ print ('-------PageRank的迭代算法-------' )
88+ print ('迭代次数:' , t )
89+ print ('PageRank: \n ' , R )
90+ print ('Time:' , end - start )
91+
92+ start = time .time () #保存开始时间
93+ t , R = power_method (n , d , M , R0 , eps )
94+ end = time .time () #保存结束时间
95+ print ('-------PageRank的幂法-------' )
96+ print ('迭代次数:' , t )
97+ print ('PageRank: \n ' , R )
98+ print ('Time:' , end - start )
0 commit comments