├── .gitignore ├── LICENSE ├── README.md ├── analysis.ipynb ├── model.py ├── requirements.txt ├── run.py └── server.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask stuff: 57 | instance/ 58 | .webassets-cache 59 | 60 | # Scrapy stuff: 61 | .scrapy 62 | 63 | # Sphinx documentation 64 | docs/_build/ 65 | 66 | # PyBuilder 67 | target/ 68 | 69 | # IPython Notebook 70 | .ipynb_checkpoints 71 | 72 | # pyenv 73 | .python-version 74 | 75 | # celery beat schedule file 76 | celerybeat-schedule 77 | 78 | # dotenv 79 | .env 80 | 81 | # virtualenv 82 | venv/ 83 | ENV/ 84 | 85 | # Spyder project settings 86 | .spyderproject 87 | 88 | # Rope project settings 89 | .ropeproject 90 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Jackie Kazil 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | *Note: This is an example repo to demostrate a stand alone model, outside of the Mesa code base.* 2 | 3 | # Schelling Segregation Model 4 | 5 | ## Summary 6 | 7 | The Schelling segregation model is a classic agent-based model, demonstrating how even a mild preference for similar neighbors can lead to a much higher degree of segregation than we would intuitively expect. The model consists of agents on a square grid, where each grid cell can contain at most one agent. Agents come in two colors: red and blue. They are happy if a certain number of their eight possible neighbors are of the same color, and unhappy otherwise. Unhappy agents will pick a random empty cell to move to each step, until they are happy. The model keeps running until there are no unhappy agents. 8 | 9 | By default, the number of similar neighbors the agents need to be happy is set to 3. That means the agents would be perfectly happy with a majority of their neighbors being of a different color (e.g. a Blue agent would be happy with five Red neighbors and three Blue ones). Despite this, the model consistently leads to a high degree of segregation, with most agents ending up with no neighbors of a different color. 10 | 11 | ## Installation 12 | 13 | To install the dependencies use pip and the requirements.txt in this directory. e.g. 14 | 15 | ``` 16 | $ pip install -r requirements.txt 17 | ``` 18 | 19 | ## How to Run 20 | 21 | To run the model interactively, run ``run.py`` in this directory. e.g. 22 | 23 | ``` 24 | $ python run.py 25 | ``` 26 | 27 | Then open your browser to [http://127.0.0.1:8888/](http://127.0.0.1:8888/) and press Reset, then Run. 28 | 29 | To view and run some example model analyses, launch the IPython Notebook and open ``analysis.ipynb``. Visualizing the analysis also requires [matplotlib](http://matplotlib.org/). 30 | 31 | ## Files 32 | 33 | * ``run.py``: Launches a model visualization server. 34 | * ``schelling.py``: Contains the agent class, and the overall model class. 35 | * ``server.py``: Defines classes for visualizing the model in the browser via Mesa's modular server, and instantiates a visualization server. 36 | * ``analysis.ipybn``: Notebook demonstrating how to run experiments and parameter sweeps on the model. 37 | 38 | ## Further Reading 39 | 40 | Schelling's original paper describing the model: 41 | 42 | * [Schelling, Thomas C. Dynamic Models of Segregation. Journal of Mathematical Sociology. 1971, Vol. 1, pp 143-186.](https://www.stat.berkeley.edu/~aldous/157/Papers/Schelling_Seg_Models.pdf) 43 | 44 | An interactive, browser-based explanation and implementation: 45 | 46 | * [Parable of the Polygons](http://ncase.me/polygons/), by Vi Hart and Nicky Case. 47 | -------------------------------------------------------------------------------- /analysis.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Schelling Segregation Model\n", 8 | "\n", 9 | "## Background\n", 10 | "\n", 11 | "The Schelling (1971) segregation model is a classic of agent-based modeling, demonstrating how agents following simple rules lead to the emergence of qualitatively different macro-level outcomes. Agents are randomly placed on a grid. There are two types of agents, one constituting the majority and the other the minority. All agents want a certain number (generally, 3) of their 8 surrounding neighbors to be of the same type in order for them to be happy. Unhappy agents will move to a random available grid space. While individual agents do not have a preference for a segregated outcome (e.g. they would be happy with 3 similar neighbors and 5 different ones), the aggregate outcome is nevertheless heavily segregated.\n", 12 | "\n", 13 | "## Implementation\n", 14 | "\n", 15 | "This is a demonstration of running a Mesa model in an IPython Notebook. The actual model and agent code are implemented in Schelling.py, in the same directory as this notebook. Below, we will import the model class, instantiate it, run it, and plot the time series of the number of happy agents." 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": 13, 21 | "metadata": { 22 | "collapsed": false 23 | }, 24 | "outputs": [], 25 | "source": [ 26 | "import matplotlib.pyplot as plt\n", 27 | "%matplotlib inline\n", 28 | "\n", 29 | "from model import SchellingModel" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": {}, 35 | "source": [ 36 | "Now we instantiate a model instance: a 10x10 grid, with an 80% chance of an agent being placed in each cell, approximately 20% of agents set as minorities, and agents wanting at least 3 similar neighbors." 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": 14, 42 | "metadata": { 43 | "collapsed": false 44 | }, 45 | "outputs": [], 46 | "source": [ 47 | "model = SchellingModel(10, 10, 0.8, 0.2, 3)" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "metadata": {}, 53 | "source": [ 54 | "We want to run the model until all the agents are happy with where they are. However, there's no guarentee that a given model instantiation will *ever* settle down. So let's run it for either 100 steps or until it stops on its own, whichever comes first:" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 15, 60 | "metadata": { 61 | "collapsed": false 62 | }, 63 | "outputs": [ 64 | { 65 | "name": "stdout", 66 | "output_type": "stream", 67 | "text": [ 68 | "46\n" 69 | ] 70 | } 71 | ], 72 | "source": [ 73 | "while model.running and model.schedule.steps < 100:\n", 74 | " model.step()\n", 75 | "print(model.schedule.steps) # Show how many steps have actually run" 76 | ] 77 | }, 78 | { 79 | "cell_type": "markdown", 80 | "metadata": {}, 81 | "source": [ 82 | "The model has a DataCollector object, which checks and stores how many agents are happy at the end of each step. It can also generate a pandas DataFrame of the data it has collected:" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": 16, 88 | "metadata": { 89 | "collapsed": false 90 | }, 91 | "outputs": [], 92 | "source": [ 93 | "model_out = model.datacollector.get_model_vars_dataframe()" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": 17, 99 | "metadata": { 100 | "collapsed": false 101 | }, 102 | "outputs": [ 103 | { 104 | "data": { 105 | "text/html": [ 106 | "
\n", 107 | "\n", 108 | " \n", 109 | " \n", 110 | " \n", 111 | " \n", 112 | " \n", 113 | " \n", 114 | " \n", 115 | " \n", 116 | " \n", 117 | " \n", 118 | " \n", 119 | " \n", 120 | " \n", 121 | " \n", 122 | " \n", 123 | " \n", 124 | " \n", 125 | " \n", 126 | " \n", 127 | " \n", 128 | " \n", 129 | " \n", 130 | " \n", 131 | " \n", 132 | " \n", 133 | " \n", 134 | " \n", 135 | " \n", 136 | "
happy
059
162
264
364
466
\n", 137 | "
" 138 | ], 139 | "text/plain": [ 140 | " happy\n", 141 | "0 59\n", 142 | "1 62\n", 143 | "2 64\n", 144 | "3 64\n", 145 | "4 66" 146 | ] 147 | }, 148 | "execution_count": 17, 149 | "metadata": {}, 150 | "output_type": "execute_result" 151 | } 152 | ], 153 | "source": [ 154 | "model_out.head()" 155 | ] 156 | }, 157 | { 158 | "cell_type": "markdown", 159 | "metadata": {}, 160 | "source": [ 161 | "Finally, we can plot the 'happy' series:" 162 | ] 163 | }, 164 | { 165 | "cell_type": "code", 166 | "execution_count": 18, 167 | "metadata": { 168 | "collapsed": false 169 | }, 170 | "outputs": [ 171 | { 172 | "data": { 173 | "text/plain": [ 174 | "" 175 | ] 176 | }, 177 | "execution_count": 18, 178 | "metadata": {}, 179 | "output_type": "execute_result" 180 | }, 181 | { 182 | "data": { 183 | "image/png": "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\n", 184 | "text/plain": [ 185 | "" 186 | ] 187 | }, 188 | "metadata": {}, 189 | "output_type": "display_data" 190 | } 191 | ], 192 | "source": [ 193 | "model_out.happy.plot()" 194 | ] 195 | }, 196 | { 197 | "cell_type": "markdown", 198 | "metadata": {}, 199 | "source": [ 200 | "For testing purposes, here is a table giving each agent's x and y values at each step." 201 | ] 202 | }, 203 | { 204 | "cell_type": "code", 205 | "execution_count": 19, 206 | "metadata": { 207 | "collapsed": false 208 | }, 209 | "outputs": [], 210 | "source": [ 211 | "x_positions = model.datacollector.get_agent_vars_dataframe()" 212 | ] 213 | }, 214 | { 215 | "cell_type": "code", 216 | "execution_count": 20, 217 | "metadata": { 218 | "collapsed": false 219 | }, 220 | "outputs": [ 221 | { 222 | "data": { 223 | "text/html": [ 224 | "
\n", 225 | "\n", 226 | " \n", 227 | " \n", 228 | " \n", 229 | " \n", 230 | " \n", 231 | " \n", 232 | " \n", 233 | " \n", 234 | " \n", 235 | " \n", 236 | " \n", 237 | " \n", 238 | " \n", 239 | " \n", 240 | " \n", 241 | " \n", 242 | " \n", 243 | " \n", 244 | " \n", 245 | " \n", 246 | " \n", 247 | " \n", 248 | " \n", 249 | " \n", 250 | " \n", 251 | " \n", 252 | " \n", 253 | " \n", 254 | " \n", 255 | " \n", 256 | " \n", 257 | " \n", 258 | " \n", 259 | " \n", 260 | " \n", 261 | " \n", 262 | " \n", 263 | " \n", 264 | " \n", 265 | " \n", 266 | " \n", 267 | " \n", 268 | "
xy
StepAgentID
0(0, 0)36
(0, 1)51
(0, 2)13
(0, 5)46
(0, 6)15
\n", 269 | "
" 270 | ], 271 | "text/plain": [ 272 | " x y\n", 273 | "Step AgentID \n", 274 | "0 (0, 0) 3 6\n", 275 | " (0, 1) 5 1\n", 276 | " (0, 2) 1 3\n", 277 | " (0, 5) 4 6\n", 278 | " (0, 6) 1 5" 279 | ] 280 | }, 281 | "execution_count": 20, 282 | "metadata": {}, 283 | "output_type": "execute_result" 284 | } 285 | ], 286 | "source": [ 287 | "x_positions.head()" 288 | ] 289 | }, 290 | { 291 | "cell_type": "markdown", 292 | "metadata": {}, 293 | "source": [ 294 | "# Effect of Homophily on segregation\n", 295 | "\n", 296 | "Now, we can do a parameter sweep to see how segregation changes with homophily.\n", 297 | "\n", 298 | "First, we create a function which takes a model instance and returns what fraction of agents are segregated -- that is, have no neighbors of the opposite type." 299 | ] 300 | }, 301 | { 302 | "cell_type": "code", 303 | "execution_count": 21, 304 | "metadata": { 305 | "collapsed": true 306 | }, 307 | "outputs": [], 308 | "source": [ 309 | "from mesa.batchrunner import BatchRunner" 310 | ] 311 | }, 312 | { 313 | "cell_type": "code", 314 | "execution_count": 22, 315 | "metadata": { 316 | "collapsed": true 317 | }, 318 | "outputs": [], 319 | "source": [ 320 | "def get_segregation(model):\n", 321 | " '''\n", 322 | " Find the % of agents that only have neighbors of their same type.\n", 323 | " '''\n", 324 | " segregated_agents = 0\n", 325 | " for agent in model.schedule.agents:\n", 326 | " segregated = True\n", 327 | " for neighbor in model.grid.neighbor_iter(agent.pos):\n", 328 | " if neighbor.type != agent.type:\n", 329 | " segregated = False\n", 330 | " break\n", 331 | " if segregated:\n", 332 | " segregated_agents += 1\n", 333 | " return segregated_agents / model.schedule.get_agent_count()" 334 | ] 335 | }, 336 | { 337 | "cell_type": "markdown", 338 | "metadata": {}, 339 | "source": [ 340 | "Now, we set up the batch run, with a dictionary of fixed and changing parameters. Let's hold everything fixed except for Homophily." 341 | ] 342 | }, 343 | { 344 | "cell_type": "code", 345 | "execution_count": 23, 346 | "metadata": { 347 | "collapsed": true 348 | }, 349 | "outputs": [], 350 | "source": [ 351 | "parameters = {\"height\": 10, \"width\": 10, \"density\": 0.8, \"minority_pc\": 0.2, \n", 352 | " \"homophily\": range(1,9)}" 353 | ] 354 | }, 355 | { 356 | "cell_type": "code", 357 | "execution_count": 24, 358 | "metadata": { 359 | "collapsed": false 360 | }, 361 | "outputs": [], 362 | "source": [ 363 | "model_reporters = {\"Segregated_Agents\": get_segregation}" 364 | ] 365 | }, 366 | { 367 | "cell_type": "code", 368 | "execution_count": 25, 369 | "metadata": { 370 | "collapsed": true 371 | }, 372 | "outputs": [], 373 | "source": [ 374 | "param_sweep = BatchRunner(SchellingModel, parameters, iterations=10, \n", 375 | " max_steps=200, model_reporters=model_reporters)" 376 | ] 377 | }, 378 | { 379 | "cell_type": "code", 380 | "execution_count": 26, 381 | "metadata": { 382 | "collapsed": false 383 | }, 384 | "outputs": [], 385 | "source": [ 386 | "param_sweep.run_all()" 387 | ] 388 | }, 389 | { 390 | "cell_type": "code", 391 | "execution_count": 27, 392 | "metadata": { 393 | "collapsed": false 394 | }, 395 | "outputs": [], 396 | "source": [ 397 | "df = param_sweep.get_model_vars_dataframe()" 398 | ] 399 | }, 400 | { 401 | "cell_type": "code", 402 | "execution_count": 28, 403 | "metadata": { 404 | "collapsed": false 405 | }, 406 | "outputs": [ 407 | { 408 | "data": { 409 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXwAAAEACAYAAACwB81wAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3X90XHd55/H3o0RCYxtbGKb5YcfSQhJksmUlg1WzSdej\nxL+S0ibg3eMIaC0qEmcT5Qcki0O3e9KzXbqEXUNSjHEcRJIFLJvWJaQttUWCRE4oqYSxk2KkxEkq\nETshGhNsaiNViv3sH3fGGska6SoznvuM9LzO0ZHu6Hru59yRv3Pnud8foqo455yb/kqiDuCcc64w\nvMF3zrkZwht855ybIbzBd865GcIbfOecmyG8wXfOuRkiLw2+iKwRkR4ReV5ENo7z+7eLyD+IyH4R\n+WcRaczHcZ1zzoUnufbDF5ES4HngKuAVoAu4XlV7Mva5ByhX1c+IyDuA54DzVPWNnA7unHMutHxc\n4dcBB1W1T1WHgR3AtWP2+QXw1tTPbwV+6Y29c84V1rl5eI4FwMsZ24cI3gQyPQg8ISKvAHOAdXk4\nrnPOuSko1E3bzwDPqOqFQC3wZRGZU6BjO+ecIz9X+IeBRRnbC1OPZboc+CyAqr4oIv8CVAM/Hvtk\nIuKT+zjn3BSpqky2Tz6u8LuAi0WkUkTKgOuBx8bs0w2sABCR84BLgZeyPaGqmvq65557Is/gmaZP\nJqu5PFPxZgor5yt8VT0pIs1AG8EbSIuqdovIhuDXug3438BDIvIMIMCnVfX1XI9dKL29vVFHOINn\nCsdiJrCZyzOFYzFTWPko6aCqu4F3j3nsgYyfjwC/n49jOeece3N8pG0IjY2NUUc4g2cKx2ImsJnL\nM4VjMVNYOQ+8yjcRUWuZnHPOMhFBC3TTdtrr6OiIOsIZPFM4FjOBzVyeKRyLmcLyBt8552YIL+k4\n51yR85KOc865UbzBD8Fizc4zhWMxE9jM5ZnCsZgpLG/wnXNuhvAavnPOFTmv4TvnnBvFG/wQLNbs\nPFM4FjOBzVyeKRyLmcLyBt8552YIr+E751yR8xq+c865UbzBD8Fizc4zhWMxE9jM5ZnCsZgpLG/w\nnXNuhshLDV9E1gD3MbLi1b1jfn8X8FFAgVJgMfAOVT06znN5Dd8556YgbA0/5wZfREqA54GrgFcI\n1ri9XlV7suz/QeAOVV2R5ffe4Dvn3BQU8qZtHXBQVftUdRjYAVw7wf4NQGsejlswFmt2nmlyyWSS\nrVu3kkwmo45yBmvnCjxTWBYzhZWPBn8B8HLG9qHUY2cQkRiwBtiVh+M6l1Vr604WLbqUT37yL1i0\n6FJaW3dGHcm5yOVlEfMp+H3gqfFq95kaGxupqqoCoKKigpqaGhKJBDDy7lro7bSojl8M24lEwkSe\no0ePsn79DQwPnwuUA79i/fpPsGLFlRw4cCDyfFa3rbx+mdvpx6zksdIepH/u7e1lKvJRw18G/Jmq\nrklt3w3o2Bu3qd/9DfAtVd0xwfN5Dd/lpK2tjdWrPwT8CHgv8CzwAfbs+TarVq2KNpxzZ0Eha/hd\nwMUiUikiZcD1wGPjBJoHLAe+k4djFtTYd3ULPNNkLiRo7DtS3y+INM1Yts5VwDOFYzFTWDmXdFT1\npIg0A22MdMvsFpENwa91W2rX64A9qjqQ6zGdm8hFF10EHCa4sif1/ZXU487NXD6Xjpt2urq6WL58\nHQMDx4CFwCHKy+fy5JPfYunSpVHHcy7vwpZ0Cn3T1rmzLrjhf4ygM9hs4AQia093BHBupvKpFUKw\nWLPzTNnF43FaWrZQXv4hyss/THn5h2hp2UI8Ho862mlWzlUmzxSOxUxheYPvpq1gEPhbUt+dc17D\nd9NOMpmksrKagYF20t0yY7F6+vp6TF3lO5cvPh++m7F6e3spK6siaOwB3ktpaeWUB6k4N914gx+C\nxZqdZ8quqqqKoaFegu6YHcCzDA/3mbppa+VcZfJM4VjMFJY3+G7aSd+0jcXqmTXrBmKxenM3bZ2L\ngtfw3bSVTCbp7e2lqqrKVGNvNZcrXgWbDz/fvMF301lr606amm6mrCwoO7W0bKGhYV3UsVyR85u2\neWSxZueZwrGUKZlM0tR0MwMD7Rw7tomBgXaamm42M1+/pXOV5pnyyxt85wrEew+5qHlJx7kC8fEB\n7mzxko5zxoxM+bCc2bPfTXn5cu895ArKG/wQLNbsPFM4FjOBMDw8BEx6QVZQFs+VZ8ovb/DdtJVM\nJunp6TFzUzSZTNLYuIHBwQ6Ghh5icLCDxsYNZvK56c9r+G5astj9MVh68RbgYMajF7NnzxZfetHl\npKA1fBFZIyI9IvK8iGzMsk9CRPaJyE9FpD0fx3VuPKO7P+411v3xFUavxPVqhFncTJNzgy/B3LOb\ngdXAZUCDiFSP2Wce8GXgg6r674H/kutxC8lizc4zZTe6+2MHVro/1tbWUlpaAiSAS4AEpaUl1NbW\nRporzcrrl8kz5Vc+rvDrgIOq2qeqw8AO4Nox+3wE2KWqhwFU9UgejuvcuEZPngZWJk+Lx+M88shX\nKS9XyssHKS9XHnnkq95LxxVMzjV8EVkLrFbVG1PbHwPqVPW2jH2+CJQSfAKYA/ylqn49y/N5Dd/l\nLF3DLy2tZHi4z0QNP83n0nH5Zm1N23OBJcCVBIuM/khEfqSqL4y3c2Nj4+mrsYqKCmpqakgkEsDI\nxynf9u2Jthsa1rFixZXs2rWL888/n+uuu85UPt/27Vy20z9PuUypqjl9AcuA3RnbdwMbx+yzEbgn\nY/urwNosz6fWtLe3Rx3hDJ4pHIuZVG3m8kzhWMyUajcnba/zUcPvAi4WkUoRKQOuBx4bs893gCtE\n5BwRmQX8DtCdh2M755wLKS/98EVkDXA/wU3gFlX9nIhsIHjX2Zba5y7g48BJ4EFV/VKW59J8ZHLO\nuZnC58N3zrkZwidPy6PMGyVWeKZwLGYCm7k8UzgWM4XlDb6btqzNpeNc1Lyk4/LCWt9yi3PppFk7\nV674eUnHFUxr604qK6tZufImKiuraW3dGWkey3PptLbuZNGiS6mv/0MWLbo08nPlZhZv8EOwWLOz\nksniOq1W59JJJpOsX38Dg4PCiROnGBwU1q//hIk3IrDzN5XJM+WXN/hFqLu7m927d9PdHf1QBovr\ntFqdS2ffvn0MD58keBPaBnQwPHyKffv2RZrLzSBhRmcV8guDI20taW6+XSGmcKlCTJubb4s0T39/\nv8Zi8xWeUVCFZzQWm6/9/f2R5tq+fYfGYvN17txajcXm6/btOyLNo6q6c+dOhXelzlP66126c+fO\nqKO5IkcBR9q6Aunu7mbz5m3A08BzwNNs3vxgpFf66XVaY7F65s5dQixWb2Kd1oaGdfT19fD44w/Q\n19dj4oZtRUUFwfz3o+fDDx537uzzBj8EKzW7zs5O4CIya9OwMPV4dNKN67333mimcYXgzejEiROR\nv/mkjcyHvxx4F7Dc58OfhGfKL2/wi0hdXR3wMqOvEA+lHo9WPB6nurraTONq0ch8+FBePkR5OT4f\n/gR8HEX+eT/8InPrrbezefODwELgEM3NN/ClL90fdSw3Bd4Pf3KWx1FY5HPpTGPd3d10dnZSV1fH\n4sWLo47jXF4lk0kqK6sZGGgnKFs+SyxWT19fj79BZuEDr/LIWs1u8eLFVFZWmmrsk8kkW7duNffx\n29prl2Yxl5VMVsdRpFk5T2+GN/guZ+mRtnfd9QUTI21dcbM6jmI68JKOy4l//J46r+FPzvKaxBZ5\nSccVhMWRtpb5XDrhWBxHAcGbdVdXl7nSZVh5afBFZI2I9IjI8yKycZzfLxeRoyLyk9TXn+bjuIVi\nsWZnJdPoj98dWPv4beU8gc+lM1XWxlGkS5f19R8t2tJlzg2+iJQAm4HVwGVAg4hUj7Prk6q6JPX1\nv3I9bqF4X+CJZY60nTXrBjMjbS3yuXSKV+YkgSdObDMxSeCbkY8r/DrgoKr2qeowsAO4dpz9Jq0v\nWZN+R7/77gfNvaMnEomoI5yW/vjd0bHd1MdvsHWeAhcSlL8Sqe8XRJomk71zZSfT6NJlgmItXeaj\nwV9AMPwz7VDqsbE+ICL7ReTvReQ9eTjuWWV5TnWL4vE4S5cu9Sv7CdTW1lJWliS4wu8COigrO2Jm\nagWX3XTpOXRugY6zF1ikqr8RkauBR4FLs+3c2Nh4+kRWVFRQU1Nz+p0+XWc829uzZ8+mrKyKgYHX\ngfuAOygtrWTXrl1UV1cXPM/Y7fRjUR1/vO2x2aLOA3DfffdF8vcz3nY8Hueaa1bw6KOrgTjwOtdc\nczUHDhwwkc9fv4m3W1q20Nh4BSJvpaRkkJaWLRw4cCCSPOmfp/wJI8yUmhN9AcuA3RnbdwMbJ/k3\n/wLMz/K7fM0YmpPR0/62m5n2N629vT3qCGfwTBPr7+/XsrJ5o/6mysrm+d/UBKxl6u/v16985Stm\nXrM0Qk6PnHM/fBE5h2Cu3qsI5n7tBBpUtTtjn/NU9bXUz3XAt1S1Ksvzaa6Z8sX7Aofnfcsn19bW\nxurVtwAHMx69mD17trBq1aqoYrlpIGw//JxLOqp6UkSagTaCewItqtotIhuCX+s24D+LyH8FhoEB\noChazYaGdaxYcaU3ZJPwia6m4hWCOvB7Sc+H71zBhPkYUMgvjJR0Mln7WKlqJ5OXvsLr7+/X0tI5\nCm9TuFjhbVpaOsfP1QQ8Uzj4ileuEIKbRgvIHGkLFxZdd7VCGJkPXykvH6S8XH0+fFdQPpeOy0l3\ndzfvec/7CJZdTJcplvGzn+01NZunJX6/w+VbwWr4bmY7fvw4sdj5DAzUA5VAH+Xl53H8+PGoo5kV\nj8e9oXeR8JJOCJl9X62wkqmqqoqTJ18HdgE3Ars4depXZgakWDlPY1nM5ZnCsZgpLL/CdzlTPQl8\nGHg78MvUtism6TmjLrvsMv/0MY15Dd/lpKuri5Urb+LYsd1AL1DF3LmrefzxB1i6dGmk2bxWHk5r\n607++I9v4pxzzuPkydf42te2erfaIuPz4buCGJlj5FVgKfCqiTlG0hPfrVx5k7mJ7ywZmbIZTpwo\nZ3AQU1M2u/zyBj8EizU7K5nS0yOXly+nvPwiysuXRz498uiJ7zaZnPjOyus3MmXzDwjmjPqBqSmb\nrZynTBYzheUNvsuLYFmEt6S+R8tX4Qrv6NGjBFM0Z46juCD1uJtuvIbvcmJxTVuLmawK5vf5EPAj\nRsZRfIA9e77t8/sUEa/hu4KweDWduQrX3LlLfBWuCdTW1lJaWkKwqMcSIEFpaYnP0T9NeYMfgsWa\nnZVMVte0Ta/Cde+9N5pbhQvsvH6jp3tImpvuwcp5ymQxU1jeD9/lJH013dRUj2oFIkfNXE3H43Gq\nq6tNZLEsPSvsrl27WLt2rZ+vacxr+C5n3o/buWiFreF7g+9y4jdInYteQW/aisgaEekRkedFZOME\n+y0VkWER+XA+jlsoFmt2VjKNvmnbgYWbtpmsnKexLObyTOFYzBRWzg2+BB2vNwOrgcuABhGpzrLf\n54A9uR7T2TH6pi1YuWnrpiY9l46lwWku//Kxpu0y4B5VvTq1fTfB6iv3jtnvdmCIYPz936nq32R5\nPi/pFBlf+7e4+RKVxa9gNXwRWQusVtUbU9sfA+pU9baMfS4Evqmq9SLyEPC33uBPLz5RWXHyezDT\ng7WBV/cBmbX9SYNZYrFmZy1TPB7nxIkT5hoJa+cpzUouy/dgkskkW7duNVdmsvLavRn56Id/GFiU\nsb0w9Vim9wM7RESAdwBXi8iwqj423hM2NjaergFXVFRQU1NDIpEARk52Ibf3798f6fHH206zksfq\n9v79+03lsfb6HT58mIGBg4zcg2lhcPCF0///osr36quv0dR0M6oxbr/90zz88IM0NKyL/HxZaQ/S\nP0/1jTkfJZ1zgOeAqwjmyO0EGlS1O8v+XtKZhrykU7xuvfV2Nm9+kOBa7RDNzTfwpS/dH1keLzNN\nXcFKOhosb9QMtAEHgB2q2i0iG0TkxvH+Sa7HdLZYnXs+mUzS1dVlriRgSTKZpKXlG8B3gW8C36Wl\n5RuRnjOL8zNNG6pq6iuIZEt7e3vUEc5gJVN/f7/GYvMVnlFoV3hGY7H52t/fH2mu7dt3aCw2X2fP\nvkRjsfm6ffuOSPOMZeX16+zs1Hnzliho6vVTnTu3Vjs7OyPLZPVvKs3Ka5cp1W5O2r765GkuJxav\nxjIXQDlxYpvJBVCssDiOInO201mzbvDZTvMpzLtCIb8weIXvsht9NaYmrsZGX7WqiatWy5qbb1OI\nKVyiENPm5tuijqSqwd9WZ2enmSt7ywh5he9z6bic2b3ptwuYDZwgFlvrN/3GkUwmWbjwEoaGHiV9\nrsrKruPQoYN+roqItX74Rcv7Ak9s9E2/T2Hhpl88Hqep6Q+Ba4APA9fQ1PQxUw2Ylddv3759DA3F\nCRZAOQEkGBp6h69pOwGLmcLyBn8C6d4nd931BVO9TywZqeEngGqCFZOir+G3tHwdeBoIvkf9JmTb\nK2TW8IPe1W468pJOFt4XOByL56mrq4uVK2/i2LG9px+bO3cJjz/+AEuXLo0kk1XJZJIFC97J8HAp\nUAX0Ulo6zOHDL/nfeRHxkk6OLPY+scji+rEWe55YNXqJw381t8ShNcU+tsMb/CyqqqoYGHiRYH6R\nrUAHg4MvmWk0LNURra0fO7pb3yUm3oTGsvT6jfi3qAOcwdJ5Spd46+s/WrQlXl/TdgJvvDFEcOPv\n7cAveeON6EtNVllbP9bXaQ0nPWZhcPAHwOvAfJqa6lmx4ko/Zxkyx3YU83nyK/ws9u3bx6lTQnDj\n72XgaU6dKjHTeyE9mZIl1jLF43Fuuukmk/8hrZyr0aXLBJZKl8lkktmzZ5sonwTnYwGZ5wkuNHGe\npsIb/AldSGYNHy6IMItz+Wf1foe1+ZnmzJnDwMALZJ6ngYEXmTNnTpSxpswb/Cxqa2spK0sSvMAd\nwLOUlR2htrY22mD42ICpsJgJ7OSyeL8js3xy7NgmE1NjHD9+nFjsfKAeuASop7z8PI4fPx5ZpjfD\nG/ws4vE4Dz/8ALFYPeXlTcRi9Tz88AORlwd8bIDLt/RN902b7jRx091iD7ngE88xYBdwJ7ALkV9H\n/kloqrwf/iQszfNusc+7c/lm9e/c8trNYfvhey+dScTjcTON6egbR5B548hKRlecLF3YpMtMTU31\noxrXqHOle35ZOU9vhpd0QrBSbx25cdRBemyApRtHVs5TJouZwFYui/3LrY3tSLO6dnNYeWnwRWSN\niPSIyPMisnGc3/+BiDwjIvtE5McicmU+jjvTHD9+nJKSOQRjAz4LXENJySwTN46SySQ9PT3mbiS7\niVleO8Da2I5pIcwcyhN9EbxpvABUAqXAfqB6zD6zMn7+beCFCZ4v73NFTxdPPfVUat7ykbnnIaZP\nPfVUpLnSq0vNm7fE5OpSLjtfO2B6oIArXtUBB1W1T1WHgR3AtWPeVH6TsTkHOJKH4844L7zwAsGc\n85k1/AWpx6MxugvdXlNXiG5yVvvhQ/HPW2NRPhr8BQRDUdMOpR4bRUSuE5FugonTb8vDcQvGSr21\nrq6O4PSOjA2Aw6nHozG6C10HFrrQZbLy2o1lJZfFfvhg875CmpXX7s0o2E1bVX1UVRcDv08wSbmb\nosWLF7NqVQJYBnwUWMaqVQkWL14cWSbLV4gunIaGdezd+xS33rqWvXufivwGqeX7CsUuH90yDwOL\nMrYXph4bl6o+JSLnisjbVfWX4+3T2Nh4usGoqKigpqbm9Nwj6XfXQm+nRXX8RCJBMpnkiSc6CN6n\n3wqc4Ikn2nn00Ue57rrrIsl34MAB7rzzFjZtCrrQDQ6+wJ133nH6CjHK85XW0dER+d+P5e0nnvg+\nmzZ9mbKyKr74xS18+tN38Od//j8jy9PT00NZWRUDA+lPja+f/tR44MCByM9XpiiP39HRMfVP0mEK\n/RN9AecwctO2jOCm7eIx+7wr4+clwIsTPN9ZuakxHezZs0dh1pibtrN0z549UUfzBaeLlMVF6C1m\nso5C3bRV1ZNAM9AGHAB2qGq3iGwQkRtTu60VkZ+KyE+A+wEbnWpDGvuuHq30hG4dWJrQzWr/ZFuv\n3QgruSzeg7F6XyHNymv3ZuRlpK2q7gbePeaxBzJ+/jzw+XwcayZLT+g2NDRSL7cyoZsrTlbvwfh6\nBmeHz6VTZNLzeZSULOTUqUOm5vNwxcnyHDEunLBz6XiDX4S6u7vp7Oykrq4u0h46bvqwNJeOmzpf\nxDyPLNXsWlt38r73XcEtt3yW973vCu+fPAmLmcBeLr8HE57FTGH5bJlFZLqsq+mci4aXdIpIV1cX\nK1fexLFje08/NnfuEh5//AGWLl0aYTLnXJS8pDMNWe1R4ZwrDt7gh2ClZuf9k6fOYiawmcszhWMx\nU1je4BcZa/OeOHe2+BoL+ec1/CKT7jNdVhaUd7zPtJuOrP6dW+2+6v3wpyGrizs7l08jf+e7gNnA\nCWKxtZH/nVt9EwK/aZtXVmp2Fuc9yWTlPGWymAls5rKSKfh7rgDWEkwDvhbVuZH+nY9e6GdT0U7Z\n7A1+EfFeOm4mmDNnDgMDrwLtwDagncHB15gzZ05kmUYutkqB3UCpqYutsLykU2R83hM33XV1dbF8\neRMDA8+efiwW+21+8IOvRTbeJJlMcv75lZw6BXAR8DIlJcovfvFzE+XUsCUdH2lbZNKzCFq8ceRc\nPgSfWA8TfJJ9b+r7K5F+kj1y5EiqsX/6dKZTp5Zx5MiRovo/6CWdEKzUNtN83pPwLGYCm7msZLI4\n3qSzs5Pgyj5zLYqFqceLhzf4btryftzFq6FhHX19PWzadCd9fT2Rly3r6uqAl8m8fwaHUo8XkTDL\nYk32BawBeoDngY3j/P4jwDOpr6eA357guXJc7Ms51e3bd2gsNl/nzVuisdh83b59R9SRXJFrbr5N\nIaZwiUJMm5tvizrSaYRc4jDnm7YiUpJq6K8CXgG6gOtVtSdjn2VAt6oeE5E1wJ+p6rIsz6e5ZnIz\nm49XcGeL1bUoCtkPvw44qKp9qjoM7ACuzdxBVZ9W1WOpzaeBBXk4bsFYqW1m8kzZWR+vAHbOVSZr\nmZLJJFu3bjVVklu8eDGVlZWmGvupyEeDv4CguJV2iIkb9E8A/5CH4xaE14GLj49XKH6trTuprKzm\nk5/8v1RWVpta6KeYFbRbpojUAx8Hrphov8bGxtP/OSsqKqipqSGRSAAjVyGF2G5t3Ulj4w2Ulp7P\npz7132lp2cIFF5xXsOMX23YikTCTp6VlC01N9YjM5403XqOl5UHi8biZfBa3rbx+R48epbFxA0ND\nTxIs9PMijY0bWLHiSg4cOBB5vkxRHr+jo2PKn1rzUcNfRlCTX5PavpvgBsK9Y/Z7L7ALWKOqL07w\nfCZq+F4HLn5WJ7pyE2tra2P16luAgxmPXsyePVtYtWpVVLFMK2QNvwu4WEQqRaQMuB54bEyYRQSN\n/R9O1NhbYr0OPPZKwwJrmayOVwB75wqsZXqFoCTXkfr+aqRpMtk6T1OTc0lHVU+KSDPQRvAG0qKq\n3SKyIfi1bgP+BzAf2CIiAgyrqukOrF4Hdi4atbW1lJQop04tI2g2XqekRKmtrY06WtHzuXQmsHr1\nNbS1dRDcgz7MqlUJ9uz5bsSpnJvekskkCxdewtDQo6SnRy4ru45Dhw6a/LRmgc+lk6Pu7u5UY/9d\n0n90bW3X0N3dXbRdspwrBr29vcRi72JoKHH6sfLyd9Lb2+sNfo58aoUsRubOSAAnUt/tzJ1hsY7o\nmcKzmMtKpqqqKgYGXiSzhj84+JKZcqqV8/RmeIOfxbSZO8O5IqR6kuAi6wYgkdqOXtGPywkz/0Ih\nvzA0l47luTOcm646Ozt13rwlCv0KnQr9OndurXZ2dkaay/L8TBRqLp18s3TTFuCHP/whbW1trFq1\nissvvzzqOM5NexbHwFjMlMnXtM2D1tadrFjxQT7/+YdYseKDpoZ3W6wjeqbwLOayksnifPjB+JsF\njJ4P/0Iz43LC8gY/i2Qyyfr1NzA4KAwOljM4KKxf/4nird05V0SszYcfrLP7Apn39AYGXox0nd03\nw0s6WQTDuz8E/IiRZdY+wJ493/bh3c7NMME6u+sYGDgGVAJ9lJfP5cknvxXZOruZvB9+XlxI0NiT\n+n5BhFmcc1EJuoQeI5ghJhiXI7LWTFfRsLykk0VtbS1lZUky+wKXlR0xM7zbSr01k2cKz2Iuz5Td\nyH2Ftcya9RFisbWR31d4M/wKP4t4PM7DDz9AU1M9qhWIHKWl5YGie4Gdc/nR0LCOFSuuZNeuXaxd\nu7Yo2wKv4U/Cp9h1zlkXtobvDb5zzhU574efR1bqiJk8UzgWM4HNXJ4pHIuZwvIG3znnZggv6Tjn\nXEhW7+kVtKQjImtEpEdEnheRjeP8/t0i8o8iMigin8rHMZ1zrpBaW3dSWVnNypU3UVlZbWqqlbBy\nbvBFpATYDKwGLgMaRKR6zG6/BG4F/k+ux4uCxZqdZwrHYiawmcszZZdMJmlqupmBgXaOHdvEwEA7\nTU03F91UK/m4wq8DDqpqn6oOAzuAazN3UNUjqroXeCMPx3POuYLq7e2lrKyKzJH3paWVRTd5Ws41\nfBFZC6xW1RtT2x8D6lT1tnH2vQf4V1X9wgTP5zV855wp02V6ZJMjbRsbG0/PUVFRUUFNTQ2JRAIY\n+Yjn277t275dyO2Wli00Nl7Bueeeh+rrtLRs4cCBA5HkSf885U8YYVZJmegLWAbszti+G9iYZd97\ngE9N8nw5rPtydrS3t0cd4QyeKRyLmVRt5vJMk+vv79evfOUr2t/fH3WUUQi54lU+avhdwMUiUiki\nZcD1wGMT7D/pxw7nnLMoHo9TXV1toozzZuSlH76IrAHuJ7gJ3KKqnxORDQTvOttE5Dzgx8BbgVPA\nceA9qnp8nOfSfGRyzrmZwufSyROrAy2ccy7N59LJg/RAi/r6j5obaJF588YKzxSexVyeKRyLmcIy\n2UvHgsyBFvA6MJ+mpnpWrLjSr/Sdc0XJSzpZdHV1sXLlTRw7tvf0Y3PnLuHxxx8wsYalc86leUkn\nR1VVVQziFsdMAAAIF0lEQVQN9ZK5Sv3wcF/RrWHpnHNp3uBnMbKGZT2zZl1CLFZvag1Li3VEzxSe\nxVyeKRyLmcLyGv4EpsMals45l+Y1fOecK3Jew3fOOTeKN/ghWKzZeaZwLGYCm7k80+SSySRbt24t\nunnw07zBd865ENIDMe+66wvmBmKG5TV855ybxHSZD9+v8J1zbhLTZcUrb/BDsFZHBM8UlsVMYDOX\nZ8pu9EDMDop1IKY3+M45N4nRAzFvMDcQMyyv4TvnXEhWp0v3+fCdc26GKOhNWxFZIyI9IvK8iGzM\nss9fishBEdkvIjX5OG6hWKkjZvJM4VjMBDZzeaZwLGYKK+cGX0RKgM3AauAyoEFEqsfsczXwLlW9\nBNgAbM31uM4556Ym55KOiCwD7lHVq1PbdxOsZXtvxj5bgXZV3Zna7gYSqvraOM/nJR3nnJuCQpZ0\nFgAvZ2wfSj020T6Hx9nHOefcWWRyeuTGxsbT/VsrKiqoqakhkUgAI/WzQm7v37+fO+64I7Ljj7ed\nfsxKnswsVvIA3HfffZH//Yy3nX7MSh5//cJvW2gP0j9PeeCXqub0BSwDdmds3w1sHLPPVmBdxnYP\ncF6W51Nr2tvbo45wBs8UjsVMqjZzeaZwLGZKtZuTttf5qOGfAzwHXAW8CnQCDaranbHPNcAtqvp7\nqZr/faq6LMvzaa6ZnHNuJglbw8+5pKOqJ0WkGWgjuCfQoqrdIrIh+LVuU9Xvisg1IvICcAL4eK7H\ndc45NzV56YevqrtV9d2qeomqfi712AOqui1jn2ZVvVhV/4Oq/iQfxy2UzLqZFZ4pHIuZwGYuzxSO\nxUxh+Vw6zjk3Q/jUCs45V+R8PnznnHOjeIMfgsWanWcKx2ImsJnLM4VjMVNY3uA759wM4TV855wr\ncl7Dd845N4o3+CFYrNl5pnAsZgKbuTxTOBYzheUNvnPOzRBew3fOuSLnNXznnHOjeIMfgsWanWcK\nx2ImsJnLM4VjMVNY3uA759wM4TV855wrcl7Dd845N0pODb6IvE1E2kTkORHZIyLzsuzXIiKviciz\nuRwvKhZrdp4pHIuZwGYuzxSOxUxh5XqFfzfwuKq+G/g+8Jks+z0ErM7xWJHZv39/1BHO4JnCsZgJ\nbObyTOFYzBRWrg3+tcAjqZ8fAa4bbydVfQr4VY7HiszRo0ejjnAGzxSOxUxgM5dnCsdiprBybfB/\nS1VfA1DVXwC/lXsk55xzZ8Oki5iLyPeA8zIfAhT403F2n5bda3p7e6OOcAbPFI7FTGAzl2cKx2Km\nsHLqliki3UBCVV8TkfOBdlVdnGXfSuBvVfW9kzzntHzTcM65sylMt8xJr/An8RjQCNwLrAe+M8G+\nkvqaUJjQzjnnpi7XGv69wEoReQ64CvgcgIhcICJ/l95JRLYD/whcKiI/F5GP53hc55xzU2RupK1z\nzrmzw8xIWxFZIyI9IvK8iGyMOg/YHDAmIgtF5PsickBE/llEbjOQ6S0i8k8isi+V6y+izpQmIiUi\n8hMReSzqLAAi0isiz6TOVWfUeQBEZJ6I/JWIdKdev98xkOnS1Dn6Ser7MSN/659JnaNnReSbIlJm\nINPtqbZg8vZAVSP/InjjeQGoBEqB/UC1gVxXADXAs1Fnych0PlCT+nkO8JyRczUr9f0c4Gng8qgz\npfJ8EvgG8FjUWVJ5XgLeFnWOMZkeBj6e+vlcYG7UmcbkKwFeAS6KOEdl6vUrS23vBP4o4kyXAc8C\nb0n932sD3pltfytX+HXAQVXtU9VhYAfBoK5IqcEBY6r6C1Xdn/r5ONANLIg2Fajqb1I/voXgP2jk\n501EFgLXAF+NOksGwdYn67nA76rqQwCq+oaq/jriWGOtAF5U1ZcjzvFrYAiYLSLnArMI3oiitBj4\nJ1X9N1U9CTwJfDjbzlb+8BYAmS/mIQw0YtaJSBXBJ5B/ijbJ6dLJPuAXQIeq/izqTMAXgf+GrfEh\nCnxPRLpE5IaowwD/DjgiIg+lyifbRCQWdagx1gGtUYdQ1V8Bm4CfA4eBo6r6eLSp+Cnwu6l5zWYR\nXOBclG1nKw2+myIRmQP8NXB76ko/Uqp6SlVrgYXAfxKR5VHmEZHfA15LfRoK1SW4QC5X1SUE/zFv\nEZErIs5zLrAE+HIq128I5sgyQURKgT8A/spAlncSlAgrgQuBOSLykSgzqWoPQW/J7wHfBfYBJ7Pt\nb6XBPwwsythemHrMjSP1cfKvga+r6kRjHwouVQ74e+D9EUe5HPgDEXmJ4OqwXkT+X8SZUNVXU9+T\nwLcJyplROgS8rKo/Tm3/NcEbgBVXA3tT5ytq7wd+qKqvp8onfwP8x4gzoaoPqer7VTUBHAWez7av\nlQa/C7hYRCpTd72vJxjUZYGlq8O0rwE/U9X7ow4CICLvSE+NnSoHrCS48R4ZVf0TVV2kqu8k+Hv6\nvqr+UZSZRGRW6pMZIjIbWEXwkTwyGsyF9bKIXJp66CrAQjkurQED5ZyU54BlIlIuIkJwrrojzoSI\nxFPfFwEfArZn2zfXkbZ5oaonRaSZ4A5zCdCiqhZO5HYgAbxdRH4O3JO+uRVhpsuBjwL/nKqZK/An\nqro7wlgXAI+k/hOUEHzyeCLCPFadB3w7NX3IucA3VbUt4kwAtwHfTJVPXgJMDIxM1aRXADdGnQVA\nVZ9JfUrcS1A22QdsizYVALtEZD4wDNw80U13H3jlnHMzhJWSjnPOubPMG3znnJshvMF3zrkZwht8\n55ybIbzBd865GcIbfOecmyG8wXfOuRnCG3znnJsh/j+rO70lfHv5MAAAAABJRU5ErkJggg==\n", 410 | "text/plain": [ 411 | "" 412 | ] 413 | }, 414 | "metadata": {}, 415 | "output_type": "display_data" 416 | } 417 | ], 418 | "source": [ 419 | "plt.scatter(df.homophily, df.Segregated_Agents)\n", 420 | "plt.grid(True)" 421 | ] 422 | }, 423 | { 424 | "cell_type": "code", 425 | "execution_count": null, 426 | "metadata": { 427 | "collapsed": true 428 | }, 429 | "outputs": [], 430 | "source": [] 431 | } 432 | ], 433 | "metadata": { 434 | "kernelspec": { 435 | "display_name": "Python 3", 436 | "language": "python", 437 | "name": "python3" 438 | }, 439 | "language_info": { 440 | "codemirror_mode": { 441 | "name": "ipython", 442 | "version": 3 443 | }, 444 | "file_extension": ".py", 445 | "mimetype": "text/x-python", 446 | "name": "python", 447 | "nbconvert_exporter": "python", 448 | "pygments_lexer": "ipython3", 449 | "version": "3.5.1" 450 | } 451 | }, 452 | "nbformat": 4, 453 | "nbformat_minor": 0 454 | } 455 | -------------------------------------------------------------------------------- /model.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | from mesa import Model, Agent 4 | from mesa.time import RandomActivation 5 | from mesa.space import SingleGrid 6 | from mesa.datacollection import DataCollector 7 | 8 | 9 | class SchellingAgent(Agent): 10 | ''' 11 | Schelling segregation agent 12 | ''' 13 | def __init__(self, pos, model, agent_type): 14 | ''' 15 | Create a new Schelling agent. 16 | 17 | Args: 18 | unique_id: Unique identifier for the agent. 19 | x, y: Agent initial location. 20 | agent_type: Indicator for the agent's type (minority=1, majority=0) 21 | ''' 22 | super().__init__(pos, model) 23 | self.pos = pos 24 | self.type = agent_type 25 | 26 | def step(self): 27 | similar = 0 28 | neighbors = self.model.grid.neighbor_iter(self.pos) 29 | for neighbor in neighbors: 30 | if neighbor.type == self.type: 31 | similar += 1 32 | 33 | # If unhappy, move: 34 | if similar < self.model.homophily: 35 | self.model.grid.move_to_empty(self) 36 | else: 37 | self.model.happy += 1 38 | 39 | 40 | class SchellingModel(Model): 41 | ''' 42 | Model class for the Schelling segregation model. 43 | ''' 44 | 45 | def __init__(self, height, width, density, minority_pc, homophily): 46 | ''' 47 | ''' 48 | 49 | self.height = height 50 | self.width = width 51 | self.density = density 52 | self.minority_pc = minority_pc 53 | self.homophily = homophily 54 | 55 | self.schedule = RandomActivation(self) 56 | self.grid = SingleGrid(height, width, torus=True) 57 | 58 | self.happy = 0 59 | self.datacollector = DataCollector( 60 | {"happy": lambda m: m.happy}, # Model-level count of happy agents 61 | # For testing purposes, agent's individual x and y 62 | {"x": lambda a: a.pos[0], "y": lambda a: a.pos[1]}) 63 | 64 | self.running = True 65 | 66 | # Set up agents 67 | # We use a grid iterator that returns 68 | # the coordinates of a cell as well as 69 | # its contents. (coord_iter) 70 | for cell in self.grid.coord_iter(): 71 | x = cell[1] 72 | y = cell[2] 73 | if random.random() < self.density: 74 | if random.random() < self.minority_pc: 75 | agent_type = 1 76 | else: 77 | agent_type = 0 78 | 79 | agent = SchellingAgent((x, y), self, agent_type) 80 | self.grid.position_agent(agent, (x, y)) 81 | self.schedule.add(agent) 82 | 83 | def step(self): 84 | ''' 85 | Run one step of the model. If All agents are happy, halt the model. 86 | ''' 87 | self.happy = 0 # Reset counter of happy agents 88 | self.schedule.step() 89 | self.datacollector.collect(self) 90 | if self.happy == self.schedule.get_agent_count(): 91 | self.running = False 92 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | jupyter==1.0.0 2 | Mesa==0.7.6 3 | -------------------------------------------------------------------------------- /run.py: -------------------------------------------------------------------------------- 1 | from server import server 2 | 3 | server.launch() 4 | -------------------------------------------------------------------------------- /server.py: -------------------------------------------------------------------------------- 1 | from mesa.visualization.ModularVisualization import ModularServer 2 | from mesa.visualization.modules import CanvasGrid, ChartModule, TextElement 3 | 4 | from model import SchellingModel 5 | 6 | 7 | class HappyElement(TextElement): 8 | ''' 9 | Display a text count of how many happy agents there are. 10 | ''' 11 | 12 | def render(self, model): 13 | return "Happy agents: " + str(model.happy) 14 | 15 | 16 | def schelling_draw(agent): 17 | ''' 18 | Portrayal Method for canvas 19 | ''' 20 | if agent is None: 21 | return 22 | portrayal = {"Shape": "circle", "r": 0.5, "Filled": "true", "Layer": 0} 23 | 24 | if agent.type == 0: 25 | portrayal["Color"] = "Red" 26 | else: 27 | portrayal["Color"] = "Blue" 28 | return portrayal 29 | 30 | happy_element = HappyElement() 31 | canvas_element = CanvasGrid(schelling_draw, 20, 20, 500, 500) 32 | happy_chart = ChartModule([{"Label": "happy", "Color": "Black"}]) 33 | 34 | server = ModularServer(SchellingModel, 35 | [canvas_element, happy_element, happy_chart], 36 | "Schelling’s Segregation Model", 37 | 20, 20, 0.8, 0.2, 4) 38 | --------------------------------------------------------------------------------