Part 1: Emoji Simulator

For this part, we’ll be using Nicky Case’s agent-based modeling simulator, the Emoji Simulator. When you make your write-ups with this, you can include screenshots for your plots and as your model “code”.


Figure 1. Demographic patterns in Detroit (graphic by Eric Fischer).

Problem 1: The Schelling Model

During the 1960s the economist Thomas Schelling researched segregation and racial preferences, and showed individuals can have only relatively mild preferences for the same type and yet these subtle preferences can lead to societal segregation.

The rules for this model are simple: each person is happy if at least a certain percentage of their neighbors are the same type as them. If a person is happy, they stay in their current location. If they are unhappy, they move to a randomly chosen new location. This continues until all the people are happy (or possibly forever).

Start by doing the following:

  • Open a blank model: https://ncase.me/sim/?s=blank
  • Make two new emoji agent types. They can be any emoji’s you want (emojipedia.org). I highly recommend choosing emojis with contrasting colors. I used whales and foxes in my implementation, so I’ll refer to them as whales and foxes below.
  • Choose a square grid of at least 30 x 30.
  • Set the initialization so that there are about equal numbers of empty spaces, whales, and foxes (or whatever emoji you chose).

For each problem, include the written answer to the problem, a screenshot of the model behavior, and the “code” (a screenshot or listing of the rules and model/environment setup).

Problem 1A) From the blank model, code up a version of the Schelling model with the following rules:

  • Each type of animal (whales and foxes) wants at least X of its neighbors to be like itself–in other words:
  • If if less than X of its neighbors are like itself, it will move to a random location anywhere on the board
  • Consider neighbors to be the 8 squares that share an edge or corner with the current location.

Code the model, supposing that each animal will move if less than 2 (25%) of its neighbors to be the same as it. Run the model a few times. What behavior do you observe?


Problem 1B) Adjust the number of neighbors required to be the same. How does the model behavior vary as this number varies from 1 to 8?


Problem 1C) Now try out adjusting the balance between empty cells and animals. How does the model behavior change as the density of whales and foxes increases or decreases? Do you always observe separation between the two types? Why do you think this is?


Problem 1D) Lastly, let’s illustrate the importance of being careful about how we specify our rules. Re-run problems 1A - 1C with a slightly different rule: each type of animal wants no more than Y of its neighbors to be the opposite type. In other words, if there are more than 6 (75%) neighbors of the other type, it will move. Does this change the behavior of the model? If so, how does the behavior change? Why do you think this is?


Problem 2: Build your own model!

Start with a blank model and build a model of your choosing! In your write-up, document the model you built, including:

  • The overall process your are modeling and/or question you are trying to address
  • Agents: the types of agents in your model
  • Rules/interactions: the rules they follow (including what configuration of neighbors they look at)
  • Environment: the environmental specifications you used (grid size, etc.)


Part 2: Python

Optional Problem

If you’re relatively new to Python, or you don’t know how to build loops and/or functions in Python, here are some tutorials to get started with:

  • 10-minute Python - very short tutorial with just the basics (often useful if you’ve coded in other things or have used python but not in a while)
  • The Python Tutorial - the official tutorial, gives more details and a good reference. Good to start with if you’ve never used python. Check out the resources section of the course website for more tutorials also.
  • Think Python - our book is a good reference too—you may want to start with Chapters 2 and 3.

Finally, we’ll be using a few modules/packages for Python in this class, such as numpy, scipy, and matplotlib. To get familiar with those, here’s a quick cheatsheet that covers many of the packages we’ll need (also useful as a reference even if you’ve used them before!).


Problem 1: Swarming Model

Next we will work with a simple agent based model of swarming flying insects (e.g. gnats) in python, adapted from Sayama’s PyCX library. This model illustrates much of the types of structures we will use throughout the class for our models.

In particular, many of the models we use will be built on three main functions:

  • Initialize: sets up the model
  • Update: moves the model forward one time step
  • Observe: generates any plots or output we wish to observe from the model

With these three basic functions and a for loop, we can build a ton of different models, as we will see over the semester! In any case, the code for the model is here: Swarming Agent-Based Model.

Problem 1A: Understanding the model) Read through the model code. In the section labeled “Define our Agents”, look at the class definition given there. We haven’t covered classes in python yet, but the agent class here defines the properties that agents have (under __init__) and the actions they can take (the other functions defined there). Based on this, list the properties and actions for the agents in this model, and say what you think each property or action means/does (include this in your homework writeup).

Problem 1B: Running the model) Run the model for 30 timesteps (the default that’s already set) and observe the behavior of the swarm. Include the plot of the swarm at the final timestep in your writeup.

Problem 1C: Expanding the swarm) In the model, each insect in the swarm is started at a random position in the unit square (the box from 0 to 1 in x and y). Adjust the code in the initialize function to make the swarm start off in a random position in a box with side-length 10 (i.e. a 10x10 box, or put another way, random x-axis and y-axis values between 0 and 10). Run the model for 30 steps again (possibly a few times to see what it does consistently). Then try the model with a 100x100 box. Include plots of the swarm at the final time step for the length 10 box and the length 100 box.

Do the swarms behave the same for each initial swarm size? Does the swarm appear to converge back to a swarm of the same size at the end of all three simulations (length 1, 10, 100), or does the final swarm size appear to change depending on the initial size? Include your answers in your writeup.

Problem 1D: Measuring swarm size) One way to track the swarm size is to calculate the variance (a measure of spread of a distribution) of the positions of all the agents. Let’s plot the variance over time for our model. We’ll do that like this:

  • Add a new global variable called vars to the global line in our three functions (i.e. it should read global agents, vars)
  • We’ll calculate the variance of the positions of our insects using the var command from numpy. Add this line to the end of the initialize function: vars = [np.var([a.x for a in agents])]. This will be a list we will use to store the variance at each time step.
  • Also add this line to the end of the update function: vars.append(np.var([a.x for a in agents])). This will add the new variance each time we update the model.

Finally, edit the model so that you run it for 100 time steps (instead of 30), and add this code after you’ve run the model:

plt.figure()
plt.plot(range(101),vars)

If running 100 time steps takes too long, you may want to comment out the lines for observe() and the display/sleep commands so that it doesn’t generate a plot at each step as it runs.

Generate plots of the variance over time for 100 time steps with initial swarm locations in boxes of length 1, 10, and 100. Include all three plots in your writeup. How does the swarm size change over time? How does it change as you adjust the size of the initial swarm? Include your answers in your writeup.



Problem 2: The Chaos Game

Next, let’s code up the Chaos Game in Python. This will give us some practice coding from scratch—building functions, using for loops, and using if statements. We’ll code it up step by step, and then put it all together.

First, let’s import some of the libraries we need (you may need to install these libraries first!):

from math import *                  # useful math functions
import numpy as np                  # useful array objects 
                                    # (also a core scientific computing library)
import matplotlib.pyplot as plt     # nice plotting commands
from random import random, randint  # random number generation functions

Problem 2A: Functions) Write a function called midpoint that takes in two tuples of the form (x,y) as inputs, and returns their midpoint as a new tuple. We can calculate the midpoint of two points \((x_1, y_1)\) and \((x_2,y_2)\) like this: \[ midpoint = \left(\frac{1}{2}(x_1 + x_2) \, ,\, \frac{1}{2}(y_1 + y_2) \right)\] We will use this function later to calculate add new points as we draw the chaos game. Add this function to the beginning of your script.


Problem 2B: Setup) Next, let’s setup some of what we need for the Chaos Game:

  • Make a list called corner that contains three tuples, each with the coordinates of one vertex on your equilateral triangle. In case you’ve forgotten your Pythagorean theorem from way back when, here’s a set of coordinates you can use: \((0,0)\), \((1,0)\), and \((0.5, \sqrt{3}/2)\) (python uses the function sqrt for square roots).
  • Set the number of total points we will plot as N = 1000
  • Make two vectors of length 1000 filled with zeros using the np.zeros function. We will use these to store all the x and y coordinates we will plot on the Chaos Game. You can make these arrays like this: x = np.zeros(N).

Problem 2C: Starting position) Now we have everything we need, and we can start the Chaos Game! Choose a random starting position for your x and y coordinates, and store this starting position in your x and y arrays as the first entry. (Remember that Python indexes from zero so you’ll store these in x[0] and y[0]!) To choose the random location, you can use the random() function. (This will pick a random value between 0 and 1, which works out since those are the maximum size for the triangle we’re using. If you picked a different size triangle, be sure to adjust the range for your random draw!)


Problem 2D: For loops) Now that we have our starting position, we need to choose the rest of our 1000 points. For this, we’ll use a loop. Write a loop that iterates from 1 to N. On each iteration of the loop, you should:

  • Choose a random vertex from your list corner
  • Calculate the midpoint between this vertex and the previous point in your x and y list
  • Save this midpoint to the list of x and y coordinates

Remember that for Python, spacing is important! Make sure you indent each line in the for loop the same amount, or you’ll run into trouble.


Problem 2E: Plot the results!) Okay, we should have a nice Chaos Game going now! We can plot our results like this:

plt.figure()
plt.scatter(x, y)   # plot our chaos game points
plt.scatter((0,1,0.5),(0,0,sqrt(3)/2),color='red') # plot the triangle vertices
plt.show()

When you put all this code together, you should get something that looks roughly like this! Include your final plot and your code when you turn in your lab.


Optional Problem 3

If you have time and interest, try changing the Chaos Game! A few things you can try:

  • Change the number of vertices you consider (you can make squares or lots of other shapes)
  • Change the fraction of the distance that you traverse with each new point (e.g. go 1/3 of the way instead of halfway to the vertex)
  • Change the rules for the vertex order that you choose! (e.g. make it so you can’t choose the same vertex twice)

If you want to try some pre-worked out ideas, there are some nice examples on Wolfram Mathworld. If you try a few different things, what do you notice? Are there particular configurations that work or don’t work? Why do you think this is?



Part 3: Project Ideas

What are you considering for your final project? Give an idea or two (definitely not final, just want you to start thinking about possibilities!)