Friday, December 23, 2011

Computational economics Lecture 17


Schelling's Segregation Model

Schelling's model studies the (in)stability of mixed neighborhoods
Schelling won the Nobel Prize for this and other work
Model shows how local interactions can lead to interesting macroeconomic structure
In particular: Mild preferences can lead to strong segregation
What follows is a modified version that captures main idea

Outline of the Model

Suppose we have two types of people
  • Orange people and green people
The live mixed together on the unit square
  • Locations of the form (xy), where 0 < xy < 1
Initially they are integrated
  • Starting locations IID bivariate uniform on unit square
Each agent is now given the chance to stay or move
  • Stay if they are "happy," move if they are "unhappy"
  • Happy if half or more of 10 nearest neighbors are of the same type
  • Nearest is in terms of Euclidean distance
If agent is unhappy
  • Draw random location
    • If happy at new location, move there
    • Else, repeat
We cycle through the agents, giving offers to move
Continuing until no-one wishes to move

Modeling

Agents are modeled as objects
  • Data:
    • type and location
  • Methods:
    • Determine whether happy or not given locations of other agents
    • If not happy, move
      • find a new location where happy
Pseudocode for the main loop
while agents are still moving:
    for agent in agents:
        give agent the opportunity to move
Use 200 agents of each type
Plot the before and after locations

My Results

Initially agents are randomly mixed



But after four rounds of the while loop they have become segregated



Conclusion

  • People in the model don't mind to live mixed with other type
    • 50% of neighbors can be other color
  • But even with these preferences, segregation still occurs

Exercise

Run your own simulation

Solution

## Filename: seg.py
## Author: John Stachurski

from random import uniform
from math import sqrt
import matplotlib.pyplot as plt

num_of_type_0 = 200
num_of_type_1 = 200
num_neighbors = 10      # Number of agents regarded as neighbors
require_same_type = 5   # Want at least this many neighbors to be same type


class Agent:

    def __init__(self, type):
        self.type = type
        self.draw_location()

    def draw_location(self):
        self.location = uniform(0, 1), uniform(0, 1)

    def get_distance(self, other):
        "Computes euclidean distance between self and other agent."
        a = (self.location[0] - other.location[0])**2
        b = (self.location[1] - other.location[1])**2
        return sqrt(a + b)

    def happy(self, agents):
        "True if sufficient number of nearest neighbors are of the same type."
        distances = []
        # distances is a list of pairs (d, agent), where d is distance from
        # agent to self
        for agent in agents:
            if self != agent:
                distance = self.get_distance(agent)
                distances.append((distance, agent))
        # Sort from smallest to largest, according to distance
        distances.sort()
        # And extract the neighboring agents
        neighbors = [agent for d, agent in distances[:num_neighbors]]
        # Count how many neighbors have the same type as self
        num_same_type = sum(self.type == agent.type for agent in neighbors)
        return num_same_type >= require_same_type

    def update(self, agents):
        "If not happy, then randomly choose new locations until happy."
        while not self.happy(agents):
            self.draw_location()

def plot_distribution(agents, figname):
    "Plot the distribution of agents in file figname.png."
    x_values_0, y_values_0 = [], []
    x_values_1, y_values_1 = [], []
    for agent in agents:
        x, y = agent.location
        if agent.type == 0:
            x_values_0.append(x)
            y_values_0.append(y)
        else:
            x_values_1.append(x)
            y_values_1.append(y)
    plt.plot(x_values_0, y_values_0, 'o', markerfacecolor='orange', markersize=6)
    plt.plot(x_values_1, y_values_1, 'o', markerfacecolor='green', markersize=6)
    plt.savefig(figname)
    plt.clf()


def main():
    """
    Create a list of agents.  Loop until none wishes to move given the 
    current distribution of locations.
    """
    agents = [Agent(0) for i in range(num_of_type_0)]
    agents.extend(Agent(1) for i in range(num_of_type_1))

    count = 1
    while 1:
        print 'Entering loop ', count
        plot_distribution(agents, 'fig%s.png' % count)
        count += 1
        no_one_moved = True
        for agent in agents:
            old_location = agent.location
            agent.update(agents)
            if agent.location != old_location:
                no_one_moved = False
        if no_one_moved:
            break

0 comments: