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

################################################################################
# Let's consider once again our DNC graph. As we've done with triadic closure 
# (aka 'common neighbors' below), we're going to evaluate how well our link
# predictors work on this social communication network.

# Read in our good friend the DNC temporal network
G = nx.read_weighted_edgelist("out.dnc-temporalGraph.data", create_using=nx.MultiGraph(), comments="%")

# Sort edges by timestamp (parsed as 'weight' for simplicity)
edges = sorted(G.edges(data=True), key=lambda t: t[2].get('weight', 1))

# Go through our predictors
G1 = nx.MultiGraph()
t_0 = G.size() / 20
counter = 0
max_k = 0
for e in edges:
  G1.add_edge(e[0], e[1])
  counter += 1
  # As before, we'll evaluate at some given time t_0, here after 5% edges added
  if counter > t_0:
    t_0 = G.size() + 1
    commons = {}
    dmax = sorted([d for n, d in G1.degree()], reverse=True)[0]
    for v in G1.nodes():
      for u in G1.nodes():
        Nu = set(G1.neighbors(u))
        Nv = set(G1.neighbors(v))
        if v > u and G1.has_edge(v, u) == False:
          
          # common neighbors
          k = len(Nu.intersection(Nv))
          
          # jaccard
          # k = len(Nv.intersection(Nu))
          # k /= len(Nv.union(Nu))
          # k *= dmax
                        
          # preferential attachment
           # k = len(Nv) * len(Nu)
              
          if k > 0:
            commons[(v,u)] = int(k)
          if k > max_k:
            max_k = int(k)

# We'll do the same thing we did before, where we evaluate the probability of
# edge creation relative to the strength of the above predictors.
total_counts = [0]*(max_k+1)
edge_counts = [0]*(max_k+1)
for c in commons:
  total_counts[commons[c]] += 1
  if G1.has_edge(c[0], c[1]):
    edge_counts[commons[c]] += 1

probs = [0]*(max_k+1)
for i in range(0, max_k+1):
  if total_counts[i] > 0:
    probs[i] = edge_counts[i] / total_counts[i]

# Hopefully plotting now works
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(probs)
plt.show()
