I have partly read through the original PageRank paper, and I have implemented a rough and much simplified version of the algorithm in the codebase as a first sketch of what it’ll become in the future.
The simplified formula:
The full formula:
Derivation of the full formula used in below pseudocode of a complete implementation of PageRank:
function computePageRank(pages, backlinks, outdegree, epsilon, d = 0.85, maxIterations = 200):
N = length(pages)
# Step 1: Initialize ranks uniformly
PR = empty map
for each p in pages:
PR[p] = 1.0 / N
# Precompute dangling nodes (pages with no outgoing links)
dangling = []
for each p in pages:
if outdegree[p] == 0:
append p to dangling
# Step 2: Iterate until convergence
iterations = 0
delta = infinity
while delta > epsilon and iterations < maxIterations:
# Total rank currently held by dangling nodes
danglingMass = 0
for each p in dangling:
danglingMass += PR[p]
teleportShare = (1 - d) / N # "jump to random page" term
danglingShare = d * danglingMass / N # redistribute dangling mass
# One round: every page passes rank along its outlinks
newPR = empty map
for each u in pages:
linkContrib = 0
for each v in backlinks[u]:
linkContrib += PR[v] / outdegree[v]
newPR[u] = teleportShare + d * linkContrib + danglingShare
# Convergence check: L1 norm of the change
delta = 0
for each u in pages:
delta += abs(newPR[u] - PR[u])
# Accept the new ranks
PR = newPR
iterations += 1
return PR, delta, iterations