Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

finaly #232

Closed
wants to merge 4 commits into from
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
122 changes: 57 additions & 65 deletions examples/color_patches/color_patches/model.py
Original file line number Diff line number Diff line change
@@ -1,106 +1,98 @@
"""
The model - a 2D lattice where agents live and have an opinion
"""

from collections import Counter
from random import random

import mesa


class ColorCell(mesa.experimental.cell_space.CellAgent):
class ColorCell(mesa.Agent):
"""
Represents a cell's opinion (visualized by a color)
"""

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

def __init__(self, model, initial_state):
def __init__(self, unique_id, model, initial_state, mutation_prob=0.1):
"""
Create a cell, in the given state, at the given row, col position.
Create a cell with the given opinion state.
"""
super().__init__(model)
super().__init__(unique_id, model)
self.state = initial_state
self.next_state = None

def get_col(self):
"""Return the col location of this cell."""
return self.cell.coordinate[0]

def get_row(self):
"""Return the row location of this cell."""
return self.cell.coordinate[1]
self.mutation_prob = mutation_prob

def determine_opinion(self):
"""
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
Determines the agent's opinion for the next step by polling its neighbors.
The opinion is determined by the majority of the 8 neighbors' opinions.
A choice is made at random in case of a tie.
The next state is stored until all cells have been polled.
"""
neighbors = self.cell.neighborhood.agents
neighbors_opinion = Counter(n.state for n in neighbors)
# Following is a a tuple (attribute, occurrences)
polled_opinions = neighbors_opinion.most_common()
tied_opinions = []
for neighbor in polled_opinions:
if neighbor[1] == polled_opinions[0][1]:
tied_opinions.append(neighbor)

self.next_state = self.random.choice(tied_opinions)[0]
if random() < 0.5:
self.next_state = self.state
return

if random() < self.mutation_prob:
# Зміна кольору на випадковий незалежно від сусідів
self.next_state = self.random.choice(ColorCell.OPINIONS)
else:
# Стандартний процес визначення "думки" на основі сусідів
neighbors = self.model.grid.get_neighbors(
self.pos, moore=True, include_center=False
)
neighbors_opinion = Counter(neighbor.state for neighbor in neighbors)
polled_opinions = neighbors_opinion.most_common()

# Збираємо всі зв'язані думки (якщо є кілька з однаковою частотою)
tied_opinions = [
opinion[0]
for opinion in polled_opinions
if opinion[1] == polled_opinions[0][1]
]
self.next_state = self.random.choice(tied_opinions)

def assume_opinion(self):
"""
Set the state of the agent to the next state
Set the state of the agent to the next state.
"""
self.state = self.next_state


class ColorPatches(mesa.Model):
"""
represents a 2D lattice where agents live
Represents a 2D lattice where agents live.
"""

def __init__(self, width=20, height=20):
"""
Create a 2D lattice with strict borders where agents live
The agents next state is first determined before updating the grid
Create a 2D lattice with strict borders where agents live.
The agents' next state is determined first, and then the grid is updated.
"""
super().__init__()
self._grid = mesa.experimental.cell_space.OrthogonalMooreGrid(
(width, height), torus=False
)

# 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 cell in self._grid.all_cells:
agent = ColorCell(self, ColorCell.OPINIONS[self.random.randrange(0, 16)])
agent.move_to(cell)
self.width = width
self.height = height
self.grid = mesa.space.MultiGrid(width, height, torus=False)
self.schedule = mesa.time.RandomActivation(self)

# Create agents
for content, x, y in self.grid.coord_iter():
initial_state = ColorCell.OPINIONS[
self.random.randrange(0, len(ColorCell.OPINIONS))
]
agent = ColorCell(self.next_id(), self, initial_state, mutation_prob=0.01)
self.grid.place_agent(agent, (x, y))
self.schedule.add(agent)

self.running = True

def step(self):
"""
Perform the model step in two stages:
- First, all agents determine their next opinion based on their neighbors current opinions
- Then, all agents update their opinion to the next opinion
"""
self.agents.do("determine_opinion")
self.agents.do("assume_opinion")

@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: 'ColorPatches' object has no attribute 'grid'
- First, all agents determine their next opinion based on their neighbors' current opinions.
- Then, all agents update their opinion to the next opinion.
"""
return self._grid
for agent in self.schedule.agents:
agent.determine_opinion()
for agent in self.schedule.agents:
agent.assume_opinion()
self.schedule.step()
12 changes: 7 additions & 5 deletions examples/color_patches/color_patches/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
]


grid_rows = 50
grid_cols = 25
grid_rows = 100
grid_cols = 100
cell_size = 10
canvas_width = grid_rows * cell_size
canvas_height = grid_cols * cell_size
Expand All @@ -48,9 +48,11 @@ def color_patch_draw(cell):
if cell is None:
raise AssertionError
portrayal = {"Shape": "rect", "w": 1, "h": 1, "Filled": "true", "Layer": 0}
portrayal["x"] = cell.get_row()
portrayal["y"] = cell.get_col()
portrayal["Color"] = _COLORS[cell.get_state()]
# Use cell.pos to get the (x, y) coordinates
portrayal["x"], portrayal["y"] = cell.pos
portrayal["Color"] = _COLORS[
cell.state
] # Make sure to use cell.state for the color
return portrayal


Expand Down
Loading