#!/usr/bin/env python # coding: utf-8 # ## CSCS530 Winter 2015 # #### Complex Systems 530 - Computer Modeling of Complex Systems (Winter 2015) # # * Course ID: CMPLXSYS 530 # * Course Title: Computer Modeling of Complex Systems # * Term: Winter 2015 # * Schedule: Wednesdays and Friday, 1:00-2:30PM ET # * Location: 120 West Hall (http://www.lsa.umich.edu/cscs/research/computerlab) # * Teachers: [Mike Bommarito](https://www.linkedin.com/in/bommarito) and [Sarah Cherng](https://www.linkedin.com/pub/sarah-cherng/35/1b7/316) # # #### [View this repository on NBViewer](http://nbviewer.ipython.org/github/mjbommar/cscs-530-w2015/tree/master/) # # # Basic Networks # # In this notebook, we'll explore one of the most popular types of environments - a network. In the cells below, we'll be creating a small-world network and simulating a disease outbreak. # # ### Imports # # In the import section below, you'll see an important new addition: __networkx__. We'll be using __networkx__ as our preferred package for creating and managing network objects; we'll include links to more info and documentation in later cells. # In[98]: get_ipython().run_line_magic('matplotlib', 'inline') # Imports import networkx as nx import numpy import matplotlib.pyplot as plt import pandas import seaborn; seaborn.set() # Import widget methods from IPython.html.widgets import * # ## Initializing a network # # In some problems, we can define our own rules to _"grow"_ or _"generate"_ a network. However, for many problems, we may want to re-use an existing methodology. __networkx__ comes with a suite of methods to "sample" random graphs, such as: # * Trees, e.g., balanced trees (networkx.balanced_tree) # * Erdos-Renyi graphs (networkx.erdos_renyi_graph) # * Watts-Strogatz small-world graphs (networkx.watts_strogatz_graph) # * Bipartite graphs # # For a full list, see [this page on Graph Generators in the networkx documentation](https://networkx.github.io/documentation/latest/reference/generators.html). # # In the sample below, we'll create a Newman-Watts-Strogatz small-world graph and print some basic info about the graph. # In[99]: # Create a random graph nodes = 30 edges = 2 prob_out = 0.2 g = nx.newman_watts_strogatz_graph(nodes, edges, prob_out) print((g.number_of_nodes(), g.number_of_edges())) # ## Visualizing a network # # As humans, we are wired for visuals; for networks, visualizations can provide an important first characterization that isn't apparent from simple statistics. # # In the cell below, we show how to calculate a "layout" for a network and visualize it using networkx. # # For more examples, see [the Drawing Graphs section of the NetworkX tutorial](https://networkx.github.io/documentation/latest/tutorial/tutorial.html#drawing-graphs). # In[100]: # Draw the random graph g_layout = nx.spring_layout(g, iterations=1000) nx.draw_networkx(g, pos=g_layout, node_color='#dddddd') # ## Outbreak in a network # # Next, we'll simulate a very simple outbreak in a network. Our disease will start by infecting a random patient, then pass with probability 1 to any connected individuals. # # To find the "connected" individuals, we'll need to learn how to find the neighbors of a node. NetworkX makes this easy. # In[101]: # Let's pick a node at random to infect patient_zero = numpy.random.choice(g.nodes()) patient_zero healthy_nodes = g.nodes() healthy_nodes.remove(patient_zero) # In[102]: # Now we can visualize the infected node's position f = plt.figure() nx.draw_networkx_nodes(g, g_layout, nodelist=[patient_zero], node_color='red') nx.draw_networkx_nodes(g, g_layout, nodelist=healthy_nodes, node_color='#dddddd') nx.draw_networkx_edges(g, g_layout, width=1.0, alpha=0.5, edge_color='#111111') _ = nx.draw_networkx_labels(g, g_layout, dict(zip(g.nodes(), g.nodes())), font_size=10) # ## First model step # # In our simple disease outbreak model, each step of the model consists of the following: # # * for each infected individual, find their neighbors # * infect all neighbors # # For our first step, we start with a single infected person; in subsequent steps, we need to use a _for_ loop to handle all currently infected persons. # In[103]: # Find patient zero's neighbors neighbors = g.neighbors(patient_zero) neighbors # Let's infect all of his neighbors! infected_patients = [patient_zero] infected_patients.extend(neighbors) infected_patients # Remove the infected from healthy nodes healthy_nodes = [node for node in healthy_nodes if node not in infected_patients] # In[104]: # Now we can visualize the infected node's position f = plt.figure() nx.draw_networkx_nodes(g, g_layout, nodelist=infected_patients, node_color='red') nx.draw_networkx_nodes(g, g_layout, nodelist=healthy_nodes, node_color='#dddddd') nx.draw_networkx_edges(g, g_layout, width=1.0, alpha=0.5, edge_color='#111111') _ = nx.draw_networkx_labels(g, g_layout, dict(zip(g.nodes(), g.nodes())), font_size=10) # ## Second model step # # As mentioned above, we now need to use a _for_ loop over all individuals. # In[105]: # Now let's infect the neighbors of all infected patients! newly_infected = [] for infected_patient in infected_patients: # Find patient zero's neighbors neighbors = [neighbor for neighbor in g.neighbors(infected_patient) if neighbor not in infected_patients] newly_infected.extend(neighbors) newly_infected # In[106]: # Update infected and healthy infected_patients.extend(newly_infected) # Remove the infected from healthy nodes healthy_nodes = [node for node in healthy_nodes if node not in infected_patients] # In[107]: # Now we can visualize the infected node's position f = plt.figure() nx.draw_networkx_nodes(g, g_layout, nodelist=infected_patients, node_color='red') nx.draw_networkx_nodes(g, g_layout, nodelist=healthy_nodes, node_color='#dddddd') nx.draw_networkx_edges(g, g_layout, width=1.0, alpha=0.5, edge_color='#111111') _ = nx.draw_networkx_labels(g, g_layout, dict(zip(g.nodes(), g.nodes())), font_size=10) # ## Running a few more steps # # Let's wrap our model step method in yet another _for_ loop, allowing us to simulate multiple steps of the model at once. # In[108]: # Now let's infect the neighbors of all infected patients! model_steps = 5 # Iterate over steps for i in range(model_steps): # Iterate over infected newly_infected = [] for infected_patient in infected_patients: # Find patient neighbors and infect neighbors = [neighbor for neighbor in g.neighbors(infected_patient) if neighbor not in infected_patients] newly_infected.extend(neighbors) # Remove the infected from healthy nodes infected_patients.extend(newly_infected) healthy_nodes = [node for node in healthy_nodes if node not in infected_patients] # Now we can visualize the infected node's position f = plt.figure() nx.draw_networkx_nodes(g, g_layout, nodelist=infected_patients, node_color='red') nx.draw_networkx_nodes(g, g_layout, nodelist=healthy_nodes, node_color='#dddddd') nx.draw_networkx_edges(g, g_layout, width=1.0, alpha=0.5, edge_color='#111111') _ = nx.draw_networkx_labels(g, g_layout, dict(zip(g.nodes(), g.nodes())), font_size=10)