-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCoachingGraph.py
123 lines (97 loc) · 3.16 KB
/
CoachingGraph.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
from matplotlib.pyplot import pause
from random import choice
import networkx as nx
import matplotlib.pyplot as plt
import itertools
import Queue
class UserInfo(object):
def __init__(self, name, user_id):
self.infected = False
self.name = name
self.user_id = user_id
self.pos = None
class CoachingGraph(object):
def __init__(self):
self.user_network = nx.DiGraph()
def add_user(self, user_id, name = '', coach = None, students = None):
if user_id in self.user_network.nodes():
print 'User already exists'
return
self.user_network.add_node(user_id, info = UserInfo(name,user_id))
if students:
for student in students:
self.add_coaching_relation(user_id, student)
if coach:
self.add_coaching_relation(coach, user_id)
#Update graph layout and fix it
self.pos = nx.spring_layout(self.user_network)
def add_coaching_relation(self, coach, student):
if coach in self.user_network.nodes():
if student in self.user_network.nodes():
self.user_network.add_edge(coach, student)
else:
print 'Student ' + str(student) + ' does not exist in userbase'
else:
print 'Coach ' + str(coach) + ' does not exist in userbase'
def get_name(self, node):
return self.user_network.node[node]['info'].name
def total_infection(self, node):
undirected_copy = nx.Graph(self.user_network)
bfs_path = [node] + map(lambda x: x[1],
nx.bfs_edges(undirected_copy, node))
self.plot()
for infectee in bfs_path:
self.infect_user(infectee)
self.plot()
def limited_infection(self, target_num):
original_target = target_num
if target_num > len(self.user_network):
self.infect_all()
print 'All users infected'
return
for user in self.user_network.nodes_iter():
if target_num == 0:
break
if self.user_network.in_degree(user) == 0:
target_num -= self.limited_bfs_infection(user, target_num)
num_infected = original_target - target_num
print 'Infected ' + str(num_infected) + \
' out of ' + str(original_target)
def limited_bfs_infection(self, node, target_num):
original_target = target_num
if target_num == 0:
return 0
self.infect_user(node)
target_num -= 1
successors = nx.bfs_successors(self.user_network,node)
fringe = Queue.Queue()
fringe.put(node)
while not fringe.empty():
self.plot()
coach = fringe.get()
if coach in successors and len(successors[coach]) <= target_num:
for student in successors[coach]:
self.infect_user(student)
fringe.put(student)
target_num -= len(successors[coach])
return original_target - target_num
def infect_user(self, node):
self.user_network.node[node]['info'].infected = True
def infect_all(self):
for infectee in self.user_network.nodes():
self.infect_user(infectee)
def plot(self):
plt.clf()
plt.ion()
labels=dict((n,d['info'].name)
for n,d in self.user_network.nodes(data=True))
nx.draw_networkx(self.user_network,
pos = self.pos,
node_color = ['r' if self.user_network.node[n]['info'].infected
else 'forestgreen' for n in self.user_network],
node_size = [100 + 50 * self.user_network.degree(n)
for n in self.user_network],
labels = labels,
alpha = .7)
plt.draw()
pause(.5)