{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Le modèle de ségrégation de Schelling" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "_ARE DYNAMIC - C. Cambier, P. Fournier, A. Guillon, J.-D. Kant, N. Maudet, S. Stinckwich_\n", "\n", "En Décembre 2016 disparaissait Thomas C. Schelling. Economiste, récipiendaire du Prix de la Banque de Suède en sciences économiques en mémoire d’Alfred Nobel (communément appelé et considéré comme le prix Nobel d’économie), il a travaillé sur de nombreux sujets, en particulier l’analyse des conflits.\n", "\n", "Une de ses contributions a permis de mieux comprendre les phénomènes de ségrégation. Plus précisément, le propos de Schelling fut d’étudier la dynamique par laquelle des phénomènes de ségrégation extrêmes peuvent survenir, en dépit de préférences qui peuvent sembler faiblement discriminantes individuellement. Ainsi, même si chaque individu se déclare prêt à accepter une certaine proportion d’invidus « différents » dans son voisinage, le résultat final peut être que la population se regroupe en régions très homogènes.\n", "\n", "![Thomas C. Schelling](http://www.nobelprize.org/nobel_prizes/economic-sciences/laureates/2005/schelling_postcard.jpg)\n", "\n", "Cette étude peut être menée à l’aide de modèles connus sous le nom d’automates cellulaires. Un des automates les plus célèbres est le [jeu de la vie](https://fr.wikipedia.org/wiki/Jeu_de_la_vie), proposé par John Conway en 1970. Il existe de nombreux autres automates cellulaires dont le comportement est relativement bien étudié, et la littérature est riche à ce sujet. Nous recommandons la lecture de l’article [2] de Jean-Paul Delahaye.\n", "\n", "## Modèle linéaire\n", "\n", "Pour illustrer le modèle, prenons un monde _linéaire_ (c’est en fait le premier modèle étudié par Schelling dans son article, à quelques détails près). Le modèle se compose des éléments suivants :\n", "\n", "- les individus sont de deux _types_ (« 0 » et « 1 »), disposés spatialement sur une ligne.\n", "- le _voisinage_ sont les quatre voisins d’une cellule, de chaque côté. Il faut noter que le nombre de voisins peut varier selon la localisation (pour les individus en bout de ligne).\n", "- le _seuil de satisfaction_ : un individu est satisfait si une majorité (faible) de ses voisins est de la même couleur que lui (i.e. il veut au moins autant de voisins de même type que lui que de voisins différents)\n", "- le mode de déplacement : un individu non satisfait va chercher à se déplacer pour trouver un emplacement qui le satisfasse. La règle dans ce cas là est qu’un individu se déplace vers l’emplacement le plus proche qui le satisfait.\n", "- la dynamique des déplacements est simplement de considérer les individus, de gauche à droite. Chaque individu non satisfait se déplace (vers la gauche ou vers la droite) vers la l’emplacement le plus proche qui le satisfait. Il s’insère alors à la localisation visée. Un tour est terminé lorsque tous les agents ont été considérés.\n", "\n", "Partant d’un état initial, le processus est répété jusqu’à équilibre, c’est-à-dire jusqu’à ce que plus aucun individu insatisfait ne puisse se déplacer, ou qu’une situation de blocage soit détectée. Cela peut nécessiter plusieurs tours.\n", "\n", "Pour illustrer le propos, considérons la situation initiale suivante :\n", "\n", "![Linear Model 1](linearmodel1.png)\n", "Les individus non satisfaits sont indiqués en gris dans la table. Le premier individu à se déplacer sera donc le deuxième en partant de la gauche. En effet, son voisinage ne comprend qu’un autre individu 1 (sur 5). Pour trouver une place satisfaisante, il va devoir se déplacer de 6 cases vers la droite. Le nouvel état sera alors (l’individu s’étant déplacé est en gras) :\n", "\n", "![Linear Model 2](linearmodel2.png)\n", "\n", "L’impact de plusieurs paramètres du modèle peut être étudié : (i) le voisinage, (ii) les préférences des individus (le seuil de voisins de leur couleur qui les satisfait), (iii) le ratio entre les deux types d’individus, (iv) la configuration initiale, et (v) les règles de mouvement.\n", "\n", "Les métriques qu’il peut être intéressant d’étudier sont, par exemple, (i) le nombre d’individus satisfaits à l’équilibre, (ii) la taille (moyenne) des regroupements homogènes observés et leur nombre, (iii) la moyenne sur tous les individus de voisins du même type qu’eux, ou encore (iv) le nombre de tours nc ́essaires pour arriver à un état stable.\n", "\n", "## Modèle spatial\n", "\n", "L’extension à un modèle spatial n’est pas complètement triviale. En effet, si toutes les localisations sont occupées, il n’est pas si évident de définir les règles de déplacements (où se déplacent les individus « chassés » de leur localisation ?). Il est alors plus aisé d’introduire alors des localisations non occupées. Dans ce cas, les individus se déplacent vers la localisation inoccupée la plus proche (selon la [distance de Manhattan](https://fr.wikipedia.org/wiki/Distance_de_Manhattan), par exemple), qui satisfait leur seuil de préférence. Une autre solution serait de les faire se déplacer simplement au hasard vers une localisation inoccupée qui les satisfait.\n", "\n", "## Travail demandé\n", "\n", "Dans le cadre de cet ARE, il vous est demandé :\n", "\n", "1. en vous appuyant sur le code qui vous est fourni, de comprendre et d’étudier le modèle linéaire Schelling, et d’essayer de reproduire le plus fidèlement possible les résultats originaux [1];\n", "2. d’analyser le comportement de ce modèle en faisant varier certains paramètres. Pour cela, vous devrez compléter le code afin de pouvoir lancer des simulations (permettant de faire varier automatiquement certaines valeurs de paramètres), et d’afficher des courbes pour visualiser les résultats moyennés sur un nombre suffisant de simulations;\n", "Vous pouvez également essayer de reproduire les résultats de l'article de Schelling ci-dessous.\n", "3. de proposer une version _animée_ du modèle spatial. Vous pourrez vous contenter d’un modèle simple de déplacement aléatoire.\n", "\n", "## Références\n", "- [1] Thomas C. Schelling, [Dynamic Models of Segregation](http://www.stat.berkeley.edu/~aldous/157/Papers/Schelling_Seg_Models.pdf), Journal of Mathematical Sociology (1971) 143-186\n", "- [2] J.-P. Delahaye, [Le royaume du jeu de la vie](http://www.lifl.fr/~jdelahay/dnalor/Jeudelavie.pdf), Pour la Science (2009) 378" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Solution pour modèle linéaire" ] }, { "cell_type": "code", "execution_count": 96, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import numpy as np\n", "import random\n", "import copy\n", "\n", "from matplotlib import pyplot as plt\n", "\n", "# GLOBAL PARAMETERS FOR EXPERIMENTS\n", "neighb = 4 # size of neighbourhood\n", "threshold = 0.5 # threshold of satisfaction\n", "maxIterations = 5 # max number of iteration for convergence\n", "size = 22 # size of the line" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Un état de l'automate cellulaire est représenté sous la forme d'une liste de 0 et de 1. Par exemple:" ] }, { "cell_type": "code", "execution_count": 97, "metadata": { "collapsed": false }, "outputs": [], "source": [ "cells = [0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "La fonction ```str_state``` convertit un automate cellulaire en une chaîne de caractères pour l'afficher à l'écran." ] }, { "cell_type": "code", "execution_count": 98, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def str_state(state):\n", " '''\n", " return the state as a string\n", " '''\n", " result = \"\"\n", " for i in state:\n", " result += str(i)\n", " return result" ] }, { "cell_type": "code", "execution_count": 99, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'0100011010011100111101'" ] }, "execution_count": 99, "metadata": {}, "output_type": "execute_result" } ], "source": [ "str_state(cells)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "La fonction ```hogeneinity_level``` calcule pour l'individu à la position c, le ratio d'individus du même type." ] }, { "cell_type": "code", "execution_count": 100, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def homogeneinity_level(position, state):\n", " '''\n", " for a given individual at position and state\n", " returns the ratio of individuals of same type in neighbourhood\n", " '''\n", " my_color = state[position]\n", " count = 0\n", " nb_neighb = 0\n", " for i in range(1, neighb+1):\n", " if position+i < len(state):\n", " nb_neighb += 1\n", " if state[position+i] == my_color:\n", " count += 1\n", " if position-i >= 0:\n", " nb_neighb += 1\n", " if state[position-i] == my_color:\n", " count += 1\n", " return float(count / nb_neighb)" ] }, { "cell_type": "code", "execution_count": 101, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0.2" ] }, "execution_count": 101, "metadata": {}, "output_type": "execute_result" } ], "source": [ "homogeneinity_level(1,cells)" ] }, { "cell_type": "code", "execution_count": 102, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def is_happy(position, state, verbose = False):\n", " '''\n", " returns whether individual at position is satisfied in a given state\n", " '''\n", " h = homogeneinity_level(position, state)\n", " if verbose:\n", " print(h)\n", " return h >= threshold" ] }, { "cell_type": "code", "execution_count": 103, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 103, "metadata": {}, "output_type": "execute_result" } ], "source": [ "is_happy(1, cells)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Il est également possible d'afficher sous forme de chaine de caractère quels individus sont insatisfaits (notés 'X'). " ] }, { "cell_type": "code", "execution_count": 104, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def str_unhappy(string):\n", " '''\n", " returns the string marking unhappy individuals with a 'X'\n", " '''\n", " result = \"\"\n", " for i in range(len(string)):\n", " if is_happy(i, string):\n", " result += \" \"\n", " else:\n", " result += \"X\"\n", " return result" ] }, { "cell_type": "code", "execution_count": 105, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0100011010011100111101\n", " X XX XXX XX X \n" ] } ], "source": [ "print(str_state(cells))\n", "print(str_unhappy(str_state(cells)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "La fonction ```move_to``` déplace un individu vers une nouvelle position à droite ou à gauche. La priorité est donnée au déplacement à droite." ] }, { "cell_type": "code", "execution_count": 106, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def move_to(c, p, s):\n", " '''\n", " c position initiale\n", " p position où l'on déplace l'agent\n", " moves individual c to position p, shifting other individuals\n", " s state\n", " and returns the resulting list\n", " '''\n", " new_s = copy.copy(s) # new list for result\n", " my_color = new_s[c]\n", " # gives priority to the right move in case of ties\n", " # I didn't find this specification in Schelling's paper\n", " if p > c: # moving to the right\n", " for i in range(c, p):\n", " new_s[i] = s[i+1]\n", " else: # moving to the left\n", "\n", " for i in range(p, c):\n", " new_s[i+1] = s[i]\n", " new_s[p] = my_color\n", " return new_s" ] }, { "cell_type": "code", "execution_count": 107, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Avant le déplacement: 0100011010011100111101\n", "Après le déplacement: 0000110110011100111101\n" ] } ], "source": [ "new_cells = move_to(1, 7, cells)\n", "print(\"Avant le déplacement:\", str_state(cells))\n", "print(\"Après le déplacement:\", str_state(new_cells))" ] }, { "cell_type": "code", "execution_count": 108, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def move_to_nearest_satisfying(c,s,verbose=False):\n", " '''\n", " will move individual c to nearest satisfying location\n", " simulate the move and check whether satisfying\n", " returns a tuple new state, and boolean satisfied\n", " note: very inefficient but simple solution\n", " '''\n", "\n", " move_limit = max(size-c, c)\n", " move_distance = 0\n", " new_s = []\n", " satisfied = False\n", " while move_distance < move_limit and not(satisfied):\n", " move_distance += 1\n", " new_s = copy.copy(s) # used to simulate the move\n", " if c+move_distance < size:\n", " new_s = move_to(c, c+move_distance, new_s)\n", " satisfied = is_happy(c+move_distance, new_s)\n", " if c-move_distance >= 0 and not satisfied: # trying to move left\n", " new_s = copy.copy(s)\n", " new_s = move_to(c, c-move_distance, new_s)\n", " satisfied = is_happy(c-move_distance, new_s)\n", " if verbose and satisfied:\n", " print (c, \" moved to:\", c-move_distance)\n", " return new_s, satisfied" ] }, { "cell_type": "code", "execution_count": 109, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Avant le déplacement: 0100011010011100111101\n", "1 moved to: -5\n", "Après le déplacement: 0000110110011100111101\n" ] } ], "source": [ "print (\"Avant le déplacement:\", str_state(cells))\n", "new_cells, sat = move_to_nearest_satisfying(1, cells,True)\n", "print (\"Après le déplacement:\", str_state(new_cells))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Dynamique\n", "\n", "La dynamique consiste ensuite à répéter les déplacements. Schelling suggère de considérer les individus un par un, en partant de la gauche, et de les faire se déplacer s'ils le peuvent. Un *tour* est terminé lorsque tous les individus ont été considérés, et on peut répéter ainsi les tours. Mais quand s'arrêter avec cette dynamique? \n", "\n", "On pourrait penser différents critères de convergence dans notre cas:\n", "* lorsque tous les individus sont satisfaits. Malheureusement, rien ne garantit que le système puisse parvenir à un état où tous les individus sont satisfaits (cela peut arriver mais c'est plutôt exceptionnel). \n", "* lorsque plus aucun individu ne peut se déplacer. Ce critère est plus pertinent, mais il cache une difficulté: le système ne parvient pas non plus nécessairement dans un état où plus aucun individus ne peut se déplacer. Ce critère seul peut donc mener à des boucles infinies. \n", "* nous emploierons donc un garde-fou, qui consistera à poser un nombre maximal d'itérations. Si le système n'est pas stabilisé selon le critère précédent après ce nombre d'itérations, la dynamique s'arrête. " ] }, { "cell_type": "code", "execution_count": 110, "metadata": { "collapsed": true }, "outputs": [], "source": [ "###############################################################################\n", "# GLOBAL DYNAMICS\n", "###############################################################################\n", "# Note: departs a little bit from Schelling's specification here\n", "# Interesting problem of non convergence here when no maxIterations condition\n", "# the penultimate individual moves to the last position, and so on\n", "\n", "\n", "def dynamics(state, verbose = False, stepwise = False):\n", " '''\n", " departs a little bit from Schelling's specification here\n", " '''\n", " one_has_moved = True\n", " iterations = 0\n", " while one_has_moved and iterations < maxIterations:\n", " one_has_moved = False\n", " for i in range(len(state)):\n", " if not (is_happy(i, state)): # i wants to move\n", " state, moved = move_to_nearest_satisfying(i, state, False)\n", " one_has_moved = moved or one_has_moved\n", " if verbose:\n", " print (\"Tour :\", iterations)\n", " print(str_state(state))\n", " print(str_unhappy(state))\n", " #print(count_unhappy(state))\n", " if stepwise:\n", " input(\"Press Enter to continue...\")\n", " iterations += 1\n", " return state" ] }, { "cell_type": "code", "execution_count": 111, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Tour : 0\n", "0000100000011111111111\n", " X \n", "Tour : 1\n", "0000000000111111111111\n", " \n", "Tour : 2\n", "0000000000111111111111\n", " \n" ] } ], "source": [ "new_cells = dynamics(cells,True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pour cet état initial on a donc une convergence directe. La dynamique s'arrête au tour 2 car plus aucun individu ne souhaite se déplacer. Mais considérons un autre état initial:" ] }, { "cell_type": "code", "execution_count": 112, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Tour : 0\n", "1111000\n", " XX \n", "Tour : 1\n", "1111000\n", " XX \n", "Tour : 2\n", "1111000\n", " XX \n", "Tour : 3\n", "1111000\n", " XX \n", "Tour : 4\n", "1111000\n", " XX \n", "Tour : 5\n", "1111000\n", " XX \n", "Tour : 6\n", "1111000\n", " XX \n", "Tour : 7\n", "1111000\n", " XX \n", "Tour : 8\n", "1111000\n", " XX \n", "Tour : 9\n", "1111000\n", " XX \n", "Tour : 10\n", "1111000\n", " XX \n", "Tour : 11\n", "1111000\n", " XX \n", "Tour : 12\n", "1111000\n", " XX \n", "Tour : 13\n", "1111000\n", " XX \n", "Tour : 14\n", "1111000\n", " XX \n", "Tour : 15\n", "1111000\n", " XX \n", "Tour : 16\n", "1111000\n", " XX \n", "Tour : 17\n", "1111000\n", " XX \n", "Tour : 18\n", "1111000\n", " XX \n", "Tour : 19\n", "1111000\n", " XX \n" ] } ], "source": [ "cells2 = [1,1,1,1,0,0,0]\n", "new_cells2 = dynamics (cells2,True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Cette fois la dynamique s'arrête grâce à la limite sur le nombre d'itérations. Comprenez-vous pourquoi? " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Calculons le nombre moyen de satisfaction pour un automate cellulaire :" ] }, { "cell_type": "code", "execution_count": 113, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Average level of satisfaction\n", "cells = np.random.randint(0, 2, (10))\n", "def average_homogeneity(cells):\n", " avr = 0\n", " for i in range(len(cells)):\n", " avr = avr + homogeneinity_level(i, cells)\n", " return avr/len(cells)" ] }, { "cell_type": "code", "execution_count": 114, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0.48059523809523813" ] }, "execution_count": 114, "metadata": {}, "output_type": "execute_result" } ], "source": [ "average_homogeneity(cells)" ] }, { "cell_type": "code", "execution_count": 115, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def average_cluster_size(cells):\n", " result = []\n", " color = cells[0]\n", " s = 0\n", " for i in range(len(cells)):\n", " if color == cells[i]:\n", " s = s + 1\n", " else:\n", " result.append(s)\n", " color = cells[i]\n", " s = 1\n", " result.append(s)\n", " avr = 0.0\n", " for j in result:\n", " avr = avr + j\n", " return avr/len(result)" ] }, { "cell_type": "code", "execution_count": 116, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "3.5" ] }, "execution_count": 116, "metadata": {}, "output_type": "execute_result" } ], "source": [ "average_cluster_size(cells2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Faisons varier le taux (threshold) de 0 à 1.0 par pas de 0.1 pour étudier la variation de ce paramètre par rapport aux taux global de satisfaction (average_homogeneity). Pour chaque pas, on fait plusieurs simulations (nb_simulations) afin d'avoir des résultats en moyenne. Enfin, on effectue un graphe montrant l'évolution du taux global de satisfaction." ] }, { "cell_type": "code", "execution_count": 121, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "jump = 0.1\n", "t = 0.0\n", "tend = 1.0\n", "result = []\n", "nb_simulations = 20\n", "maxIterations = 20\n", "size = 100\n", "while t < tend:\n", " avr = 0.0\n", " threshold = t\n", " for i in range(nb_simulations):\n", " state = np.random.randint(0, 2, (size))\n", " avr = avr + average_cluster_size(dynamics(state))\n", " result.append(avr/nb_simulations)\n", " t += jump\n", "x = np.linspace(0.0, 1.0, (1.0/jump)+1)\n", "\n", "plt.plot(x, result)\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.0" } }, "nbformat": 4, "nbformat_minor": 0 }