Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,8 @@ docs/_build/
# PyBuilder
target/

# Jupyter and iPython notebook checkpoints
*.ipynb_checkpoints

# Spyder app workspace config file
.spyderworkspace
33 changes: 33 additions & 0 deletions examples/ColorPatches/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
## Color Patches:
Is a cellulat automaton model where each agent lives in a cell on a 2D grid, and never moves.<br>
An agent's state represents its "opinion" and is shown by the color of the cell the agent lives in. Each color represents an opinion - there are 16 of them.<br>
At each time step, an agent's opinion is influenced by that of its neighbors, and changes to the most common one found; ties are randomly arbitrated.<br>
As an agent adapts its thinking to that of its neighbors, the cell color changes.


### Parameters you can play with:
(you must change the code to alter the parameters at this stage)
* Vary the number of opinions.
* Vary the size of the grid
* Change the grid from fixed borders to a torus continuum


### Observe
* how groups of like minded agents form and evolve
* how sometimes a single opinion prevails
* how some minority or fragmented opinions rapidly disappear


### Sources and Attribution
Inspired from [this model](http://www.cs.sjsu.edu/~pearce/modules/lectures/abs/as/ca.htm) from San Jose University<br>
Other similar models: [Schelling Segregation Model](https://github.com/projectmesa/mesa/tree/master/examples/Schelling)


### To run this example

* Launch the model
```python
python color_patches.py
```
* Visit your browser: http://127.0.0.1:8888/
* In your browser hit *reset*, then *run*
67 changes: 67 additions & 0 deletions examples/ColorPatches/color_cell.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"""
Subclassing Agent to represent a cell
"""


from collections import Counter
import random

from mesa import Agent



class ColorCell(Agent):
'''
Represents a cell's opinion (visualized by a color)
'''

OPINIONS = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]


def __init__(self, pos, model, initial_state):
'''
Create a cell, in the given state, at the given row, col position.
'''
Agent.__init__(self, pos, model)
self._row = pos[1]
self._col = pos[0]
self._state = initial_state
self._next_state = None

def get_col(self):
'''Return the col location of this cell.'''
return self._col

def get_row(self):
'''Return the row location of this cell.'''
return self._row

def get_state(self):
'''Return the current state (OPINION) of this cell.'''
return self._state

def step(self, model):
'''
Determines the agent opinion for the next step by polling its neighbors
The opinion is determined by the majority of the 8 neighbors' opinion
A choice is made at random in case of a tie
The next state is stored until all cells have been polled
'''
neighbors_opinion = Counter(n.get_state() \
for n in model.grid.neighbor_iter((self._col, self._row), True))
polled_opinions = neighbors_opinion.most_common() #a tuple (attribute, occurrences)
tied_opinions = []
for neighbor in polled_opinions:
if neighbor[1] == polled_opinions[0][1]:
tied_opinions.append(neighbor)

self._next_state = random.choice(tied_opinions)[0]


# model argument is unused
def advance(self, model):
'''
Set the state of the agent to the next state
'''
self._state = self._next_state

80 changes: 80 additions & 0 deletions examples/ColorPatches/color_patch_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
"""
The model - a 2D lattice where agents live and have an opinion
"""


import random

from mesa import Model
from mesa.time import SimultaneousActivation
from mesa.space import Grid
from color_cell import ColorCell



class ColorPatchModel(Model):
'''
represents a 2D lattice where agents live
'''

def __init__(self, height, width):
'''
Create a 2D lattice with strict borders where agents live
The agents next state is first determined before updating the grid
'''

self._grid = Grid(height, width, torus=False)
self._schedule = SimultaneousActivation(self)

# self._grid.coord_iter()
# --> should really not return content + col + row
# -->but only col & row
# for (contents, col, row) in self._grid.coord_iter():
# replaced content with _ to appease linter
for (_, col, row) in self._grid.coord_iter():
cell = ColorCell((col, row), self, ColorCell.OPINIONS[random.randrange(0, 16)])
self._grid.place_agent(cell, (col, row))
self._schedule.add(cell)

self.running = True

def step(self):
'''
Advance the model one step.
'''
self._schedule.step()



# the following is a temporary fix for the framework classes accessing model
# attributes directly
# I don't think it should
# --> it imposes upon the model builder to use the attributes names that
# the framework expects.
#
# Traceback included in docstrings

@property
def grid(self):
"""
/mesa/visualization/modules/CanvasGridVisualization.py
is directly accessing Model.grid
76 def render(self, model):
77 grid_state = defaultdict(list)
---> 78 for y in range(model.grid.height):
79 for x in range(model.grid.width):
80 cell_objects = model.grid.get_cell_list_contents([(x, y)])

AttributeError: 'ColorPatchModel' object has no attribute 'grid'
"""
return self._grid

@property
def schedule(self):
"""
mesa_ABM/examples_ABM/color_patches/mesa/visualization/ModularVisualization.py",
line 278, in run_model
while self.model.schedule.steps < self.max_steps and self.model.running:
AttributeError: 'NoneType' object has no attribute 'steps'
"""
return self._schedule
50 changes: 50 additions & 0 deletions examples/ColorPatches/color_patches.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"""
handles the definition of the canvas parameters and
the drawing of the model representation on the canvas
"""


from color_patch_model import ColorPatchModel
from mesa.visualization.modules import CanvasGrid
from mesa.visualization.ModularVisualization import ModularServer


_COLORS = ['Aqua', 'Blue', 'Fuchsia', 'Gray', 'Green',
'Lime', 'Maroon', 'Navy', 'Olive', 'Orange', 'Purple',
'Red', 'Silver', 'Teal', 'White', 'Yellow']


GRID_ROWS = 25
GRID_COLS = 50
CELL_SIZE = 10
CANVAS_HEIGHT = GRID_ROWS * CELL_SIZE
CANVAS_WIDTH = GRID_COLS * CELL_SIZE


def color_patch_draw(cell):
'''
This function is registered with the visualization server to be called
each tick to indicate how to draw the cell in its current state.

:param cell: the cell in the simulation

:return: the portrayal dictionary.

'''
assert cell is not None
portrayal = {"Shape": "rect", "w": 1, "h": 1, "Filled": "true", "Layer": 0}
portrayal["x"] = cell.get_col()
portrayal["y"] = cell.get_row()
portrayal["Color"] = _COLORS[cell.get_state()]
return portrayal


CANVAS_ELEMENT = CanvasGrid(color_patch_draw,
GRID_COLS, GRID_ROWS,
CANVAS_HEIGHT, CANVAS_WIDTH)

SERVER = ModularServer(ColorPatchModel,
[CANVAS_ELEMENT], "Color Patches",
GRID_ROWS, GRID_COLS)

SERVER.launch()
3 changes: 3 additions & 0 deletions examples/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

This directory contains example models meant to test and demonstrate Mesa's features, and provide demonstrations for how to build and analyze agent-based models. For more information on each model, see its own Readme and documentation.

### Color Patches
A cellular automaton model where agents opinions are influenced by that of their neighbors. As the model evolves, color patches representing the prevailing opinion in a given area expand, contract, and sometimes disappear.

### Conway's Game Of Life
An implementation of the Famous Pr. Conway's Game Of Life

Expand Down