class ForestFire(Model): ''' Simple Forest Fire model. ''' def __init__(self, height, width, density): ''' Create a new forest fire model. Args: height, width: The size of the grid to model density: What fraction of grid cells have a tree in them. ''' # Initialize model parameters self.height = height self.width = width self.density = density # Set up model objects self.schedule = RandomActivation(self) self.grid = Grid(height, width, torus=False) self.datacollector = DataCollector( {"Fine": lambda m: self.count_type(m, "Fine"), "On Fire": lambda m: self.count_type(m, "On Fire"), "Burned Out": lambda m: self.count_type(m, "Burned Out")}) # Place a tree in each cell with Prob = density for (contents, x, y) in self.grid.coord_iter(): if random.random() < self.density: # Create a tree new_tree = TreeCell((x, y)) # Set all trees in the first column on fire. if x == 0: new_tree.condition = "On Fire" self.grid._place_agent((x, y), new_tree) self.schedule.add(new_tree) self.running = True def step(self): ''' Advance the model by one step. ''' self.schedule.step() self.datacollector.collect(self) # Halt if no more fire if self.count_type(self, "On Fire") == 0: self.running = False @staticmethod def count_type(model, tree_condition): ''' Helper method to count trees in a given condition in a given model. ''' count = 0 for tree in model.schedule.agents: if tree.condition == tree_condition: count += 1 return count
def __init__(self, height, width, density): ''' Create a new forest fire model. Args: height, width: The size of the grid to model density: What fraction of grid cells have a tree in them. ''' # Initialize model parameters self.height = height self.width = width self.density = density # Set up model objects self.schedule = RandomActivation(self) self.grid = Grid(height, width, torus=False) self.datacollector = DataCollector( {"Fine": lambda m: self.count_type(m, "Fine"), "On Fire": lambda m: self.count_type(m, "On Fire"), "Burned Out": lambda m: self.count_type(m, "Burned Out")}) # Place a tree in each cell with Prob = density for (contents, x, y) in self.grid.coord_iter(): if random.random() < self.density: # Create a tree new_tree = TreeCell((x, y)) # Set all trees in the first column on fire. if x == 0: new_tree.condition = "On Fire" self.grid._place_agent((x, y), new_tree) self.schedule.add(new_tree) self.running = True
def __init__(self, height=100, width=100, density=0.7): """ Create a new forest fire model. Args: height, width: The size of the grid to model density: What fraction of grid cells have a tree in them. """ # Initialize model parameters self.height = height self.width = width self.density = density # Set up model objects self.schedule = RandomActivation(self) self.grid = Grid(height, width, torus=False) # Place a tree in each cell with Prob = density for (contents, x, y) in self.grid.coord_iter(): if self.random.random() < self.density: # Create a tree new_tree = TreeCell((x, y), self) # Set all trees in the first column on fire. if x == 0: new_tree.condition = "On Fire" self.grid._place_agent((x, y), new_tree) self.schedule.add(new_tree)
class ForestFire(Model): """ Simple Forest Fire model. """ def __init__(self, height=100, width=100, density=0.7): """ Create a new forest fire model. Args: height, width: The size of the grid to model density: What fraction of grid cells have a tree in them. """ # Set up model objects self.schedule = BaseScheduler(self) self.grid = Grid(height, width, torus=False) # Place a tree in each cell with Prob = density for (contents, x, y) in self.grid.coord_iter(): if self.random.random() < density: # Create a tree new_tree = TreeCell((x, y), self) # Set all trees in the first column on fire. if x == 0: new_tree.condition = "On Fire" self.grid._place_agent((x, y), new_tree) self.schedule.add(new_tree) def step(self): """ Advance the model by one step. """ self.schedule.step()
def __init__(self, height=50, width=50, server=True): ''' Create a new playing area of (height, width) cells. ''' # Set up the grid and schedule. # Use SimultaneousActivation which simulates all the cells # computing their next state simultaneously. This needs to # be done because each cell's next state depends on the current # state of all its neighbors -- before they've changed. self.schedule = SimultaneousActivation(self) self.server = server # Use a simple grid, where edges wrap around. self.grid = Grid(height, width, torus=True) #Datacollector -- default for this model is no data collection, but one can use OABM to assign one. #so this is an empty DataCollector instance from MESA self.datacollector = DataCollector() # Place a cell at each location, with some initialized to # ALIVE and some to DEAD. for (contents, x, y) in self.grid.coord_iter(): cell = Cell((x, y), self) if self.random.random() < 0.1: cell.state = cell.ALIVE self.grid.place_agent(cell, (x, y)) self.schedule.add(cell) self.running = True
def __init__( self, height, width, cop_vision, max_jail_term, prison_interaction, arrest_prob_constant=2.3, movement=True, max_steps=1000, seed=None, ): """Seed is used to set randomness in the __new__ function of the Model superclass.""" # pylint: disable-msg=unused-argument,super-init-not-called super().__init__() self.height = height self.width = width self.cop_vision = cop_vision self.max_jail_term = max_jail_term self.arrest_prob_constant = arrest_prob_constant self.movement = True self.running = True self.max_steps = max_steps self.iteration = 0 self.prison_interaction = prison_interaction self.schedule = RandomActivation(self) self.grid = Grid(height, width, torus=True)
def __init__(self, height, width, density, esquinas): super().__init__() # Parámetros para inicializar modelo self.height = height self.width = width self.density = density self.esquinas = esquinas self.initialTrees = 0 self.burnedTrees = 0 self.percen = 0 # Creación del planificador y del grid self.schedule = RandomActivation(self) self.grid = Grid(width, height, torus=False) # Recolector de datos para gráfica self.datacollector = DataCollector({ "Fine": lambda m: self.count_type(m, "Fine"), "On Fire": lambda m: self.count_type(m, "On Fire"), "Burned Out": lambda m: self.count_type(m, "Burned Out") }) # Creación de los agentes del modelo y configuración de parámetros self.setup() # Ejecución en navegador despues de crear self.running = True
def __init__(self, height=50, width=50): ''' Create a new playing area of (height, width) cells. ''' # Set up the grid and schedule. # Use SimultaneousActivation which simulates all the cells # Computing their next state simultaneously. # This needs to be done because each cell's next state depends on # the current state of all its neighbors -- before they've changed self.schedule = SimultaneousActivation(self) # Use a single grid, where edges wrap around. self.grid = Grid(height, width, torus=True) # Place a cell at each location, with some initialized to # ALIVE and some to DEAD for (contents, x, y) in self.grid.coord_iter(): cell = Cell((x, y), self) if self.random.random() < 0.1: cell.state = cell.ALIVE # place_agent: Position an agent on the Grid, and set its pos variable self.grid.place_agent(cell, (x, y)) # add(): Add an agent object to the schedule self.schedule.add(cell) self.running = True
def __init__(self, height=100, width=100, density=0.65): self.height = height self.width = width self.density = density self.schedule = RandomActivation(self) self.grid = Grid(height, width, torus=False) self.datacollector = DataCollector({ "Fine": lambda m: self.count_type(m, "Fine"), "On Fire": lambda m: self.count_type(m, "On Fire"), "Burned Out": lambda m: self.count_type(m, "Burned Out"), }) for (contents, x, y) in self.grid.coord_iter(): if self.random.random() < self.density: new_tree = TreeCell((x, y), self) # Set all trees in the first column on fire. if x == 0: new_tree.condition = "On Fire" self.grid._place_agent((x, y), new_tree) self.schedule.add(new_tree) self.running = True self.datacollector.collect(self)
def __init__(self, height, width): ''' Create a new playing area of (height, width) cells. ''' # Set up the grid and schedule. # Use SimultaneousActivation which simulates all the cells # computing their next state simultaneously. This needs to # be done because each cell's next state depends on the current # state of all its neighbors -- before they've changed. self.schedule = SimultaneousActivation(self) # Use a simple grid, where edges wrap around. self.grid = Grid(height, width, torus=True) # Place a cell at each location, with some initialized to # ALIVE and some to DEAD. for (contents, x, y) in self.grid.coord_iter(): cell = Cell((x, y), self) if random() < .1: cell.state = cell.ALIVE self.grid.place_agent(cell, (x, y)) self.schedule.add(cell) self.running = True
def __init__(self, height, width): ''' Create a new playing area of (height, width) cells. ''' # Set up the grid and schedule. # Use SimultaneousActivation which simulates all the cells # computing their next state simultaneously. This needs to # be done because each cell's next state depends on the current # state of all its neighbors -- before they've changed. self.schedule = SimultaneousActivation(self) # Use a simple grid, where edges wrap around. self.grid = Grid(height, width, torus=True) # Place a cell at each location, with some initialized to # ALIVE and some to DEAD. for (contents, x, y) in self.grid.coord_iter(): pos = (x, y) init_state = CGoLCell.DEAD # Initially, make 10% of the cells ALIVE. if random.random() < 0.1: init_state = CGoLCell.ALIVE cell = CGoLCell(pos, self, init_state) # Put this cell in the grid at position (x, y) self.grid.place_agent(cell, pos) # Add this cell to the scheduler. self.schedule.add(cell) self.running = True
def __init__(self, height=40, width=40, citizen_density=0.7, cop_density=0.074, citizen_vision=7, cop_vision=7, legitimacy=0.8, max_jail_term=1000, active_threshold=.1, arrest_prob_constant=2.3, movement=True, max_iters=1000): super().__init__() self.height = height self.width = width self.citizen_density = citizen_density self.cop_density = cop_density self.citizen_vision = citizen_vision self.cop_vision = cop_vision self.legitimacy = legitimacy self.max_jail_term = max_jail_term self.active_threshold = active_threshold self.arrest_prob_constant = arrest_prob_constant self.movement = movement self.max_iters = max_iters self.iteration = 0 self.schedule = RandomActivation(self) self.grid = Grid(height, width, torus=True) model_reporters = { "Quiescent": lambda m: self.count_type_citizens(m, "Quiescent"), "Active": lambda m: self.count_type_citizens(m, "Active"), "Jailed": lambda m: self.count_jailed(m)} agent_reporters = { "x": lambda a: a.pos[0], "y": lambda a: a.pos[1], 'breed': lambda a: a.breed, "jail_sentence": lambda a: getattr(a, 'jail_sentence', None), "condition": lambda a: getattr(a, "condition", None), "arrest_probability": lambda a: getattr(a, "arrest_probability", None) } self.datacollector = DataCollector(model_reporters=model_reporters, agent_reporters=agent_reporters) unique_id = 0 if self.cop_density + self.citizen_density > 1: raise ValueError( 'Cop density + citizen density must be less than 1') for (contents, x, y) in self.grid.coord_iter(): if self.random.random() < self.cop_density: cop = Cop(unique_id, self, (x, y), vision=self.cop_vision) unique_id += 1 self.grid[y][x] = cop self.schedule.add(cop) elif self.random.random() < ( self.cop_density + self.citizen_density): citizen = Citizen(unique_id, self, (x, y), hardship=0.7,#self.random.random(), regime_legitimacy=self.legitimacy if self.random.random()<0.9 else 0.01, risk_aversion=self.random.random(), threshold=self.active_threshold, vision=self.citizen_vision) unique_id += 1 self.grid[y][x] = citizen self.schedule.add(citizen) self.running = True self.datacollector.collect(self)
def __init__(self, height=40, width=40, citizen_density=0.7, cop_density=0.074, citizen_vision=7, cop_vision=7, legitimacy=0.8, max_jail_term=1000, active_threshold=.1, arrest_prob_constant=2.3, movement=True, max_iters=1000): super().__init__() self.height = height self.width = width self.citizen_density = citizen_density self.cop_density = cop_density self.citizen_vision = citizen_vision self.cop_vision = cop_vision self.legitimacy = legitimacy self.max_jail_term = max_jail_term self.active_threshold = active_threshold self.arrest_prob_constant = arrest_prob_constant self.movement = movement self.max_iters = max_iters self.iteration = 0 self.schedule = RandomActivation(self) self.grid = Grid(height, width, torus=True) model_reporters = { "Quiescent": lambda m: self.count_type_citizens(m, "Quiescent"), "Active": lambda m: self.count_type_citizens(m, "Active") } agent_reporters = { "x": lambda a: a.pos[0], "y": lambda a: a.pos[1], 'breed': lambda a: a.breed, "jail_sentence": lambda a: getattr(a, 'jail_sentence', None), "condition": lambda a: getattr(a, "condition", None), "arrest_probability": lambda a: getattr(a, "arrest_probability", None) } self.datacollector = DataCollector(model_reporters=model_reporters, agent_reporters=agent_reporters) unique_id = 0 for (contents, x, y) in self.grid.coord_iter(): citizen = Citizen(unique_id, self, (x, y), g=0.5, opinion=self.random.random(), vision=self.citizen_vision) unique_id += 1 self.grid[y][x] = citizen self.schedule.add(citizen) self.running = True self.datacollector.collect(self)
def __init__(self, width=100, height=100, density=0.65, wind=0.0): """ Create a new forest fire model. Args: width, height: The size of the grid to model density: What fraction of grid cells have a tree in them. """ # Set up model objects self.schedule = RandomActivation(self) self.grid = Grid(width, height, torus=False) self.width = width self.height = height self.count_step = 1 # Variáveis de controle self.density = density self.wind = wind self.datacollector_cluster_fine = DataCollector({ "Number of clusters (Fine)": lambda m: self.count_clusters(m, self.width, self.height, "Fine"), }) self.datacollector_cluster_fireputout = DataCollector({ "Number of clusters (Fire Put Out)": lambda m: self.count_clusters(m, self.width, self.height, "Fire Put Out"), }) self.datacollector = DataCollector({ "Fine": lambda m: self.count_type(m, "Fine"), "On Fire": lambda m: self.count_type(m, "On Fire"), "Burned Out": lambda m: self.count_type(m, "Burned Out"), "Fire Put Out": lambda m: self.count_type(m, "Fire Put Out"), }) # Place a tree in each cell with Prob = density for (contents, x, y) in self.grid.coord_iter(): if self.random.random() < density: # Create a tree new_tree = TreeCell((x, y), self, wind) # Set all trees in the first column on fire. if x == 0: new_tree.condition = "On Fire" self.grid._place_agent((x, y), new_tree) self.schedule.add(new_tree) self.running = True self.datacollector_cluster_fine.collect(self) self.datacollector_cluster_fireputout.collect(self) self.datacollector.collect(self)
class ConwaysGameOfLife(Model): ''' Represents the 2-dimensional array of cells in Conway's Game of Life. ''' def __init__(self, height=50, width=50, server=True): ''' Create a new playing area of (height, width) cells. ''' # Set up the grid and schedule. # Use SimultaneousActivation which simulates all the cells # computing their next state simultaneously. This needs to # be done because each cell's next state depends on the current # state of all its neighbors -- before they've changed. self.schedule = SimultaneousActivation(self) self.server = server # Use a simple grid, where edges wrap around. self.grid = Grid(height, width, torus=True) #Datacollector -- default for this model is no data collection, but one can use OABM to assign one. #so this is an empty DataCollector instance from MESA self.datacollector = DataCollector() # Place a cell at each location, with some initialized to # ALIVE and some to DEAD. for (contents, x, y) in self.grid.coord_iter(): cell = Cell((x, y), self) if self.random.random() < 0.1: cell.state = cell.ALIVE self.grid.place_agent(cell, (x, y)) self.schedule.add(cell) self.running = True def step(self): ''' Have the scheduler advance each cell by one step ''' self.schedule.step() def run_model(self, n=None): if n: self.num_steps = n if self.server == False: for _ in range(self.num_steps): self.step() return self else: from .server import server server.launch()
class TestBaseGrid(unittest.TestCase): ''' Testing a non-toroidal grid. ''' torus = False def setUp(self): ''' Create a test non-toroidal grid and populate it with Mock Agents ''' self.grid = Grid(3, 5, self.torus) self.agents = [] counter = 0 for y in range(3): for x in range(5): if TEST_GRID[y][x] == 0: continue counter += 1 # Create and place the mock agent a = MockAgent(counter, None) self.agents.append(a) self.grid.place_agent(a, (x, y)) def test_agent_positions(self): ''' Ensure that the agents are all placed properly. ''' for agent in self.agents: x, y = agent.pos assert self.grid[y][x] == agent def test_neighbors(self): ''' Test the base neighborhood methods on the non-toroid. ''' neighborhood = self.grid.get_neighborhood(1, 1, moore=True) assert len(neighborhood) == 8 neighborhood = self.grid.get_neighborhood(4, 1, moore=True) assert len(neighborhood) == 5 neighborhood = self.grid.get_neighborhood(0, 0, moore=False) assert len(neighborhood) == 2 neighbors = self.grid.get_neighbors(4, 1, moore=False) assert len(neighbors) == 0 neighbors = self.grid.get_neighbors(4, 1, moore=True) assert len(neighbors) == 2 neighbors = self.grid.get_neighbors(1, 1, moore=False, include_center=True) assert len(neighbors) == 3 neighbors = self.grid.get_neighbors(3, 1, moore=False, radius=2) assert len(neighbors) == 4
def __init__(self, width, height, key1=103, key2=104): self.width = width self.height = height self.key1 = (key1, ) self.key2 = key2 self.schedule = SimultaneousActivation(self) self.grid = Grid(width, height, torus=True) for (c, x, y) in self.grid.coord_iter(): a = MockAgent(x + y * 100, self, x * y * 3) self.grid.place_agent(a, (x, y)) self.schedule.add(a)
class InspectionModel(Model): ''' Simple Restaurant Inspection model. ''' def __init__(self, height, width, density): ''' Create a new restaurant inspection model. Args: height, width: The size of the grid to model density: What fraction of grid cells have a restaurant in them. ''' # Initialize model parameters self.height = height self.width = width self.density = density # Set up model objects self.schedule = RandomActivation(self) self.grid = Grid(height, width, torus=False) self.datacollector = DataCollector( {"Good": lambda m: self.count_type(m, "Good"), "Bad": lambda m: self.count_type(m, "Bad")}) # Place a restaurant in each cell with Prob = density for (contents, x, y) in self.grid.coord_iter(): if random.random() < self.density: # Create a restaurant new_restaurant = RestaurantCell((x, y)) self.grid._place_agent((x, y), new_restaurant) self.schedule.add(new_restaurant) self.running = True def step(self): ''' Advance the model by one step. ''' self.schedule.step() self.datacollector.collect(self) @staticmethod def count_type(model, restaurant_hygiene): ''' Helper method to count restaurants in a given condition in a given model. ''' count = 0 for restaurant in model.schedule.agents: if restaurant.hygiene == restaurant_hygiene and restaurant.rating != 'Closed': count += 1 return count
def __init__(self, width=50, height=50, k_full=3, k_active=3, full_value=200, g=28): # scheduler self.schedule = RandomActivation(self) # grid: instance of Grid with specified width, height and torus=False self.grid = Grid(width=width, height=height, torus=False) ### TO BE DONE # Model parameters # Full value: maximum value can be reached by a cell self.full_value = None # k_full: how many neighbors with full state is needed for changing state of an inactive cell self.k_full = None # k_active: how many neighbors with active state is needed for changing state of an inactive cell self.k_active = None # g: accelerates activation of a cell, added to the change of state for an active cell self.g = None ### TO BE DONE # running: needed for interactive visualization self.running = True # Create molecules and place them in a grid cell # Looping through all rows of the grid for x in range(height): # Looping through all columns of the grid for y in range(width): ### TO BE DONE # Instantiate molecule molecule = MoleculeCell(pos=None, model=None) # Add molecule to the scheduler pass # Place molecule in the grid self.grid.place_agent(pos=None, agent=molecule) ### TO BE DONE # data collector for plotting self.data_collection = DataCollector( # collect number of inactive and full molecules at each step model_reporters={ "Inactives": count_inactive, "Fulls": count_full }, agent_reporters={"State": "state"})
def __init__(self, height, width, density): ''' Create a new restaurant inspection model. Args: height, width: The size of the grid to model density: What fraction of grid cells have a restaurant in them. ''' # Initialize model parameters self.height = height self.width = width self.density = density # Set up model objects self.schedule = RandomActivation(self) self.grid = Grid(height, width, torus=False) self.datacollector = DataCollector( {"Good": lambda m: self.count_type(m, "Good"), "Bad": lambda m: self.count_type(m, "Bad")}) # Place a restaurant in each cell with Prob = density for (contents, x, y) in self.grid.coord_iter(): if random.random() < self.density: # Create a restaurant new_restaurant = RestaurantCell((x, y)) self.grid._place_agent((x, y), new_restaurant) self.schedule.add(new_restaurant) self.running = True
def setUp(self): ''' Create a test non-toroidal grid and populate it with Mock Agents ''' self.grid = Grid(3, 5, self.torus) self.agents = [] counter = 0 for y in range(3): for x in range(5): if TEST_GRID[y][x] == 0: continue counter += 1 # Create and place the mock agent a = MockAgent(counter, None) self.agents.append(a) self.grid.place_agent(a, (x, y))
def __init__(self, L, p, direction, strength): """ :param L: size of model's grid :param p: probability of tree's occurrence in a cell :param direction: tuple (x,y) - direction of the wind: (0,0) - no wind, (0,1) - North, (0,-1) - South, (1,0) - East, (-1,0) - West, (1,1) - North-East, (-1,1) - North-West, (1,-1) - South-East, (-1,-1) - South-West. :param strength: int [0,1] - let's assume 0 - 0 km/h, 1 - 100km/h At the beginning we assume that every tree has probability of becoming a burning cell equal to 0.5 (if has burning neighbour). If considered non-burning tree has a burning neighbour tree and wind is blowing from the same direction as the burning neighbour, then probability of setting considered tree to fire is raising by half of the wind strength (not speed). On the other side, if source of fire is on the opposite site of source of wind then probability of setting considered tree to fire is lowered by half of wind strength. Otherwise, probability of setting tree to fire is not changed (trees occurring diagonal and perpendicular to wind direction are not affected by wind). """ super().__init__() self.grid = Grid(L, L, False) self.schedule = SimultaneousActivation(self) self.running = True self.p = p self.direction = direction self.strength = strength for i in range(L): for j in range(L): if self.random.random() <= self.p: if i == L - 1: tree = TreeAgent((i, j), self, "burning") else: tree = TreeAgent((i, j), self, "occupied") self.schedule.add(tree) self.grid.place_agent(tree, (i, j)) self.datacollector = DataCollector(model_reporters={ "p*": compute_p, "Cluster": compute_cluster })
class ColorPatchModel(Model): ''' represents a 2D lattice where agents live ''' def __init__(self, width, height): ''' Create a 2D lattice with strict borders where agents live The agents next state is first determined before updating the grid ''' self._grid = Grid(width, height, 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 (_, row, col) in self._grid.coord_iter(): cell = ColorCell((row, col), self, ColorCell.OPINIONS[random.randrange(0, 16)]) self._grid.place_agent(cell, (row, col)) 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): return self._grid @property def schedule(self): return self._schedule
def __init__(self, height=100, width=100, dummy="", density=0.5, p_inf=0.1, p_rec=0.3, p_reinf=0.05, p_test=0.1, p_death=0.2, test_n=0, hood="Moore", datacollector={}): ''' Create a new playing area of (height, width) cells. ''' # Use SimultaneousActivation which simulates all the cells # computing their next state simultaneously. This needs to # be done because each cell's next state depends on the current # state of all its neighbors -- before they've changed. self.height = height self.width = width self.schedule = SimultaneousActivation(self) # Use a simple grid, where edges wrap around. self.grid = Grid(height, width, torus=True) # Use the DataCollector method to store the relevant information of our # model. This helps with plotting in the web socke, but also with running #more models at the same time using BatchRunner (in batch.py) self.datacollector = DataCollector( model_reporters=self.compute_reporters()) # Place a cell at each location, with some initialized to # ALIVE and some to DEAD. for (contents, x, y) in self.grid.coord_iter(): cell = Cell((x, y), self, p_inf, p_rec, p_reinf, p_test, p_death, test_n, hood) if self.random.random() < density: cell.state = cell.INFECTED self.grid.place_agent(cell, (x, y)) self.schedule.add(cell) self.measure_CA = [] self.running = True self.datacollector.collect(self)
def __init__(self, height=100, width=100, density=0.65): ''' Create a new forest fire model. Args: - height: the grid's height - width: the grid's width - density: what fraction of grid cells have a tree in them (initially) ''' ''' Set up model ojects RandomActivation is a schedular which actives each agent once per step, in random order, with the order reshuffled every step. This is equivalent to the NetLogo 'ask agent…' and is generally the default behavior for an ABM ''' self.schedule = RandomActivation(self) self.grid = Grid(height, width, torus=False) self.datacollector = DataCollector({ # lambda function, it is like: lambda x, y: x ** y 'Fine': lambda m: self.count_type(m, 'Fine'), 'On Fire': lambda m: self.count_type(m, 'On Fire'), 'Burned Out': lambda m: self.count_type(m, 'Burned Out'), }) # Place a tree in each cell with Prob = density (here is 0.65) # coord_iter: returns coordinates as well as cell contents. for (contents, x, y) in self.grid.coord_iter(): if self.random.random() < density: # Create a tree new_tree = TreeCell((x, y), self) # Set all trees in the first column on fire. if x == 0: new_tree.condition = 'On Fire' # place_agent: positions an agent on the grid, and set its pos variable. self.grid._place_agent((x, y), new_tree) # Add an agent object to the schedule. self.schedule.add(new_tree) self.running = True self.datacollector.collect(self)
def __init__(self, height, width, citizen_density, cop_density, citizen_vision, cop_vision, legitimacy, max_jail_term, active_threshold=.1, arrest_prob_constant=2.3, movement=True, max_iters=1000): super(CivilViolenceModel, self).__init__() self.height = height self.width = width self.citizen_density = citizen_density self.cop_density = cop_density self.citizen_vision = citizen_vision self.cop_vision = cop_vision self.legitimacy = legitimacy self.max_jail_term = max_jail_term self.active_threshold = active_threshold self.arrest_prob_constant = arrest_prob_constant self.movement = movement self.running = True self.max_iters = max_iters self.iteration = 0 self.schedule = RandomActivation(self) self.grid = Grid(height, width, torus=True) model_reporters = { "Quiescent": lambda m: self.count_type_citizens(m, "Quiescent"), "Active": lambda m: self.count_type_citizens(m, "Active"), "Jailed": lambda m: self.count_jailed(m)} agent_reporters = { "x": lambda a: a.pos[0], "y": lambda a: a.pos[1], 'breed': lambda a: a.breed, "jail_sentence": lambda a: getattr(a, 'jail_sentence', None), "condition": lambda a: getattr(a, "condition", None), "arrest_probability": lambda a: getattr(a, "arrest_probability", None) } self.dc = DataCollector(model_reporters=model_reporters, agent_reporters=agent_reporters) unique_id = 0 if self.cop_density + self.citizen_density > 1: raise ValueError( 'Cop density + citizen density must be less than 1') for (contents, x, y) in self.grid.coord_iter(): if random.random() < self.cop_density: cop = Cop(unique_id, (x, y), vision=self.cop_vision, model=self) unique_id += 1 self.grid[y][x] = cop self.schedule.add(cop) elif random.random() < ( self.cop_density + self.citizen_density): citizen = Citizen(unique_id, (x, y), hardship=random.random(), regime_legitimacy=self.legitimacy, risk_aversion=random.random(), threshold=self.active_threshold, vision=self.citizen_vision, model=self) unique_id += 1 self.grid[y][x] = citizen self.schedule.add(citizen)
class MockModel(Model): """ Test model for testing """ def __init__(self, width, height, key1=103, key2=104): self.width = width self.height = height self.key1 = key1, self.key2 = key2 self.schedule = SimultaneousActivation(self) self.grid = Grid(width, height, torus=True) for (c, x, y) in self.grid.coord_iter(): a = MockAgent(x + y * 100, self, x * y * 3) self.grid.place_agent(a, (x, y)) self.schedule.add(a) def step(self): self.schedule.step()
def setUp(self): ''' Create a test non-toroidal grid and populate it with Mock Agents ''' width = 3 # width of grid height = 5 # height of grid self.grid = Grid(width, height, self.torus) self.agents = [] counter = 0 for x in range(width): for y in range(height): if TEST_GRID[x][y] == 0: continue counter += 1 # Create and place the mock agent a = MockAgent(counter, None) self.agents.append(a) self.grid.place_agent(a, (x, y))
class ForestFire(Model): def __init__(self, height=100, width=100, density=0.65): self.height = height self.width = width self.density = density self.schedule = RandomActivation(self) self.grid = Grid(height, width, torus=False) self.datacollector = DataCollector({ "Fine": lambda m: self.count_type(m, "Fine"), "On Fire": lambda m: self.count_type(m, "On Fire"), "Burned Out": lambda m: self.count_type(m, "Burned Out"), }) for (contents, x, y) in self.grid.coord_iter(): if self.random.random() < self.density: new_tree = TreeCell((x, y), self) # Set all trees in the first column on fire. if x == 0: new_tree.condition = "On Fire" self.grid._place_agent((x, y), new_tree) self.schedule.add(new_tree) self.running = True self.datacollector.collect(self) def step(self): self.schedule.step() self.datacollector.collect(self) # Halt if no more fire if self.count_type(self, "On Fire") == 0: self.running = False @staticmethod def count_type(model, tree_condition): count = 0 for tree in model.schedule.agents: if tree.condition == tree_condition: count += 1 return count
def __init__(self, height, width, density): """ Create a new forest fire model. Args: height, width: The size of the grid to model density: What fraction of grid cells have a tree in them. """ # Initialize model parameters self.height = height self.width = width self.density = density # Set up model objects self.schedule = RandomActivation(self) self.grid = Grid(height, width, torus=True) self.datacollector = DataCollector({ "Unelectrified": lambda m: self.count_type(m, "Unelectrified"), "Transition": lambda m: self.count_type(m, "Transition"), "Electrified": lambda m: self.count_type(m, "Electrified") }) # Place a tree in each cell with Prob = density for (contents, x, y) in self.grid.coord_iter(): if random.random() < self.density: # Create a tree x = random.randrange(self.width) y = random.randrange(self.height) new_tree = TreeCell((x, y), self) # Set all trees in the first column on fire. # if x == 4: # new_tree.condition = "Transition" # self.grid._place_agent((x, y), new_tree) # self.schedule.add(new_tree) if (x < 40 & y < 40): new_tree.condition = "Transition" self.grid._place_agent((x, y), new_tree) self.schedule.add(new_tree) self.running = True
class ConwaysGameOfLife(Model): """ Represents the 2-dimensional array of cells in Conway's Game of Life. """ def __init__(self, size, **kwargs): """ Create a new playing area of (height, width) cells. """ # Set up the grid and schedule. # Use SimultaneousActivation which simulates all the cells # computing their next state simultaneously. This needs to # be done because each cell's next state depends on the current # state of all its neighbors -- before they've changed. self.schedule = SimultaneousActivation(self) # Use a simple grid, where edges wrap around. self.grid = Grid(size, size, torus=True) # Place a cell at each location, with some initialized to # ALIVE and some to DEAD. for (_contents, x, y) in self.grid.coord_iter(): cell = Cell((x, y), self) if self.random.random() < 0.1: cell.state = cell.ALIVE self.grid.place_agent(cell, (x, y)) self.schedule.add(cell) self.running = True def step(self): """ Have the scheduler advance each cell by one step """ self.schedule.step() def on_click(self, x, y, **kwargs): print(x, y) cell = self.grid[x][y] cell.state = cell.ALIVE
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 __init__(self, L, p): super().__init__() self.grid = Grid(L, L, False) self.schedule = SimultaneousActivation(self) self.running = True self.p = p for i in range(L): for j in range(L): if self.random.random() <= self.p: if i == L - 1: tree = TreeAgent((i, j), self, "burning") else: tree = TreeAgent((i, j), self, "occupied") self.schedule.add(tree) self.grid.place_agent(tree, (i, j)) self.datacollector = DataCollector(model_reporters={ "p*": compute_p, "Cluster": compute_cluster })
def __init__(self, data, height=10, width=10, part="Part 1"): """ Create a new playing area of (height, width) cells. """ # Set up the grid and schedule. # Use SimultaneousActivation which simulates all the cells # computing their next state simultaneously. This needs to # be done because each cell's next state depends on the current # state of all its neighbors -- before they've changed. self.schedule = SimultaneousActivation(self) # Use a simple grid, where edges wrap around. self.grid = Grid(height, width, torus=False) self.dc = DataCollector({ "Empty": lambda m: self.count_type(m, Cell.DEAD), "Occupied": lambda m: self.count_type(m, Cell.ALIVE), }) self.numalive = 0 # Place a cell at each location, with some initialized to # ALIVE and some to DEAD. for (contents, x, y) in self.grid.coord_iter(): if data[(len(data) - 1) - y][x] == ".": state = Cell.FLOOR else: state = Cell.DEAD cell = Cell((x, y), self, state, part) self.grid.place_agent(cell, (x, y)) self.schedule.add(cell) self.running = True self.dc.collect(self)
class ConwaysGameOfLife(Model): ''' Represents the 2-dimensional array of cells in Conway's Game of Life. ''' def __init__(self, height=50, width=50): ''' Create a new playing area of (height, width) cells. ''' # Set up the grid and schedule. # Use SimultaneousActivation which simulates all the cells # computing their next state simultaneously. This needs to # be done because each cell's next state depends on the current # state of all its neighbors -- before they've changed. self.schedule = SimultaneousActivation(self) # Use a simple grid, where edges wrap around. self.grid = Grid(height, width, torus=True) # Place a cell at each location, with some initialized to # ALIVE and some to DEAD. for (contents, x, y) in self.grid.coord_iter(): cell = Cell((x, y), self) if self.random.random() < 0.1: cell.state = cell.ALIVE self.grid.place_agent(cell, (x, y)) self.schedule.add(cell) self.running = True def step(self): ''' Have the scheduler advance each cell by one step ''' self.schedule.step()
class CivilViolenceModel(Model): """ Model 1 from "Modeling civil violence: An agent-based computational approach," by Joshua Epstein. http://www.pnas.org/content/99/suppl_3/7243.full Attributes: height: grid height width: grid width citizen_density: approximate % of cells occupied by citizens. cop_density: approximate % of calles occupied by cops. citizen_vision: number of cells in each direction (N, S, E and W) that citizen can inspect cop_vision: number of cells in each direction (N, S, E and W) that cop can inspect legitimacy: (L) citizens' perception of regime legitimacy, equal across all citizens max_jail_term: (J_max) active_threshold: if (grievance - (risk_aversion * arrest_probability)) > threshold, citizen rebels arrest_prob_constant: set to ensure agents make plausible arrest probability estimates movement: binary, whether agents try to move at step end max_iters: model may not have a natural stopping point, so we set a max. """ def __init__(self, height, width, citizen_density, cop_density, citizen_vision, cop_vision, legitimacy, max_jail_term, active_threshold=.1, arrest_prob_constant=2.3, movement=True, max_iters=1000): super(CivilViolenceModel, self).__init__() self.height = height self.width = width self.citizen_density = citizen_density self.cop_density = cop_density self.citizen_vision = citizen_vision self.cop_vision = cop_vision self.legitimacy = legitimacy self.max_jail_term = max_jail_term self.active_threshold = active_threshold self.arrest_prob_constant = arrest_prob_constant self.movement = movement self.running = True self.max_iters = max_iters self.iteration = 0 self.schedule = RandomActivation(self) self.grid = Grid(height, width, torus=True) model_reporters = { "Quiescent": lambda m: self.count_type_citizens(m, "Quiescent"), "Active": lambda m: self.count_type_citizens(m, "Active"), "Jailed": lambda m: self.count_jailed(m)} agent_reporters = { "x": lambda a: a.pos[0], "y": lambda a: a.pos[1], 'breed': lambda a: a.breed, "jail_sentence": lambda a: getattr(a, 'jail_sentence', None), "condition": lambda a: getattr(a, "condition", None), "arrest_probability": lambda a: getattr(a, "arrest_probability", None) } self.dc = DataCollector(model_reporters=model_reporters, agent_reporters=agent_reporters) unique_id = 0 if self.cop_density + self.citizen_density > 1: raise ValueError( 'Cop density + citizen density must be less than 1') for (contents, x, y) in self.grid.coord_iter(): if random.random() < self.cop_density: cop = Cop(unique_id, (x, y), vision=self.cop_vision, model=self) unique_id += 1 self.grid[y][x] = cop self.schedule.add(cop) elif random.random() < ( self.cop_density + self.citizen_density): citizen = Citizen(unique_id, (x, y), hardship=random.random(), regime_legitimacy=self.legitimacy, risk_aversion=random.random(), threshold=self.active_threshold, vision=self.citizen_vision, model=self) unique_id += 1 self.grid[y][x] = citizen self.schedule.add(citizen) def step(self): """ Advance the model by one step and collect data. """ self.schedule.step() self.dc.collect(self) self.iteration += 1 if self.iteration > self.max_iters: self.running = False @staticmethod def count_type_citizens(model, condition, exclude_jailed=True): """ Helper method to count agents by Quiescent/Active. """ count = 0 for agent in model.schedule.agents: if agent.breed == 'cop': continue if exclude_jailed and agent.jail_sentence: continue if agent.condition == condition: count += 1 return count @staticmethod def count_jailed(model): """ Helper method to count jailed agents. """ count = 0 for agent in model.schedule.agents: if agent.breed == 'citizen' and agent.jail_sentence: count += 1 return count
class TestBaseGrid(unittest.TestCase): ''' Testing a non-toroidal grid. ''' torus = False def setUp(self): ''' Create a test non-toroidal grid and populate it with Mock Agents ''' self.grid = Grid(3, 5, self.torus) self.agents = [] counter = 0 for y in range(3): for x in range(5): if TEST_GRID[y][x] == 0: continue counter += 1 # Create and place the mock agent a = MockAgent(counter, None) self.agents.append(a) self.grid.place_agent(a, (x, y)) def test_agent_positions(self): ''' Ensure that the agents are all placed properly. ''' for agent in self.agents: x, y = agent.pos assert self.grid[y][x] == agent def test_cell_agent_reporting(self): ''' Ensure that if an agent is in a cell, get_cell_list_contents accurately reports that fact. ''' for agent in self.agents: x, y = agent.pos assert agent in self.grid.get_cell_list_contents([(x, y)]) def test_listfree_cell_agent_reporting(self): ''' Ensure that if an agent is in a cell, get_cell_list_contents accurately reports that fact, even when single position is not wrapped in a list. ''' for agent in self.agents: x, y = agent.pos assert agent in self.grid.get_cell_list_contents((x, y)) def test_iter_cell_agent_reporting(self): ''' Ensure that if an agent is in a cell, iter_cell_list_contents accurately reports that fact. ''' for agent in self.agents: x, y = agent.pos assert agent in self.grid.iter_cell_list_contents([(x, y)]) def test_listfree_iter_cell_agent_reporting(self): ''' Ensure that if an agent is in a cell, iter_cell_list_contents accurately reports that fact, even when single position is not wrapped in a list. ''' for agent in self.agents: x, y = agent.pos assert agent in self.grid.iter_cell_list_contents((x, y)) def test_neighbors(self): ''' Test the base neighborhood methods on the non-toroid. ''' neighborhood = self.grid.get_neighborhood((1, 1), moore=True) assert len(neighborhood) == 8 neighborhood = self.grid.get_neighborhood((4, 1), moore=True) assert len(neighborhood) == 5 neighborhood = self.grid.get_neighborhood((0, 0), moore=False) assert len(neighborhood) == 2 neighbors = self.grid.get_neighbors((4, 1), moore=False) assert len(neighbors) == 0 neighbors = self.grid.get_neighbors((4, 1), moore=True) assert len(neighbors) == 2 neighbors = self.grid.get_neighbors((1, 1), moore=False, include_center=True) assert len(neighbors) == 3 neighbors = self.grid.get_neighbors((3, 1), moore=False, radius=2) assert len(neighbors) == 4 def test_coord_iter(self): ci = self.grid.coord_iter() # no agent in first space first = next(ci) assert first[0] is None assert first[1] == 0 assert first[2] == 0 # first agent in the second space second = next(ci) assert second[0].unique_id == 1 assert second[0].pos == (1, 0) assert second[1] == 1 assert second[2] == 0
class TestBaseGrid(unittest.TestCase): ''' Testing a non-toroidal grid. ''' torus = False def setUp(self): ''' Create a test non-toroidal grid and populate it with Mock Agents ''' width = 3 # width of grid height = 5 # height of grid self.grid = Grid(width, height, self.torus) self.agents = [] counter = 0 for x in range(width): for y in range(height): if TEST_GRID[x][y] == 0: continue counter += 1 # Create and place the mock agent a = MockAgent(counter, None) self.agents.append(a) self.grid.place_agent(a, (x, y)) def test_agent_positions(self): ''' Ensure that the agents are all placed properly. ''' for agent in self.agents: x, y = agent.pos assert self.grid[x][y] == agent def test_cell_agent_reporting(self): ''' Ensure that if an agent is in a cell, get_cell_list_contents accurately reports that fact. ''' for agent in self.agents: x, y = agent.pos assert agent in self.grid.get_cell_list_contents([(x, y)]) def test_listfree_cell_agent_reporting(self): ''' Ensure that if an agent is in a cell, get_cell_list_contents accurately reports that fact, even when single position is not wrapped in a list. ''' for agent in self.agents: x, y = agent.pos assert agent in self.grid.get_cell_list_contents((x, y)) def test_iter_cell_agent_reporting(self): ''' Ensure that if an agent is in a cell, iter_cell_list_contents accurately reports that fact. ''' for agent in self.agents: x, y = agent.pos assert agent in self.grid.iter_cell_list_contents([(x, y)]) def test_listfree_iter_cell_agent_reporting(self): ''' Ensure that if an agent is in a cell, iter_cell_list_contents accurately reports that fact, even when single position is not wrapped in a list. ''' for agent in self.agents: x, y = agent.pos assert agent in self.grid.iter_cell_list_contents((x, y)) def test_neighbors(self): ''' Test the base neighborhood methods on the non-toroid. ''' neighborhood = self.grid.get_neighborhood((1, 1), moore=True) assert len(neighborhood) == 8 neighborhood = self.grid.get_neighborhood((1, 4), moore=False) assert len(neighborhood) == 3 neighborhood = self.grid.get_neighborhood((1, 4), moore=True) assert len(neighborhood) == 5 neighborhood = self.grid.get_neighborhood((0, 0), moore=False) assert len(neighborhood) == 2 neighbors = self.grid.get_neighbors((4, 1), moore=False) assert len(neighbors) == 0 neighbors = self.grid.get_neighbors((4, 1), moore=True) assert len(neighbors) == 0 neighbors = self.grid.get_neighbors((1, 1), moore=False, include_center=True) assert len(neighbors) == 3 neighbors = self.grid.get_neighbors((1, 3), moore=False, radius=2) assert len(neighbors) == 2 def test_coord_iter(self): ci = self.grid.coord_iter() # no agent in first space first = next(ci) assert first[0] is None assert first[1] == 0 assert first[2] == 0 # first agent in the second space second = next(ci) assert second[0].unique_id == 1 assert second[0].pos == (0, 1) assert second[1] == 0 assert second[2] == 1 def test_agent_move(self): # get the agent at [0, 1] agent = self.agents[0] self.grid.move_agent(agent, (1, 1)) assert agent.pos == (1, 1) # move it off the torus and check for the exception if not self.torus: with self.assertRaises(Exception): self.grid.move_agent(agent, [-1, 1]) with self.assertRaises(Exception): self.grid.move_agent(agent, [1, self.grid.height + 1]) else: self.grid.move_agent(agent, [-1, 1]) assert agent.pos == (self.grid.width - 1, 1) self.grid.move_agent(agent, [1, self.grid.height + 1]) assert agent.pos == (1, 1) def test_agent_remove(self): agent = self.agents[0] x, y = agent.pos self.grid.remove_agent(agent) assert agent.pos is None assert self.grid.grid[x][y] is None
class ColorPatchModel(Model): ''' represents a 2D lattice where agents live ''' def __init__(self, width, height): ''' Create a 2D lattice with strict borders where agents live The agents next state is first determined before updating the grid ''' self._grid = Grid(width, height, 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 (_, row, col) in self._grid.coord_iter(): cell = ColorCell((row, col), self, ColorCell.OPINIONS[random.randrange(0, 16)]) self._grid.place_agent(cell, (row, col)) 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