import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
import random

def pageranks_walk(G, numIter):
	visits = {}
	for v in G.nodes():
		visits[v] = 0
	
	v = random.choice(list(G.nodes()))
	for i in range(0, numIter):
		visits[v] += 1
		
		if G.out_degree(v) > 0:
			v = random.choice(list(G.successors(v)))
		else:
			v = random.choice(list(G.nodes()))
	
	pageranks = {}
	for v in G.nodes():
		pageranks[v] = visits[v] / numIter
	
	return pageranks


def pageranks_calc(G, numIter):
	pageranks = {}
	sinks = 0
	sinksNext = 0
	for v in G.nodes():
		pageranks[v] = 1.0 / G.order()
		if G.out_degree(v) == 0:
			sinks += pageranks[v]
		
	for i in range(0, numIter):
		for v in G.nodes():
			pageranks[v] = sinks / G.order()
			
			for e in G.in_edges(v):
				u = e[0]
				pageranks[v] += pageranks[u] / G.out_degree(u)
				
			if G.out_degree(v) == 0:
				sinksNext += pageranks[v]
		
		sinks = sinksNext
		sinksNext = 0
		
	return pageranks


def pageranks_algebraic(G, numIter):
	A = nx.to_numpy_matrix(G)
	D = np.zeros(len(A))
	for i in range(0, len(A)):
		D[i] = A.sum(axis=1)[i]
		
	D = np.linalg.inv(np.diag(D))
	M = np.transpose(D * A)
	
	pageranks = np.full((len(A), 1), 1.0 / len(A))
	
	for i in range(0, numIter):
		pageranks = M * pageranks
		
	return pageranks


# Data from https://www.pro-football-reference.com/years/2019/games.htm
G = nx.read_edgelist("nfl.data", create_using=nx.DiGraph(), data = (("pL", int),("pW",int), ("ydsL",int), ("ydsW",int), ("toL", int),  ("toW", int)) )

D = nx.MultiDiGraph()
for e in G.edges():
	E = G.get_edge_data(e[0],e[1])
	
	for i in range(0, E['pW']):
		D.add_edge(e[0], e[1]);
		
	for i in range(0, E['pL']):
		D.add_edge(e[1], e[0]);
		

P = pageranks_calc(D, 100)
P = sorted(P.items(), key=operator.itemgetter(1), reverse=True)

P = pageranks_calc(D, 100)
P = sorted(P.items(), key=operator.itemgetter(1), reverse=True)
