From 1cfe6c46e72cafabaf9745159b2f6db42ba1b965 Mon Sep 17 00:00:00 2001 From: coderbeta1 Date: Sat, 24 Feb 2024 20:20:22 +0530 Subject: [PATCH 1/8] Improve schelling model --- examples/schelling/README.md | 8 ++++++++ examples/schelling/model.py | 19 ++++++++++++++---- examples/schelling/server.py | 37 ++++++++++++++++++++++++++++-------- 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/examples/schelling/README.md b/examples/schelling/README.md index 64cc9c83..5cb080dd 100644 --- a/examples/schelling/README.md +++ b/examples/schelling/README.md @@ -22,6 +22,14 @@ To run the model interactively, run ``mesa runserver`` in this directory. e.g. $ mesa runserver ``` +or + +Directly run the file ``run.py`` in the terminal. e.g. + +``` + $ python run.py +``` + Then open your browser to [http://127.0.0.1:8521/](http://127.0.0.1:8521/) and press Reset, then Run. 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/). diff --git a/examples/schelling/model.py b/examples/schelling/model.py index 2eb148df..1e84a41f 100644 --- a/examples/schelling/model.py +++ b/examples/schelling/model.py @@ -6,7 +6,7 @@ class SchellingAgent(mesa.Agent): Schelling segregation agent """ - def __init__(self, pos, model, agent_type): + def __init__(self, pos, model, agent_type, unique_id): """ Create a new Schelling agent. @@ -16,6 +16,7 @@ def __init__(self, pos, model, agent_type): agent_type: Indicator for the agent's type (minority=1, majority=0) """ super().__init__(pos, model) + self.unique_id = unique_id self.pos = pos self.type = agent_type @@ -38,6 +39,15 @@ class Schelling(mesa.Model): """ def __init__(self, width=20, height=20, density=0.8, minority_pc=0.2, homophily=3): + """ + Create a new Schelling model. + + Args: + width, height: Size of the space. + density: Initial Chance for a cell to populated + minority_pc: Chances for an agent to be in minority class + homophily: Minimum number of agents of same class needed to be happy + """ super().__init__() self.width = width self.height = height @@ -55,6 +65,7 @@ def __init__(self, width=20, height=20, density=0.8, minority_pc=0.2, homophily= {"x": lambda a: a.pos[0], "y": lambda a: a.pos[1]}, ) + agent_id = 0 # Unique ID for each agent # Set up agents # We use a grid iterator that returns # the coordinates of a cell as well as @@ -64,9 +75,10 @@ def __init__(self, width=20, height=20, density=0.8, minority_pc=0.2, homophily= if self.random.random() < self.density: agent_type = 1 if self.random.random() < self.minority_pc else 0 - agent = SchellingAgent((x, y), self, agent_type) + agent = SchellingAgent(pos=(x, y), model=self, agent_type=agent_type, unique_id=agent_id) self.grid.place_agent(agent, (x, y)) self.schedule.add(agent) + agent_id += 1 self.running = True self.datacollector.collect(self) @@ -77,8 +89,7 @@ def step(self): """ self.happy = 0 # Reset counter of happy agents self.schedule.step() - # collect data - self.datacollector.collect(self) + self.datacollector.collect(self) # collect data if self.happy == self.schedule.get_agent_count(): self.running = False diff --git a/examples/schelling/server.py b/examples/schelling/server.py index 1396e9c7..f318952c 100644 --- a/examples/schelling/server.py +++ b/examples/schelling/server.py @@ -26,20 +26,41 @@ def schelling_draw(agent): return portrayal -canvas_element = mesa.visualization.CanvasGrid(schelling_draw, 20, 20, 500, 500) +canvas_element = mesa.visualization.CanvasGrid( + portrayal_method=schelling_draw, + grid_width=20, + grid_height=20, + canvas_width=500, + canvas_height=500, + ) happy_chart = mesa.visualization.ChartModule([{"Label": "happy", "Color": "Black"}]) model_params = { "height": 20, "width": 20, - "density": mesa.visualization.Slider("Agent density", 0.8, 0.1, 1.0, 0.1), - "minority_pc": mesa.visualization.Slider("Fraction minority", 0.2, 0.00, 1.0, 0.05), - "homophily": mesa.visualization.Slider("Homophily", 3, 0, 8, 1), + "density": mesa.visualization.Slider( + name="Agent density", + value=0.8, + min_value=0.1, + max_value=1.0, + step=0.1), + "minority_pc": mesa.visualization.Slider( + name="Fraction minority", + value=0.2, + min_value=0.00, + max_value=1.0, + step=0.05), + "homophily": mesa.visualization.Slider( + name="Homophily", + value=3, + min_value=0, + max_value=8, + step=1), } server = mesa.visualization.ModularServer( - Schelling, - [canvas_element, get_happy_agents, happy_chart], - "Schelling", - model_params, + model_cls=Schelling, + visualization_elements=[canvas_element, get_happy_agents, happy_chart], + name="Schelling Segregation Model", + model_params=model_params, ) From 0bd7dbddfbf9ae1b8481a7d94b2eb8f6d54ca967 Mon Sep 17 00:00:00 2001 From: Achal Jain Date: Sat, 24 Feb 2024 20:27:52 +0530 Subject: [PATCH 2/8] Update server.py --- examples/schelling/server.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/schelling/server.py b/examples/schelling/server.py index f318952c..35a775db 100644 --- a/examples/schelling/server.py +++ b/examples/schelling/server.py @@ -29,7 +29,7 @@ def schelling_draw(agent): canvas_element = mesa.visualization.CanvasGrid( portrayal_method=schelling_draw, grid_width=20, - grid_height=20, + grid_height=20, canvas_width=500, canvas_height=500, ) @@ -42,7 +42,7 @@ def schelling_draw(agent): name="Agent density", value=0.8, min_value=0.1, - max_value=1.0, + max_value=1.0, step=0.1), "minority_pc": mesa.visualization.Slider( name="Fraction minority", From 4e1fa676b4e27147743e03b3dc3a1da2efbb1a07 Mon Sep 17 00:00:00 2001 From: Achal Jain Date: Sat, 24 Feb 2024 23:14:39 +0530 Subject: [PATCH 3/8] Update model.py --- examples/schelling/model.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/schelling/model.py b/examples/schelling/model.py index 1e84a41f..57a4fcfd 100644 --- a/examples/schelling/model.py +++ b/examples/schelling/model.py @@ -15,8 +15,7 @@ def __init__(self, pos, model, agent_type, unique_id): x, y: Agent initial location. agent_type: Indicator for the agent's type (minority=1, majority=0) """ - super().__init__(pos, model) - self.unique_id = unique_id + super().__init__(unique_id, model) self.pos = pos self.type = agent_type From 4426e4e7c5f20d5c74c1cfe779eb2726d2e89470 Mon Sep 17 00:00:00 2001 From: Achal Jain Date: Sun, 25 Feb 2024 17:51:03 +0530 Subject: [PATCH 4/8] Update model.py --- examples/schelling/model.py | 39 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/examples/schelling/model.py b/examples/schelling/model.py index 57a4fcfd..3b005bc2 100644 --- a/examples/schelling/model.py +++ b/examples/schelling/model.py @@ -6,7 +6,7 @@ class SchellingAgent(mesa.Agent): Schelling segregation agent """ - def __init__(self, pos, model, agent_type, unique_id): + def __init__(self, unique_id, model, agent_type): """ Create a new Schelling agent. @@ -16,12 +16,13 @@ def __init__(self, pos, model, agent_type, unique_id): agent_type: Indicator for the agent's type (minority=1, majority=0) """ super().__init__(unique_id, model) - self.pos = pos self.type = agent_type def step(self): similar = 0 - for neighbor in self.model.grid.iter_neighbors(self.pos, True): + for neighbor in self.model.grid.iter_neighbors( + self.pos, moore=True, radius=self.model.radius + ): if neighbor.type == self.type: similar += 1 @@ -37,7 +38,7 @@ class Schelling(mesa.Model): Model class for the Schelling segregation model. """ - def __init__(self, width=20, height=20, density=0.8, minority_pc=0.2, homophily=3): + def __init__(self, height, width, homophily, radius, density, minority_pc=0.5, seed=None): """ Create a new Schelling model. @@ -46,49 +47,47 @@ def __init__(self, width=20, height=20, density=0.8, minority_pc=0.2, homophily= density: Initial Chance for a cell to populated minority_pc: Chances for an agent to be in minority class homophily: Minimum number of agents of same class needed to be happy + radius: Search radius for checking similarity + seed: Seed for Reproducibility """ - super().__init__() - self.width = width + + super().__init__(seed=seed) self.height = height + self.width = width self.density = density self.minority_pc = minority_pc self.homophily = homophily + self.radius = radius self.schedule = mesa.time.RandomActivation(self) - self.grid = mesa.space.SingleGrid(width, height, torus=True) + self.grid = mesa.space.SingleGrid(height, width, torus=True) self.happy = 0 self.datacollector = mesa.DataCollector( - {"happy": "happy"}, # Model-level count of happy agents - # For testing purposes, agent's individual x and y - {"x": lambda a: a.pos[0], "y": lambda a: a.pos[1]}, + model_reporters={"happy": "happy"}, # Model-level count of happy agents ) - agent_id = 0 # Unique ID for each agent # Set up agents # We use a grid iterator that returns # the coordinates of a cell as well as # its contents. (coord_iter) - for cell in self.grid.coord_iter(): - x, y = cell[1] + for _cont, pos in self.grid.coord_iter(): if self.random.random() < self.density: agent_type = 1 if self.random.random() < self.minority_pc else 0 - - agent = SchellingAgent(pos=(x, y), model=self, agent_type=agent_type, unique_id=agent_id) - self.grid.place_agent(agent, (x, y)) + agent = SchellingAgent(self.next_id(), self, agent_type) + self.grid.place_agent(agent, pos) self.schedule.add(agent) - agent_id += 1 - self.running = True self.datacollector.collect(self) def step(self): """ - Run one step of the model. If All agents are happy, halt the model. + Run one step of the model. """ self.happy = 0 # Reset counter of happy agents self.schedule.step() - self.datacollector.collect(self) # collect data + self.datacollector.collect(self) + if self.happy == self.schedule.get_agent_count(): self.running = False From 746268bfa2651d6dea24f6ec6dc2b0e2718810c0 Mon Sep 17 00:00:00 2001 From: Achal Jain Date: Sun, 25 Feb 2024 17:51:31 +0530 Subject: [PATCH 5/8] Update server.py --- examples/schelling/server.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/examples/schelling/server.py b/examples/schelling/server.py index 35a775db..44832b7d 100644 --- a/examples/schelling/server.py +++ b/examples/schelling/server.py @@ -29,7 +29,7 @@ def schelling_draw(agent): canvas_element = mesa.visualization.CanvasGrid( portrayal_method=schelling_draw, grid_width=20, - grid_height=20, + grid_height=20, canvas_width=500, canvas_height=500, ) @@ -42,7 +42,7 @@ def schelling_draw(agent): name="Agent density", value=0.8, min_value=0.1, - max_value=1.0, + max_value=1.0, step=0.1), "minority_pc": mesa.visualization.Slider( name="Fraction minority", @@ -56,6 +56,12 @@ def schelling_draw(agent): min_value=0, max_value=8, step=1), + "radius": mesa.visualization.Slider( + name="Search Radius", + value=1, + min_value=1, + max_value=5, + step=1), } server = mesa.visualization.ModularServer( From de690631b8e8e95006f17146893ac4a7c2e50a09 Mon Sep 17 00:00:00 2001 From: Achal Jain Date: Sun, 25 Feb 2024 18:42:58 +0530 Subject: [PATCH 6/8] Update model.py --- examples/schelling/model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/schelling/model.py b/examples/schelling/model.py index 3b005bc2..3c49ab1d 100644 --- a/examples/schelling/model.py +++ b/examples/schelling/model.py @@ -38,7 +38,7 @@ class Schelling(mesa.Model): Model class for the Schelling segregation model. """ - def __init__(self, height, width, homophily, radius, density, minority_pc=0.5, seed=None): + def __init__(self, height=20, width=20, homophily=3, radius=1, density=0.8, minority_pc=0.2, seed=None): """ Create a new Schelling model. From dc5cff8a34a73d4d4af7660d5e21c92f146685a2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 25 Feb 2024 15:18:05 +0000 Subject: [PATCH 7/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- examples/schelling/README.md | 2 +- examples/schelling/model.py | 15 ++++++++++++--- examples/schelling/server.py | 32 ++++++++++---------------------- 3 files changed, 23 insertions(+), 26 deletions(-) diff --git a/examples/schelling/README.md b/examples/schelling/README.md index 5cb080dd..fe8971f6 100644 --- a/examples/schelling/README.md +++ b/examples/schelling/README.md @@ -22,7 +22,7 @@ To run the model interactively, run ``mesa runserver`` in this directory. e.g. $ mesa runserver ``` -or +or Directly run the file ``run.py`` in the terminal. e.g. diff --git a/examples/schelling/model.py b/examples/schelling/model.py index 3c49ab1d..ffbf361c 100644 --- a/examples/schelling/model.py +++ b/examples/schelling/model.py @@ -38,7 +38,16 @@ class Schelling(mesa.Model): Model class for the Schelling segregation model. """ - def __init__(self, height=20, width=20, homophily=3, radius=1, density=0.8, minority_pc=0.2, seed=None): + def __init__( + self, + height=20, + width=20, + homophily=3, + radius=1, + density=0.8, + minority_pc=0.2, + seed=None, + ): """ Create a new Schelling model. @@ -50,7 +59,7 @@ def __init__(self, height=20, width=20, homophily=3, radius=1, density=0.8, mino radius: Search radius for checking similarity seed: Seed for Reproducibility """ - + super().__init__(seed=seed) self.height = height self.width = width @@ -88,6 +97,6 @@ def step(self): self.schedule.step() self.datacollector.collect(self) - + if self.happy == self.schedule.get_agent_count(): self.running = False diff --git a/examples/schelling/server.py b/examples/schelling/server.py index 44832b7d..1f0d5f92 100644 --- a/examples/schelling/server.py +++ b/examples/schelling/server.py @@ -29,39 +29,27 @@ def schelling_draw(agent): canvas_element = mesa.visualization.CanvasGrid( portrayal_method=schelling_draw, grid_width=20, - grid_height=20, + grid_height=20, canvas_width=500, canvas_height=500, - ) +) happy_chart = mesa.visualization.ChartModule([{"Label": "happy", "Color": "Black"}]) model_params = { "height": 20, "width": 20, "density": mesa.visualization.Slider( - name="Agent density", - value=0.8, - min_value=0.1, - max_value=1.0, - step=0.1), + name="Agent density", value=0.8, min_value=0.1, max_value=1.0, step=0.1 + ), "minority_pc": mesa.visualization.Slider( - name="Fraction minority", - value=0.2, - min_value=0.00, - max_value=1.0, - step=0.05), + name="Fraction minority", value=0.2, min_value=0.00, max_value=1.0, step=0.05 + ), "homophily": mesa.visualization.Slider( - name="Homophily", - value=3, - min_value=0, - max_value=8, - step=1), + name="Homophily", value=3, min_value=0, max_value=8, step=1 + ), "radius": mesa.visualization.Slider( - name="Search Radius", - value=1, - min_value=1, - max_value=5, - step=1), + name="Search Radius", value=1, min_value=1, max_value=5, step=1 + ), } server = mesa.visualization.ModularServer( From d0f17a89a89dfd1c1aab086ce942bc1fba083e9a Mon Sep 17 00:00:00 2001 From: Achal Jain Date: Mon, 26 Feb 2024 16:58:41 +0530 Subject: [PATCH 8/8] Update model.py --- examples/schelling/model.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/schelling/model.py b/examples/schelling/model.py index ffbf361c..dfba4efb 100644 --- a/examples/schelling/model.py +++ b/examples/schelling/model.py @@ -69,7 +69,7 @@ def __init__( self.radius = radius self.schedule = mesa.time.RandomActivation(self) - self.grid = mesa.space.SingleGrid(height, width, torus=True) + self.grid = mesa.space.SingleGrid(width, height, torus=True) self.happy = 0 self.datacollector = mesa.DataCollector( @@ -80,7 +80,7 @@ def __init__( # We use a grid iterator that returns # the coordinates of a cell as well as # its contents. (coord_iter) - for _cont, pos in self.grid.coord_iter(): + for _, pos in self.grid.coord_iter(): if self.random.random() < self.density: agent_type = 1 if self.random.random() < self.minority_pc else 0 agent = SchellingAgent(self.next_id(), self, agent_type)