{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "
\n", " \n", " \"QuantEcon\"\n", " \n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Schelling’s Segregation Model\n", "\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Contents\n", "\n", "- [Schelling’s Segregation Model](#Schelling’s-Segregation-Model) \n", " - [Overview](#Overview) \n", " - [The Model](#The-Model) \n", " - [Results](#Results) \n", " - [Exercises](#Exercises) \n", " - [Solutions](#Solutions) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Overview\n", "\n", "In 1969, Thomas C. Schelling developed a simple but striking model of racial segregation [[Sch69]](zreferences.ipynb#schelling1969)\n", "\n", "His model studies the dynamics of racially mixed neighborhoods\n", "\n", "Like much of Schelling’s work, the model shows how local interactions can lead to surprising aggregate structure\n", "\n", "In particular, it shows that relatively mild preference for neighbors of similar race can lead in aggregate to the collapse of mixed neighborhoods, and high levels of segregation\n", "\n", "In recognition of this and other research, Schelling was awarded the 2005 Nobel Prize in Economic Sciences (joint with Robert Aumann)\n", "\n", "In this lecture we (in fact you) will build and run a version of Schelling’s model" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The Model\n", "\n", "We will cover a variation of Schelling’s model that is easy to program and captures the main idea\n", "\n", "Suppose we have two types of people: orange people and green people\n", "\n", "For the purpose of this lecture, we will assume there are 250 of each type\n", "\n", "These agents all live on a single unit square\n", "\n", "The location of an agent is just a point $ (x, y) $, where $ 0 < x, y < 1 $" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Preferences\n", "\n", "We will say that an agent is *happy* if half or more of her 10 nearest neighbors are of the same type\n", "\n", "Here ‘nearest’ is in terms of [Euclidean distance](https://en.wikipedia.org/wiki/Euclidean_distance)\n", "\n", "An agent who is not happy is called *unhappy*\n", "\n", "An important point here is that agents are not averse to living in mixed areas\n", "\n", "They are perfectly happy if half their neighbors are of the other color" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Behavior\n", "\n", "Initially, agents are mixed together (integrated)\n", "\n", "In particular, the initial location of each agent is an independent draw from a bivariate uniform distribution on $ S = (0, 1)^2 $\n", "\n", "Now, cycling through the set of all agents, each agent is now given the chance to stay or move\n", "\n", "We assume that each agent will stay put if they are happy and move if unhappy\n", "\n", "The algorithm for moving is as follows\n", "\n", "1. Draw a random location in $ S $ \n", "1. If happy at new location, move there \n", "1. Else, go to step 1 \n", "\n", "\n", "In this way, we cycle continuously through the agents, moving as required\n", "\n", "We continue to cycle until no one wishes to move" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Results\n", "\n", "Let’s have a look at the results we got when we coded and ran this model\n", "\n", "As discussed above, agents are initially mixed randomly together\n", "\n", "![_static/figures/schelling_fig1.png](_static/figures/schelling_fig1.png) \n", "But after several cycles they become segregated into distinct regions\n", "\n", "![_static/figures/schelling_fig2.png](_static/figures/schelling_fig2.png) \n", "![_static/figures/schelling_fig3.png](_static/figures/schelling_fig3.png) \n", "![_static/figures/schelling_fig4.png](_static/figures/schelling_fig4.png) \n", "In this instance, the program terminated after 4 cycles through the set of\n", "agents, indicating that all agents had reached a state of happiness\n", "\n", "What is striking about the pictures is how rapidly racial integration breaks down\n", "\n", "This is despite the fact that people in the model don’t actually mind living mixed with the other type\n", "\n", "Even with these preferences, the outcome is a high degree of segregation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercises\n", "\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exercise 1\n", "\n", "Implement and run this simulation for yourself\n", "\n", "Use 250 agents of each type" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Solutions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exercise 1\n", "\n", "Here’s one solution that does the job we want. If you feel like a\n", "further exercise you can probably speed up some of the computations and\n", "then increase the number of agents." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Setup" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": true }, "outputs": [], "source": [ "using InstantiateFromURL\n", "github_project(\"QuantEcon/quantecon-notebooks-julia\", version = \"0.2.0\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false }, "outputs": [], "source": [ "using Parameters, Plots, LinearAlgebra, Statistics, Compat\n", "gr(fmt = :png);" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false }, "outputs": [], "source": [ "Agent = @with_kw (kind, location = rand(2))\n", "\n", "draw_location!(a) = a.location .= rand(2)\n", "\n", "# distance is just 2 norm: uses our subtraction function\n", "get_distance(a, agent) = norm(a.location - agent.location)\n", "\n", "function is_happy(a)\n", " distances = [(get_distance(a, agent), agent) for agent in agents]\n", " sort!(distances)\n", " neighbors = [agent for (d, agent) in distances[1:neighborhood_size]]\n", " share = mean(isequal(a.kind), other.kind for other in neighbors)\n", "\n", " # can also do\n", " # share = mean(isequal(a.kind),\n", " # first(agents[idx]) for idx in\n", " # partialsortperm(get_distance.(Ref(a), agents),\n", " # 1:neighborhood_size))\n", "\n", " return share ≥ preference\n", "end\n", "\n", "function update!(a)\n", " # If not happy, then randomly choose new locations until happy.\n", " while !is_happy(a)\n", " draw_location!(a)\n", " end\n", "end\n", "\n", "function plot_distribution(agents)\n", " x_vals_0, y_vals_0 = zeros(0), zeros(0)\n", " x_vals_1, y_vals_1 = zeros(0), zeros(0)\n", "\n", " # obtain locations of each type\n", " for agent in agents\n", " x, y = agent.location\n", " if agent.kind == 0\n", " push!(x_vals_0, x)\n", " push!(y_vals_0, y)\n", " else\n", " push!(x_vals_1, x)\n", " push!(y_vals_1, y)\n", " end\n", " end\n", "\n", " p = scatter(x_vals_0, y_vals_0, color = :orange, markersize = 8, alpha = 0.6)\n", " scatter!(x_vals_1, y_vals_1, color = :green, markersize = 8, alpha = 0.6)\n", " return plot!(legend = :none)\n", "end" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false }, "outputs": [], "source": [ "num_of_type_0 = 250\n", "num_of_type_1 = 250\n", "neighborhood_size = 10 # Number of agents regarded as neighbors\n", "preference = 0.5 # Want their kind to make at least this share of the neighborhood\n", "\n", "# Create a list of agents\n", "agents = vcat([Agent(kind = 0) for i in 1:num_of_type_0],\n", " [Agent(kind = 1) for i in 1:num_of_type_1])\n", "\n", "plot_array = Any[]\n", "\n", "# loop until none wishes to move\n", "while true\n", " push!(plot_array, plot_distribution(agents))\n", " no_one_moved = true\n", " for agent in agents\n", " old_location = copy(agent.location)\n", " update!(agent)\n", " if norm(old_location - agent.location) ≉ 0\n", " no_one_moved = false\n", " end\n", " end\n", " if no_one_moved\n", " break\n", " end\n", "end\n", "n = length(plot_array)\n", "plot(plot_array...,\n", " layout = (n, 1),\n", " size = (600, 400n),\n", " title = reshape([\"Cycle $i\" for i in 1:n], 1, n))" ] } ], "metadata": { "filename": "schelling.rst", "kernelspec": { "display_name": "Julia 1.2", "language": "julia", "name": "julia-1.2" }, "title": "Schelling’s Segregation Model" }, "nbformat": 4, "nbformat_minor": 2 }