-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpagerank.py
152 lines (136 loc) · 3.38 KB
/
pagerank.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import numpy as np
from numpy.linalg import inv
#this dictionary will represent our simple directed graph
graph = {'A': ['B', 'C'],
'B': ['C', 'D'],
'C': ['D'],
'D': ['C'],
'E': ['F'],
'F': ['C']}
#some other inputs you can try
'''
graph = {'1': ['2'],
'2': ['1','3','4'],
'3': ['2','1'],
'4': ['3','4']}
'''
'''graph = {'Kevin': ['Mark', 'Katie'],
'Katie': ['Kevin', 'Mark', 'Jieun'],
'Jay': ['Jieun', 'Alex'],
'Mark': ['Kevin', 'Katie'],
'Jieun': ['Katie', 'Mark', 'Jay'],
'Alex': ['Jay']}
'''
'''
Pretty print graph
'''
def pprint(graph):
print("\nGraph:")
for x in graph.keys():
print("%s: " %x, end ='')
for y in range(0, len(graph[x])):
if y == len(graph[x])-1:
print("%s" %(graph[x])[y])
else:
print("%s, " %(graph[x])[y], end = '')
print("")
pprint(graph)
#place the out_degree into an array
def out_degree(graph):
a = []
for x in graph.keys():
a.append(len(graph[x]))
return a
print("Outdegree: %s" %out_degree(graph))
#place the in_degree into an array
def in_degree(graph):
a = [] #place in degrees here
for x in graph.keys():
z = 0
for y in graph.keys():
for h in range(0, len(graph[y])):
if x in (graph[y])[h]:
z += 1
a.append(z)
return a
print("\nIndegree: %s" %in_degree(graph))
'''
Look_up references the keys as integer values from 0 to len(graph)
This is to ensure all non-integer key values are compatible with
numpy matrix
'''
def look_up():
lookUp = {}
i = 0
for x in graph.keys():
lookUp[x] = i
i+=1
return lookUp
#print(look_up())
'''
A_ij = { if there is an edge from j to i, 1
{ else 0
ex: B to A -> 1,2 = 1; A->A -> 1,1 = 1
Note: can use in-degree to check matrix
number of 1s for row of key corresponds to
number of 1s for matrix
'''
def convert_matrix():
matrixA = np.zeros((len(graph), len(graph)))
lookUpGraph = look_up()
for x in graph.keys():
i = lookUpGraph[x]
for y in graph.keys():
for h in range(0, len(graph[y])):
if x == (graph[y])[h]:
j=lookUpGraph[y]
matrixA[i][j] = 1
return matrixA
print("\nA\n%s" %convert_matrix())
'''Whoops: this converted the matrix incorrectly
What it did: if the j is in i, mark 1 vs
What its supposed to do: if there exists an edge from j to i
def convert_matrix():
matrixA = np.zeros((len(graph), len(graph)))
lookUpGraph = look_up()
for x in graph.keys():
i = lookUpGraph[x]
for h in range(0, len(graph[x])):
if graph[x][h] in lookUpGraph.keys():
j=lookUpGraph[graph[x][h]]
#print("i: %s, j: %s " %(i, j))
matrixA[i][j] = 1
return matrixA
'''
'''
A_ij = { max(out_degree, 1)
{ 0 if i != j
'''
def diag_matrix():
out_degreeList = out_degree(graph)
x=np.identity(len(graph))
matrixBound = len(graph)-1
for z in range(matrixBound,-1,-1): #decrement = -1, doens't include -1
#print(z)
popV = out_degreeList.pop() #so that you don't call pop twice
if(popV > x[z][z]): #out_degree bigger than the diagonal
x[z][z] = popV
return(x)
print("D\n%s"%diag_matrix())
'''
column vector
'''
def one_matrix():
x = np.ones((len(graph), 1))
return(x)
print("1\n%s"%one_matrix())
'''
D*(D-0.85*A)^-1 *1
'''
def pageRank():
one = one_matrix()
diag = diag_matrix()
matrixA = convert_matrix()
solution=np.matmul(np.matmul(diag,inv(np.subtract(diag,0.85*matrixA))), one)
return solution
print("\nPagerank is D*(D-0.85*A)^-1 * 1\n%s" %pageRank())