In [207]:
%matplotlib inline
In [208]:
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
import matplotlib.animation as animation

from JSAnimation.IPython_display import display_animation, anim_to_html
In [242]:
n = 256
g = nx.erdos_renyi_graph(n, 1.)
# g = nx.erdos_renyi_graph(n, 10/(n-1))
# g = nx.watts_strogatz_graph(n, 4, 0.001)
# g = nx.barabasi_albert_graph(n, 2)
# g = nx.powerlaw_cluster_graph(n, 2, 0.01)
# g = nx.relaxed_caveman_graph(16, 16, 0.12)
# g = nx.read_graphml("risk.graphml").to_undirected()
# g = nx.read_graphml("USAir97.graphml").to_undirected()

print("Nodes:", len(g.nodes))
pos = nx.fruchterman_reingold_layout(g, k=0.1)

# The KK layout algorithm takes a minute
# pos = nx.kamada_kawai_layout(g)
Nodes: 256

Probabilistic SI Model

In [243]:
infected_map = {x:False for x in g.nodes}
infected_map[94] = True

trans_p = 0.9
In [244]:
node_dict = g.nodes(data=True)
for k in [inf for inf in infected_map if infected_map[inf] == True]:
    print(node_dict[k])
{}
In [245]:
# Build the graph and set its size
graph_fig = plt.figure()
graph_fig.set_figheight(10)
graph_fig.set_figwidth(15)
ax = graph_fig.gca()

# The edges don't change, so we want to go ahead and draw them once
nx.draw_networkx_edges(g, pos, ax=ax)

# Get colors for infected nodes
cmap = plt.get_cmap("rainbow")
colors = [1.0 if infected_map[x] else 0.0 for x in g.nodes]

# Draw the first frame of our animation
ims = [
    (nx.draw_networkx_nodes(g, pos, node_color=colors, cmap=cmap, ax=ax, vmin=0.0, vmax=1.0),)
]

# Draw at most *horizon* fames, keeping track of changes in the infected count
#  We'll stop if we don't see the infected count change.
horizon = 16
last_infected_count = sum([1 for n, i in infected_map.items() if i])
infected_counts = [last_infected_count]

# For up to *horizon* time steps, infect nodes
for add in np.arange(horizon):
    
    # For each infected node, find and infect uninfected neighbors
    for ill_node in [n for n, i in infected_map.items() if i]:
        for neighbor in g.neighbors(ill_node):
            
            # probabilistic transmission
            if ( np.random.random() < trans_p ):
                infected_map[neighbor] = True
    
    # Update infected colors
    colors = [1.0 if infected_map[x] else 0.0 for x in g.nodes]
    
    # Add the new frame of colored nodes to our frames
    ims.append(
        (nx.draw_networkx_nodes(g, pos, node_color=colors, cmap=cmap, ax=ax, vmin=0.0, vmax=1.0),)
    )
    
    # Check if we have infected the whole graph or reached a steady state/fixed point
    infected_count = sum([1 for n, i in infected_map.items() if i])
    if ( infected_count == len(g.nodes) ):
        print("Total Infection After:", add+1)
        break

    last_infected_count = infected_count
    infected_counts.append(last_infected_count)

im_ani = animation.ArtistAnimation(graph_fig, ims, interval=1000, repeat_delay=3000,
                                   blit=True)

display_animation(im_ani)
Total Infection After: 2
Out[245]:


Once Loop Reflect
In [246]:
plt.plot(infected_counts)
plt.xlabel("Time Steps")
plt.ylabel("Infected Count")

plt.show()
In [ ]:
print("Degree Centrality:")
cents = sorted(nx.degree_centrality(g).items(), key=lambda x: x[1], reverse=True)
for node, rank in cents[:5]:
    print("\t", node, rank)
print("\t ...")
for node, rank in cents[-5:]:
    print("\t", node, rank)
    
print("Closeness Centrality:")
cents = sorted(nx.closeness_centrality(g).items(), key=lambda x: x[1], reverse=True)
for node, rank in cents[:5]:
    print("\t", node, rank)
print("\t ...")
for node, rank in cents[-5:]:
    print("\t", node, rank)
    
print("Betweenness Centrality:")
cents = sorted(nx.betweenness_centrality(g).items(), key=lambda x: x[1], reverse=True)
for node, rank in cents[:5]:
    print("\t", node, rank)
print("\t ...")
for node, rank in cents[-5:]:
    print("\t", node, rank)
    
print("Eigenvector Centrality:")
cents = sorted(nx.eigenvector_centrality(g).items(), key=lambda x: x[1], reverse=True)
for node, rank in cents[:5]:
    print("\t", node, rank)
print("\t ...")
for node, rank in cents[-5:]:
    print("\t", node, rank)

Immunization

In [ ]:
infected_map = {x:False for x in g.nodes}
infected_map[0] = True

immune_map = {x:False for x in g.nodes}
immune_map[219] = True
immune_map[179] = True

trans_p = 1.
In [ ]:
node_dict = g.nodes(data=True)
print("Infected:")
for k in [inf for inf in infected_map if infected_map[inf] == True]:
    print(node_dict[k])
    
print("Innoculated:")
for k in [inf for inf in immune_map if immune_map[inf] == True]:
    print(node_dict[k])
In [ ]:
# Build the graph and set its size
graph_fig = plt.figure()
graph_fig.set_figheight(10)
graph_fig.set_figwidth(15)
ax = graph_fig.gca()

# The edges don't change, so we want to go ahead and draw them once
nx.draw_networkx_edges(g, pos, ax=ax)

# Get colors for infected nodes
cmap = plt.get_cmap("rainbow")
colors = [1.0 if infected_map[x] else 0.5 if immune_map[x] else 0.0 for x in g.nodes]

# Draw the first frame of our animation
ims = [
    (nx.draw_networkx_nodes(g, pos, alpha=0.75, node_color=colors, cmap=cmap, ax=ax, vmin=0.0, vmax=1.0),)
]

# Draw at most *horizon* fames, keeping track of changes in the infected count
#  We'll stop if we don't see the infected count change.
horizon = 16
last_infected_count = sum([1 for n, i in infected_map.items() if i])
infected_counts = [last_infected_count]

# For up to *horizon* time steps, infect nodes
for add in np.arange(horizon):
    
    # For each infected node, find and infect uninfected neighbors
    for ill_node in [n for n, i in infected_map.items() if i]:
        for neighbor in g.neighbors(ill_node):
            
            # Can't infect immune neighbors
            if ( immune_map[neighbor] == True ):
                continue
            
            # probabilistic transmission
            if ( np.random.random() < trans_p ):
                infected_map[neighbor] = True
    
    # Update infected colors
    colors = [1.0 if infected_map[x] else 0.5 if immune_map[x] else 0.0 for x in g.nodes]
    
    # Add the new frame of colored nodes to our frames
    ims.append(
        (nx.draw_networkx_nodes(g, pos, alpha=0.75, node_color=colors, cmap=cmap, ax=ax, vmin=0.0, vmax=1.0),)
    )
    
    # Check if we have infected the whole graph or reached a steady state/fixed point
    infected_count = sum([1 for n, i in infected_map.items() if i])
    if ( infected_count == len(g.nodes) ):
        print("Total Infection After:", add+1)
        break
    elif (last_infected_count == infected_count):
        print("Reached steady state after:", add+1)
        break
    last_infected_count = infected_count
    infected_counts.append(last_infected_count)

print("Infected Percentage:", infected_counts[-1] / len(g.nodes))
    
im_ani = animation.ArtistAnimation(graph_fig, ims, interval=1000, repeat_delay=3000,
                                   blit=True)

display_animation(im_ani)
In [ ]:
 

K Threshold Model

In [ ]:
infected_map = {x:False for x in g.nodes}
infected_map[182] = True
infected_map[50] = True
In [ ]:
k_threshold = 2

graph_fig = plt.figure()
graph_fig.set_figheight(10)
graph_fig.set_figwidth(15)
ax = graph_fig.gca()

nx.draw_networkx_edges(g, pos, ax=ax)

cmap = plt.get_cmap("rainbow")
colors = [1.0 if infected_map[x] else 0.0 for x in g.nodes]
ims = [
    (nx.draw_networkx_nodes(g, pos, node_color=colors, cmap=cmap, ax=ax, vmin=0.0, vmax=1.0),)
]

# Draw at most *horizon* fames, keeping track of changes in the infected count
#  We'll stop if we don't see the infected count change.
horizon = 10
last_infected_count = sum([1 for n, i in infected_map.items() if i])
infected_counts = [last_infected_count]

# For up to *horizon* time steps, infect nodes
for add in np.arange(horizon):
    
    # Make a temporary copy of the infected map, so we don't add
    #  newly infected people in the spreading step
    this_step_inf_map = dict(infected_map)

    # For each node, check if >= k-threshold neighors are infected
    for node in g.nodes:
        # If we are already infected, skip
        if (infected_map[node] ):
            continue
            
        # How many infected neighbors do we have?
        infected_neighbors = sum([1 for v in g.neighbors(node) if infected_map[v]])
        
        # compare against threshold
        if ( infected_neighbors >= k_threshold ):
            this_step_inf_map[node] = True
    
    # Update the infected map with new infections
    infected_map.update(this_step_inf_map)
    
    colors = [1.0 if infected_map[x] else 0.0 for x in g.nodes]
    ims.append(
        (nx.draw_networkx_nodes(g, pos, node_color=colors, cmap=cmap, ax=ax, vmin=0.0, vmax=1.0),)
    )
    
    infected_count = sum([1 for n, i in infected_map.items() if i])
    if ( infected_count == len(g.nodes) ):
        print("Total Infection After:", add+1)
        break
    elif (last_infected_count == infected_count):
        print("Reached steady state after:", add+1)
        break
    last_infected_count = infected_count
    infected_counts.append(last_infected_count)

im_ani = animation.ArtistAnimation(graph_fig, ims, interval=1000, repeat_delay=3000,
                                   blit=True)

display_animation(im_ani)
In [ ]:
plt.plot(infected_counts)
plt.xlabel("Time Steps")
plt.ylabel("Infected Count")

plt.show()
In [ ]: