-
Notifications
You must be signed in to change notification settings - Fork 0
/
pagerank.py
105 lines (84 loc) · 2.99 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
from _page_rank import ffi, lib
import sys
class PageRank:
def __init__(self, maxNodes, epsilon, dVal, threads, batchsize, scale,
weighted):
self.graph = lib.newGraph(maxNodes, batchsize, dVal, epsilon, threads,
1 if scale else 0)
self.mapping = {}
self.index = 0
self.scale = scale
self.weighted = weighted
self.weight = {}
def __del__(self):
lib.cleanup(self.graph)
def addWeight(self, name, weight):
if not name in self.weight:
self.weight[name] = 0
self.weight[name] += weight
def getTotalWeight(self, name):
return self.weight[name]
def addEdge(self, line):
(left, right, weight) = line
# see http://stackoverflow.com/a/402704/2243495
if isinstance(left, int):
leftId = left
else:
leftId = self.getOrSetId(left)
if isinstance(right, int):
rightId = right
else:
rightId = self.getOrSetId(right)
if not self.weighted:
# we want to point from left to right with weight 1
weight = -1
if weight > 0:
lib.addEdgeByIds(self.graph, rightId, leftId, weight)
self.addWeight(left, weight)
self.addWeight(right, -weight)
elif weight < 0:
lib.addEdgeByIds(self.graph, leftId, rightId, -weight)
self.addWeight(right, -weight)
self.addWeight(left, weight)
else:
# lets not figure out how to handle this until it happens
raise Exception("zero weight")
return [left, right]
def getId(self, name):
return self.mapping[name]
def setId(self, name, id):
self.mapping[name] = id
def getOrSetId(self, name):
if name in self.mapping:
return self.getId(name)
else:
self.setId(name, self.index)
self.index += 1
return self.index - 1
def computeRanking(self, maxiterations):
# todo undirected stuff
for i in range(maxiterations):
self.computeIteration()
if self.isConverged():
break
def findNode(self, name):
if isinstance(name, int):
id = name
else:
id = self.getId(name)
return lib.findNodeById(self.graph, id)
def isConverged(self):
return self.graph.converged == 1
def computeIteration(self):
lib.computeIteration(self.graph)
def getOrderedNodes(self, nodes):
name_ordered = sorted(nodes)
return sorted(name_ordered, key=self.getRank, reverse=True)
def getTotalWeightOrderedNodes(self, nodes):
return sorted(nodes, key=self.getTotalWeight, reverse=True)
def getRank(self, node):
struct = self.findNode(node)
rank = struct.pageRank_b if self.graph.isSourceA == 1 else struct.pageRank_a
if self.scale:
rank = rank * self.graph.weightedSize
return rank