Exemplo n.º 1
1
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
Exemplo n.º 2
0
class SchellingModel(Model):
    '''
    Model class for the Schelling segregation model.
    '''

    def __init__(self, height, width, density, minority_pc, homophily):
        '''
        '''

        self.height = height
        self.width = width
        self.density = density
        self.minority_pc = minority_pc
        self.homophily = homophily

        self.schedule = RandomActivation(self)
        self.grid = Grid(height, width, torus=True)

        self.happy = 0
        self.datacollector = DataCollector(
            {"happy": lambda m: m.happy}, # Model-level count of happy agents
            # For testing purposes, agent's individual x and y
            {"x": lambda a: a.x, "y": lambda a: a.y}) 

        self.running = True

        # Set up agents
        for x in range(self.width):
            for y in range(self.height):
                if random.random() < self.density:
                    if random.random() < self.minority_pc:
                        agent_type = 1
                    else:
                        agent_type = 0

                    agent = SchellingAgent((x,y), x, y, agent_type)
                    self.grid[y][x] = agent
                    self.schedule.add(agent)

    def get_empty(self):
        '''
        Get a list of coordinate tuples of currently-empty cells.
        '''
        empty_cells = []
        for x in range(self.width):
            for y in range(self.height):
                if self.grid[y][x] is None:
                    empty_cells.append((x, y))
        return empty_cells

    def step(self):
        '''
        Run one step of the model. If All agents are happy, halt the model.
        '''
        self.happy = 0 # Reset counter of happy agents
        self.schedule.step()
        self.datacollector.collect(self)

        if self.happy == self.schedule.get_agent_count():
            self.running = False
Exemplo n.º 3
0
Arquivo: model.py Projeto: GeoESW/mesa
class ShapesModel(Model):
    def __init__(self, N, width=20, height=10):
        self.running = True
        self.N = N    # num of agents
        self.headings = ((1, 0), (0, 1), (-1, 0), (0, -1))  # tuples are fast
        self.grid = SingleGrid(width, height, torus=False)
        self.schedule = RandomActivation(self)
        self.make_walker_agents()

    def make_walker_agents(self):
        unique_id = 0
        while True:
            if unique_id == self.N:
                break
            x = random.randrange(self.grid.width)
            y = random.randrange(self.grid.height)
            pos = (x, y)
            heading = random.choice(self.headings)
            # heading = (1, 0)
            if self.grid.is_cell_empty(pos):
                print("Creating agent {2} at ({0}, {1})"
                      .format(x, y, unique_id))
                a = Walker(unique_id, self, pos, heading)
                self.schedule.add(a)
                self.grid.place_agent(a, pos)
                unique_id += 1

    def step(self):
        self.schedule.step()
Exemplo n.º 4
0
class MoneyModel(Model):
    """A model with some number of agents."""
    def __init__(self, N, width, height):
        self.num_agents = N
        self.running = True
        self.grid = MultiGrid(height, width, True)
        self.schedule = RandomActivation(self)
        self.datacollector = DataCollector(model_reporters={"Gini": compute_gini},
                agent_reporters={"Wealth": lambda a: a.wealth})
        # Create agents
        for i in range(self.num_agents):
            a = MoneyAgent(i)
            self.schedule.add(a)
            # Add the agent to a random grid cell
            x = random.randrange(self.grid.width)
            y = random.randrange(self.grid.height)
            self.grid.place_agent(a, (x, y))

    def step(self):
        self.datacollector.collect(self)
        self.schedule.step()
    
    def run_model(self, n):
        for i in range(n):
            self.step()
Exemplo n.º 5
0
class WorldModel(Model):
    def __init__(self, N, width, height):
        self.grid = SingleGrid(height, width, True)

        self.schedule = RandomActivation(self)
        self.num_agents = N
        self.running = True
        
        for i in range(self.num_agents):
            ethnicity = random.choice(Ethnicities)
            a = PersonAgent(unique_id=i,
                            model=self,
                            ethnicity=int(ethnicity)
                            )
            self.schedule.add(a)
            # Add the agent to a random grid cell

            self.grid.position_agent(a)
            
        self.datacollector = DataCollector(
            agent_reporters={
                "Nationalism": lambda a: a.nationalism,
                "X": lambda a: a.pos[0],
                "Y": lambda a: a.pos[1]
            }
        )

    def step(self):
        self.datacollector.collect(self)
        self.schedule.step()
Exemplo n.º 6
0
class WalkerWorld(Model):
    '''
    Random walker world.
    '''
    height = 10
    width = 10

    def __init__(self, height, width, agent_count):
        '''
        Create a new WalkerWorld.

        Args:
            height, width: World size.
            agent_count: How many agents to create.
        '''
        self.height = height
        self.width = width
        self.grid = MultiGrid(self.height, self.width, torus=True)
        self.agent_count = agent_count

        self.schedule = RandomActivation(self)
        # Create agents
        for i in range(self.agent_count):
            x = random.randrange(self.width)
            y = random.randrange(self.height)
            a = WalkerAgent((x, y), self, True)
            self.schedule.add(a)
            self.grid.place_agent(a, (x, y))

    def step(self):
        self.schedule.step()
class Money_Model(Model):
    def __init__(self, N, width=50, height=50, torus=True):
        self.num_agents = N
        self.schedule = RandomActivation(self)
        self.grid = MultiGrid(height, width, torus)
        self.create_agents()
        self.dc = DataCollector({"Gini": lambda m: m.compute_gini()},
                               {"Wealth": lambda a: a.wealth})
        self.running = True

    def create_agents(self):
        for i in range(self.num_agents):
            a = Money_Agent(i)
            self.schedule.add(a)
            x = random.randrange(self.grid.width)
            y = random.randrange(self.grid.height)
            self.grid.place_agent(a, (x, y))

    def step(self):
        self.dc.collect(self)
        self.schedule.step()
        
    def run_model(self, steps):
        for i in range(steps):
            self.step()
    
    def compute_gini(self):
        agent_wealths = [agent.wealth for agent in self.schedule.agents]
        x = sorted(agent_wealths)
        N = self.num_agents
        B = sum( xi * (N-i) for i,xi in enumerate(x) ) / (N*sum(x))
        return (1 + (1/N) - 2*B)
Exemplo n.º 8
0
Arquivo: model.py Projeto: GeoESW/mesa
class MoneyModel(Model):
    """A simple model of an economy where agents exchange currency at random.

    All the agents begin with one unit of currency, and each time step can give
    a unit of currency to another agent. Note how, over time, this produces a
    highly skewed distribution of wealth.
    """

    def __init__(self, N, width, height):
        self.num_agents = N
        self.running = True
        self.grid = MultiGrid(height, width, True)
        self.schedule = RandomActivation(self)
        self.datacollector = DataCollector(
            model_reporters={"Gini": compute_gini},
            agent_reporters={"Wealth": lambda a: a.wealth}
        )
        # Create agents
        for i in range(self.num_agents):
            a = MoneyAgent(i, self)
            self.schedule.add(a)
            # Add the agent to a random grid cell
            x = random.randrange(self.grid.width)
            y = random.randrange(self.grid.height)
            self.grid.place_agent(a, (x, y))

    def step(self):
        self.datacollector.collect(self)
        self.schedule.step()

    def run_model(self, n):
        for i in range(n):
            self.step()
Exemplo n.º 9
0
class BoltzmannWealthModelNetwork(Model):
    """A model with some number of agents."""

    def __init__(self, num_agents=7, num_nodes=10):

        self.num_agents = num_agents
        self.num_nodes = num_nodes if num_nodes >= self.num_agents else self.num_agents
        self.G = nx.erdos_renyi_graph(n=self.num_nodes, p=0.5)
        self.grid = NetworkGrid(self.G)
        self.schedule = RandomActivation(self)
        self.datacollector = DataCollector(
            model_reporters={"Gini": compute_gini},
            agent_reporters={"Wealth": lambda _: _.wealth}
        )

        list_of_random_nodes = self.random.sample(self.G.nodes(), self.num_agents)

        # Create agents
        for i in range(self.num_agents):
            a = MoneyAgent(i, self)
            self.schedule.add(a)
            # Add the agent to a random node
            self.grid.place_agent(a, list_of_random_nodes[i])

        self.running = True
        self.datacollector.collect(self)

    def step(self):
        self.schedule.step()
        # collect data
        self.datacollector.collect(self)

    def run_model(self, n):
        for i in range(n):
            self.step()
Exemplo n.º 10
0
class Foraging(Model):
    
    number_of_bean = 0
    number_of_corn = 0
    number_of_soy = 0
    
    def __init__(self, width=50, height=50, torus=True, num_bug=50, seed=42, strategy=None):
        super().__init__(seed=seed)
        self.number_of_bug = num_bug
        if not(strategy in ["stick", "switch"]):
            raise TypeError("'strategy' must be one of {stick, switch}")
        self.strategy = strategy
        
        self.grid = SingleGrid(width, height, torus)
        self.schedule = RandomActivation(self)
        data = {"Bean": lambda m: m.number_of_bean,
                "Corn": lambda m: m.number_of_corn,
                "Soy": lambda m: m.number_of_soy,
                "Bug": lambda m: m.number_of_bug,
                }
        self.datacollector = DataCollector(data)
        
        # create foods
        self._populate(Bean)
        self._populate(Corn)
        self._populate(Soy)
        
        # create bugs
        for i in range(self.number_of_bug):
            pos = self.grid.find_empty()
            bug = Bug(i, self)
            bug.strategy = self.strategy
            self.grid.place_agent(bug, pos)
            self.schedule.add(bug)
    
    def step(self):
        self.schedule.step()
        self.datacollector.collect(self)
        
        if not(self.grid.exists_empty_cells()):
            self.running = False
    
    def _populate(self, food_type):
        prefix = "number_of_{}"
        
        counter = 0
        while counter < food_type.density * (self.grid.width * self.grid.height):
            pos = self.grid.find_empty()
            food = food_type(counter, self)
            self.grid.place_agent(food, pos)
            self.schedule.add(food)
            food_name = food_type.__name__.lower()
            attr_name = prefix.format(food_name)
            val = getattr(self, attr_name)
            val += 1
            setattr(self, attr_name, val)
            counter += 1
Exemplo n.º 11
0
class Charts(Model):

    # grid height
    grid_h = 20
    # grid width
    grid_w = 20

    """init parameters "init_people", "rich_threshold", and "reserve_percent"
       are all UserSettableParameters"""
    def __init__(self, height=grid_h, width=grid_w, init_people=2, rich_threshold=10,
                 reserve_percent=50,):
        self.height = height
        self.width = width
        self.init_people = init_people
        self.schedule = RandomActivation(self)
        self.grid = MultiGrid(self.width, self.height, torus=True)
        # rich_threshold is the amount of savings a person needs to be considered "rich"
        self.rich_threshold = rich_threshold
        self.reserve_percent = reserve_percent
        # see datacollector functions above
        self.datacollector = DataCollector(model_reporters={
                                           "Rich": get_num_rich_agents,
                                           "Poor": get_num_poor_agents,
                                           "Middle Class": get_num_mid_agents,
                                           "Savings": get_total_savings,
                                           "Wallets": get_total_wallets,
                                           "Money": get_total_money,
                                           "Loans": get_total_loans},
                                           agent_reporters={
                                           "Wealth": lambda x: x.wealth})

        # create a single bank for the model
        self.bank = Bank(1, self, self.reserve_percent)

        # create people for the model according to number of people set by user
        for i in range(self.init_people):
            # set x, y coords randomly within the grid
            x = self.random.randrange(self.width)
            y = self.random.randrange(self.height)
            p = Person(i, (x, y), self, True, self.bank, self.rich_threshold)
            # place the Person object on the grid at coordinates (x, y)
            self.grid.place_agent(p, (x, y))
            # add the Person object to the model schedule
            self.schedule.add(p)

        self.running = True
        self.datacollector.collect(self)

    def step(self):
        # tell all the agents in the model to run their step function
        self.schedule.step()
        # collect data
        self.datacollector.collect(self)

    def run_model(self):
        for i in range(self.run_time):
            self.step()
Exemplo n.º 12
0
class Schelling(Model):
    '''
    Model class for the Schelling segregation model.
    '''

    def __init__(self, height=20, width=20, density=0.8, minority_pc=0.2, homophily=3):
        '''
        '''

        self.height = height
        self.width = width
        self.density = density
        self.minority_pc = minority_pc
        self.homophily = homophily

        self.schedule = RandomActivation(self)
        self.grid = SingleGrid(height, width, torus=True)

        self.happy = 0
        self.datacollector = 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]})

        # 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 = cell[1]
            y = cell[2]
            if self.random.random() < self.density:
                if self.random.random() < self.minority_pc:
                    agent_type = 1
                else:
                    agent_type = 0

                agent = SchellingAgent((x, y), self, agent_type)
                self.grid.position_agent(agent, (x, y))
                self.schedule.add(agent)

        self.running = True
        self.datacollector.collect(self)

    def step(self):
        '''
        Run one step of the model. If All agents are happy, halt the model.
        '''
        self.happy = 0  # Reset counter of happy agents
        self.schedule.step()
        # collect data
        self.datacollector.collect(self)

        if self.happy == self.schedule.get_agent_count():
            self.running = False
Exemplo n.º 13
0
class SchellingModel(Model):
    """
    Model class for the Schelling segregation model.
    """

    def __init__(self, height, width, density, minority_pc, homophily):
        """
        """

        self.height = height
        self.width = width
        self.density = density
        self.minority_pc = minority_pc
        self.homophily = homophily

        self.schedule = RandomActivation(self)
        self.grid = SingleGrid(height, width, torus=True)

        self.happy = 0
        self.total_agents = 0
        self.datacollector = DataCollector(
            {"unhappy": lambda m: m.total_agents - m.happy},
            # For testing purposes, agent's individual x and y
            {"x": lambda a: a.pos[X], "y": lambda a: a.pos[Y]},
        )

        self.running = True

        # Set up agents
        # We use a grid iterator that returns
        # the coordinates of a cell as well as
        # its contents. (coord_iter)
        for cell, x, y in self.grid.coord_iter():
            if random.random() < self.density:
                if random.random() < self.minority_pc:
                    agent_type = 1
                else:
                    agent_type = 0

                agent = SchellingAgent(self.total_agents, agent_type)
                self.grid.position_agent(agent, x, y)
                self.schedule.add(agent)
                self.total_agents += 1

    def step(self):
        """
        Run one step of the model. If All agents are happy, halt the model.
        """
        self.happy = 0  # Reset counter of happy agents
        self.schedule.step()
        self.datacollector.collect(self)

        if self.happy == self.total_agents:
            self.running = False
Exemplo n.º 14
0
Arquivo: model.py Projeto: GeoESW/mesa
class BoidModel(Model):
    '''
    Flocker model class. Handles agent creation, placement and scheduling.
    '''

    def __init__(self,
                 population=100,
                 width=100,
                 height=100,
                 speed=1,
                 vision=10,
                 separation=2,
                 cohere=0.025,
                 separate=0.25,
                 match=0.04):
        '''
        Create a new Flockers model.

        Args:
            population: Number of Boids
            width, height: Size of the space.
            speed: How fast should the Boids move.
            vision: How far around should each Boid look for its neighbors
            separation: What's the minimum distance each Boid will attempt to
                    keep from any other
            cohere, separate, match: factors for the relative importance of
                    the three drives.        '''
        self.population = population
        self.vision = vision
        self.speed = speed
        self.separation = separation
        self.schedule = RandomActivation(self)
        self.space = ContinuousSpace(width, height, True,
                                     grid_width=10, grid_height=10)
        self.factors = dict(cohere=cohere, separate=separate, match=match)
        self.make_agents()
        self.running = True

    def make_agents(self):
        '''
        Create self.population agents, with random positions and starting headings.
        '''
        for i in range(self.population):
            x = random.random() * self.space.x_max
            y = random.random() * self.space.y_max
            pos = np.array((x, y))
            velocity = np.random.random(2) * 2 - 1
            boid = Boid(i, self, pos, self.speed, velocity, self.vision,
                        self.separation, **self.factors)
            self.space.place_agent(boid, pos)
            self.schedule.add(boid)

    def step(self):
        self.schedule.step()
Exemplo n.º 15
0
class MoneyModel(Model):
    """A model with some number of agents."""
    def __init__(self, N):
        self.num_agents = N
        self.schedule = RandomActivation(self)
        # Create agents
        for i in range(self.num_agents):
            a = MoneyAgent(i)
            self.schedule.add(a)

    def step(self):
        '''Advance the model by one step.'''
        self.schedule.step()
Exemplo n.º 16
0
class VirusOnNetwork(Model):
    """A virus model with some number of agents"""

    def __init__(self, num_nodes=10, avg_node_degree=3, initial_outbreak_size=1, virus_spread_chance=0.4,
                virus_check_frequency=0.4, recovery_chance=0.3, gain_resistance_chance=0.5):

        self.num_nodes = num_nodes
        prob = avg_node_degree / self.num_nodes
        self.G = nx.erdos_renyi_graph(n=self.num_nodes, p=prob)
        self.grid = NetworkGrid(self.G)
        self.schedule = RandomActivation(self)
        self.initial_outbreak_size = initial_outbreak_size if initial_outbreak_size <= num_nodes else num_nodes
        self.virus_spread_chance = virus_spread_chance
        self.virus_check_frequency = virus_check_frequency
        self.recovery_chance = recovery_chance
        self.gain_resistance_chance = gain_resistance_chance

        self.datacollector = DataCollector({"Infected": number_infected,
                                            "Susceptible": number_susceptible,
                                            "Resistant": number_resistant})

        # Create agents
        for i, node in enumerate(self.G.nodes()):
            a = VirusAgent(i, self, State.SUSCEPTIBLE, self.virus_spread_chance, self.virus_check_frequency,
                           self.recovery_chance, self.gain_resistance_chance)
            self.schedule.add(a)
            # Add the agent to the node
            self.grid.place_agent(a, node)

        # Infect some nodes
        infected_nodes = self.random.sample(self.G.nodes(), self.initial_outbreak_size)
        for a in self.grid.get_cell_list_contents(infected_nodes):
            a.state = State.INFECTED

        self.running = True
        self.datacollector.collect(self)

    def resistant_susceptible_ratio(self):
        try:
            return number_state(self, State.RESISTANT) / number_state(self, State.SUSCEPTIBLE)
        except ZeroDivisionError:
            return math.inf

    def step(self):
        self.schedule.step()
        # collect data
        self.datacollector.collect(self)

    def run_model(self, n):
        for i in range(n):
            self.step()
Exemplo n.º 17
0
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
Exemplo n.º 18
0
class SchellingModel(Model):
    '''
    Model class for the Schelling segregation model.
    '''

    def __init__(self, height, width, density, type_pcs=[.2, .2, .2, .2, .2]):
        '''
        '''

        self.height = height
        self.width = width
        self.density = density
        self.type_pcs = type_pcs

        self.schedule = RandomActivation(self)
        self.grid = SingleGrid(height, width, torus=False)

        self.happy = 0
        self.datacollector = DataCollector(
            {"happy": lambda m: m.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]})

        self.running = True

        # Set up agents
        # We use a grid iterator that returns
        # the coordinates of a cell as well as
        # its contents. (coord_iter)

        total_agents = self.height * self.width * self.density
        agents_by_type = [total_agents*val for val in self.type_pcs]

        for loc, types in enumerate(agents_by_type):
            for i in range(int(types)):
                pos = self.grid.find_empty()
                agent = SchellingAgent(pos, self, loc)
                self.grid.position_agent(agent, pos)
                self.schedule.add(agent)

    def step(self):
        '''
        Run one step of the model. If All agents are happy, halt the model.
        '''
        self.happy = 0  # Reset counter of happy agents
        self.schedule.step()
        self.datacollector.collect(self)

        if self.happy == self.schedule.get_agent_count():
            self.running = False
Exemplo n.º 19
0
class VirusModel(Model):
    """A virus model with some number of agents"""

    def __init__(self, num_nodes, avg_node_degree, initial_outbreak_size, virus_spread_chance, virus_check_frequency,
                 recovery_chance, gain_resistance_chance):

        self.num_nodes = num_nodes
        prob = avg_node_degree / self.num_nodes
        self.G = nx.erdos_renyi_graph(n=self.num_nodes, p=prob)
        self.grid = NetworkGrid(self.G)
        self.schedule = RandomActivation(self)
        self.initial_outbreak_size = initial_outbreak_size if initial_outbreak_size <= num_nodes else num_nodes
        self.virus_spread_chance = virus_spread_chance
        self.virus_check_frequency = virus_check_frequency
        self.recovery_chance = recovery_chance
        self.gain_resistance_chance = gain_resistance_chance
        self.running = True

        self.datacollector = DataCollector({"Infected": number_infected,
                                            "Susceptible": number_susceptible,
                                            "Resistant": number_resistant})

        # Create agents
        for i, node in enumerate(self.G.nodes()):
            a = VirusAgent(i, self, State.SUSCEPTIBLE, self.virus_spread_chance, self.virus_check_frequency,
                           self.recovery_chance, self.gain_resistance_chance)
            self.schedule.add(a)
            # Add the agent to the node
            self.grid.place_agent(a, node)

        # Infect some nodes
        infected_nodes = random.sample(self.G.nodes(), self.initial_outbreak_size)
        for a in self.grid.get_cell_list_contents(infected_nodes):
            a.state = State.INFECTED

    def resistant_susceptible_ratio(self):
        try:
            return number_state(self, State.RESISTANT) / number_state(self, State.SUSCEPTIBLE)
        except ZeroDivisionError:
            return math.inf

    def step(self):
        self.schedule.step()
        self.datacollector.collect(self)

    def run_model(self, n):
        for i in range(n):
            self.step()
Exemplo n.º 20
0
class NewModel(Model):
    def __init__(self, width, height, num_agents):
        self.schedule = RandomActivation(self)
        self.grid = SingleGrid(width, height, torus = True)
        self.num_agents = num_agents
        
        # to collect info about how many agents are happy, average similarity of neighbors, length of residence
        self.datacollector = DataCollector(model_reporters = {"Happy": lambda m: m.happy, "Similar": lambda m: m.similar, "Residence": lambda m: m.avg_residence}, agent_reporters = {"x": lambda a: a.pos[0], "y": lambda a: a.pos[1]})
        
        self.avg_residence = 0
        self.happy = 0
        self.similar = 0
        self.running = True
        
        for i in range(self.num_agents):   
            # white
            if random.random() < 0.70:
                agent_type = 1
                income = np.random.normal(54000, 41000)
            
            # black
            else:
                agent_type = 0
                income = np.random.normal(32000, 40000)

            # add new agents
            agent = NewAgent(i, self, agent_type, income)
            self.schedule.add(agent)
            
            # assign the initial coords of the agents
            x = self.random.randrange(self.grid.width)
            y = self.random.randrange(self.grid.height)

            self.grid.position_agent(agent, (x, y))
            
    def step(self):
        '''Advance the model by one step.'''

        self.happy = 0
        self.schedule.step()
        # get the average similarity
        self.similar /= self.num_agents
        # get the average length of residence
        self.avg_residence /= self.num_agents
        self.datacollector.collect(self)
       
        if self.happy == self.schedule.get_agent_count():
            self.running = False
Exemplo n.º 21
0
class SchellingModel(Model):
    """Model class for the Schelling segregation model."""
    def __init__(self, density, minority_pc):
        self.density = density
        self.minority_pc = minority_pc

        self.schedule = RandomActivation(self)
        self.grid = GeoSpace(crs='epsg:4326')

        self.happy = 0
        self.datacollector = DataCollector(
            {"happy": lambda m: m.happy})  # Model-level count of happy agents

        self.running = True

        # Set up the grid with patches for every NUTS region
        regions = geojson.load(open('nuts_rg_60M_2013_lvl_2.geojson'))
        self.grid.create_agents_from_GeoJSON(regions,
                                             SchellingAgent,
                                             model=self,
                                             unique_id='NUTS_ID')

        # Set up agents
        for agent in self.grid.agents:
            if random.random() < self.density:
                if random.random() < self.minority_pc:
                    agent.atype = 1
                else:
                    agent.atype = 0
                self.schedule.add(agent)

        # Update the bounding box of the grid and create a new rtree
        self.grid.update_bbox()
        self.grid.create_rtree()

    def step(self):
        """Run one step of the model.

        If All agents are happy, halt the model.
        """
        self.happy = 0  # Reset counter of happy agents
        self.schedule.step()
        self.datacollector.collect(self)

        if self.happy == self.schedule.get_agent_count():
            self.running = False

        self.grid.create_rtree()
Exemplo n.º 22
0
class WalkingModel(Model):
    def __init__(self, N, width, height):
        self.num_agents = N
        self.schedule = RandomActivation(self)
        self.grid = MultiGrid(width, height, True)
        self.running = True
        self.allAgents = []

        # create a grid with travel(grocery, social areas), home, and work locations
        # self.allLocations = {}
        num_travel = int(self.num_agents / 10)  # number of travel locations
        num_work = int(self.num_agents / 5)
        self.travelLocs = [(random.randint(0, width - 1),
                            random.randint(0, height - 1))
                           for i in range(num_travel)]
        self.workLocs = [(random.randint(0, width - 1),
                          random.randint(0, height - 1))
                         for i in range(num_work)]

        self.homeLocs = []
        for i in range(self.num_agents):
            homeX, homeY = random.randint(0, width - 1), random.randint(
                0, height - 1)
            while (homeX, homeY) in self.workLocs or (
                    homeX, homeY
            ) in self.travelLocs:  # "reroll" the home location if it already exists
                homeX, homeY = random.randint(0, width - 1), random.randint(
                    0, height - 1)

            self.homeLocs.append((homeX, homeY))

            agent = WalkingAgent(i, self, self.homeLocs[i],
                                 random.choice(self.workLocs))
            self.schedule.add(agent)
            self.grid.place_agent(agent, agent.home)
            self.allAgents.append(agent)

        ## displaying how many of each location there are
        # homeCount = len(self.homeLocs)
        # workCount = len(self.workLocs)
        # travelCount = len(self.travelLocs)
        # print(homeCount, workCount, travelCount)

    def getWorkLocs(self):
        return self.workLocs

    def getHomeLocs(self):
        return self.homeLocs
Exemplo n.º 23
0
class ScientistModel(Model):
    def __init__(self, N, ideas_per_time, time_periods):

        # Scalar: indicates the total number of scientists in the model
        # N is the number of scientists per time period
        self.num_scientists = N * time_periods

        # Scalar: number of ideas unique to each time period
        self.ideas_per_time = ideas_per_time

        # Scalar: total number of ideas in the model. +2 is used to account
        # for first two, non-steady state time periods
        self.total_ideas = ideas_per_time * (time_periods + 2)

        # Array: stores the max investment allowed for each idea
        self.max_investment = poisson(lam=10, size=self.total_ideas)

        # Array: store parameters for true idea return distribution
        self.true_sds = poisson(4, size=self.total_ideas)
        self.true_means = poisson(25, size=self.total_ideas)

        # Ensures that none of the standard devs are equal to 0
        self.true_sds += 1

        # Array: keeps track of total effort allocated to each idea across all
        # scientists
        self.total_effort = np.zeros(self.total_ideas)

        # Make scientists choose ideas and allocate effort in a random order
        # for each step of the model (i.e. within a time period, the order
        # in which young and old scientists get to invest in ideas is random)
        self.schedule = RandomActivation(self)
        for i in range(4, self.num_scientists + 4):
            a = Scientist(i, self)
            self.schedule.add(a)

        # Create data collector method for keeping track of variables over time
        self.datacollector = DataCollector(
            model_reporters={"Total effort": "total_effort"},
            agent_reporters={
                "Effort invested": "effort_invested",
                "Perceived returns": "perceived_returns"
            })

    def step(self):
        # Call data collector to keep track of variables at each model step
        self.datacollector.collect(self)
        self.schedule.step()
Exemplo n.º 24
0
class MoneyModel(Model):
    """A model with some number of agents."""
    def __init__(self, N):
        self.num_agents = N
        # Create agents
        self.schedule = RandomActivation(self)
        # Create agents
        for i in range(self.num_agents):
            wages = float(randint(1, 10))
            exp = random() / 2
            a = MoneyAgent(i, wages, exp, self)
            self.schedule.add(a)

    def step(self):
        '''Advance the model by one step.'''
        self.schedule.step()
Exemplo n.º 25
0
class Warehouse(Model):
    def __init__(self, world, tsp_seqs, last_sim_step):
        self.schedule = RandomActivation(self)
        self.world = world
        self.tsp_seq = tsp_seqs
        self.last_sim_step = last_sim_step
        self.time_step = 0
        self.task_count = 0
        self.grid = MultiGrid(world.width, world.height, torus=False)
        self.data_collector = DataCollector(
            {"task_count": "task_count"}
        )
        self.robot_count = 0
        # Set up MultiGrid from csv map
        for element in world:
            if world[element] == MAPNODETYPES.WALL:
                # Wall
                agent = Wall(element, self)
                self.grid.place_agent(agent, element)
                self.schedule.add(agent)
                # Task endpoint
            elif world[element] == MAPNODETYPES.TASK_ENDPOINT:
                agent = Space(element, self)
                self.grid.place_agent(agent, element)
                self.schedule.add(agent)
                # Robot spawn endpoint
            elif world[element] == MAPNODETYPES.PARKING:
                # Parking location
                agent = Parking(element, self)
                self.grid.place_agent(agent, element)
                self.schedule.add(agent)
                # Robot location (At park initially)
                self.robot_count += 1
                agent = Robot(element, self, world.agents[self.robot_count].path)
                self.grid.place_agent(agent, element)
                self.schedule.add(agent)
        self.running = True

    def step(self):
        new_task_count = 0
        # Update tasks counter
        for seq_id in self.tsp_seq:
            if self.tsp_seq[seq_id].qsize() > 0:
                if self.time_step >= self.tsp_seq[seq_id].queue[0].release_time:
                    if self.time_step in self.world.agents[seq_id].path:
                        if self.tsp_seq[seq_id].queue[0].delivery_endpoint == \
                                self.world.agents[seq_id].path[self.time_step]:
                            self.tsp_seq[seq_id].get()
            new_task_count += self.tsp_seq[seq_id].qsize()
        self.task_count = new_task_count
        # Stop running once finished
        if self.time_step >= self.last_sim_step:
            self.running = False
        # Next step
        self.time_step += 1
        self.schedule.step()
        self.data_collector.collect(self)
Exemplo n.º 26
0
class Simulation(Model):
    """A model with some number of agents."""
    def __init__(self, params, seed=None):
        #self.num_agents = params.get('num_persons')
        self.num_agents = int(
            params.get('density') * params.get('grid_x') *
            params.get('grid_y'))
        self.grid = MultiGrid(params.get('grid_x'), params.get('grid_y'), True)
        self.schedule = RandomActivation(self)
        self.start_infected = params.get('initial_infected')
        self.recovery_period = params.get('recovery_period')
        self.infect_rate = params.get('infect_rate')
        self.mortality_rate = params.get(
            'mortality_rate') / self.recovery_period
        self.active_ratio = params.get('active_ratio')
        self.immunity_chance = params.get('immunity_chance')
        self.quarantine_rate = params.get('quarantine_rate')
        self.lockdown_rate = params.get('lockdown_rate')

        self.running = True
        self.current_cycle = 0

        # Create agents
        for i in range(self.num_agents):
            a = Person(i, self)
            if self.random.random() < self.start_infected:
                a.set_infected()
            if self.random.random() < self.lockdown_rate:
                a.set_lockdown()
            self.schedule.add(a)
            # Add the agent to a random grid cell
            x = self.random.randrange(self.grid.width)
            y = self.random.randrange(self.grid.height)
            self.grid.place_agent(a, (x, y))

        self.datacollector = DataCollector(
            model_reporters={
                "Infected": total_infected,
                "Deaths": total_deaths,
                "Immune": total_immune
            })

    def step(self):
        '''Advance the model by one step.'''
        self.datacollector.collect(self)
        self.schedule.step()
        self.current_cycle += 1
Exemplo n.º 27
0
class SegregationModel(Model):
    def __init__(self, number_of_agents, width, height, happiness_threshold,
                 minority_rate):
        self.num_agents = number_of_agents
        self.grid = MultiGrid(width, height, False)
        self.schedule = RandomActivation(self)

        ## Create Agents
        number_of_minority = round(number_of_agents * (minority_rate))
        for i in range(number_of_agents):
            if (i + 1) <= number_of_minority:
                ethnicity = 1
            else:
                ethnicity = 2
            a = SegregationAgent(i, ethnicity, happiness_threshold, self)
            self.schedule.add(a)

            # place agent on grid
            # x = self.random.randrange(self.grid.width)
            # y = self.random.randrange(self.grid.height)
            empty_place = self.grid.find_empty()
            self.grid.place_agent(a, empty_place)
            logger.info("Agent " + str(i) + " placed in " + str(empty_place))

        self.datacollector = DataCollector(
            agent_reporters={"Happiness": "happy"},
            model_reporters={"Overall_happiness": overall_happiness},
        )

    def plot_grid(self):
        ethnicities = np.zeros((self.grid.width, self.grid.height))

        for cell in self.grid.coord_iter():
            cell_content, x, y = cell
            agent_present = len(cell_content)
            if agent_present > 0:
                cell_content = list(cell_content)
                ethnicities[x][y] = cell_content[0].ethnicity

        plt.imshow(ethnicities, interpolation="nearest")
        plt.colorbar()
        plt.show()

    def step(self):
        self.datacollector.collect(self)
        self.schedule.step()
        self.plot_grid()
Exemplo n.º 28
0
class SchellingModel(Model):
    '''
    Model class for the Schelling segregation model.
    '''
    def __init__(self,
                 height=50,
                 width=50,
                 density=0.8,
                 minority_pc=0.5,
                 homophily=3):
        '''
        '''

        self.height = height
        self.width = width
        self.density = density
        self.minority_pc = minority_pc
        self.homophily = homophily

        self.schedule = RandomActivation(self)
        self.grid = SingleGrid(height, width, torus=True)

        self.happy = 0

        # 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 = cell[1]
            y = cell[2]
            if random.random() < self.density:
                if random.random() < self.minority_pc:
                    agent_type = 1
                else:
                    agent_type = 0

                agent = SchellingAgent((x, y), self, agent_type)
                self.grid.position_agent(agent, (x, y))
                self.schedule.add(agent)

    def step(self):
        '''
        Run one step of the model.
        '''
        self.happy = 0  # Reset counter of happy agents
        self.schedule.step()
Exemplo n.º 29
0
class BoidModel(Model):
    '''
    Flocker model class. Handles agent creation, placement and scheduling.
    '''
    N = 100
    width = 100
    height = 100

    def __init__(self, N, width, height, speed, vision, separation):
        '''
        Create a new Flockers model.

        Args:
            N: Number of Boids
            width, height: Size of the space.
            speed: How fast should the Boids move.
            vision: How far around should each Boid look for its neighbors
            separtion: What's the minimum distance each Boid will attempt to
                       keep from any other
        '''
        self.N = N
        self.vision = vision
        self.speed = speed
        self.separation = separation
        self.schedule = RandomActivation(self)
        self.space = ContinuousSpace(width, height, True,
            grid_width=10, grid_height=10)
        self.make_agents()
        self.running = True

    def make_agents(self):
        '''
        Create N agents, with random positions and starting headings.
        '''
        for i in range(self.N):
            x = random.random() * self.space.x_max
            y = random.random() * self.space.y_max
            pos = (x, y)
            heading = np.random.random(2) * 2 - np.array((1, 1))
            heading /= np.linalg.norm(heading)
            boid = Boid(i, pos, self.speed, heading, self.vision, self.separation)
            self.space.place_agent(boid, pos)
            self.schedule.add(boid)

    def step(self):
        self.schedule.step()
Exemplo n.º 30
0
class ArgumentModel(Model):
    """ ArgumentModel which inherit from Model.
    """
    def __init__(self):
        self.schedule = RandomActivation(self)
        self.__messages_service = MessageService(self.schedule)
        Item1 = Item('Item1', description='first item')
        Item2 = Item('Item2', description='second item')
        self.list_items = [Item1, Item2]
        for i in range(2):
            a = ArgumentAgent(i, self, "Agent" + str(i), self.list_items)
            self.schedule.add(a)
        self.running = True

    def step(self):
        self.__messages_service.dispatch_messages()
        self.schedule.step()
Exemplo n.º 31
0
class AlertSystem(Model):
    """A model with some number of agents."""
    def __init__(self, server=None):
        self.agents = [AlertAgent, DialAgent]
        self.schedule = RandomActivation(self)
        if server is not None:
            self.server = server
        else:
            self.server = Server(system=self)
        # Create agents
        for i, ag in enumerate(self.agents):
            a = ag(i, self)
            self.schedule.add(a)

    def step(self):
        '''Advance the model by one step.'''
        self.schedule.step()
Exemplo n.º 32
0
class FirmModel(Model):
    """A model with some number of agents."""
    def __init__(self, N):
        self.alpha = 0.5
        self.beta = 1 - self.alpha
        self.num_agents = N
        # Create agents
        self.schedule = RandomActivation(self)
        # Create agents
        for i in range(self.num_agents):
            exp = random()
            a = FirmAgent(i, exp, self)
            self.schedule.add(a)

    def step(self):
        '''Advance the model by one step.'''
        self.schedule.step()
Exemplo n.º 33
0
class MoneyModel(Model):
    def __init__(self, number_of_agents, width, height):
        self.num_agents = number_of_agents
        self.grid = MultiGrid(width, height, True)
        self.schedule = RandomActivation(self)

        # Create agents
        for i in range(number_of_agents):
            a = MoneyAgent(i, self)
            self.schedule.add(a)

            ## place agent on grid
            x = self.random.randrange(self.grid.width)
            y = self.random.randrange(self.grid.height)
            self.grid.place_agent(a, (x, y))

            # start datacollector
            self.datacollector = DataCollector(
                model_reporters={"Gini": compute_gini},
                agent_reporters={"Wealth": "wealth"},
            )

    def plot_grid(self):
        agent_counts = np.zeros((self.grid.width, model.grid.height))

        for cell in self.grid.coord_iter():
            cell_content, x, y = cell
            agent_count = len(cell_content)
            agent_counts[x][y] = agent_count

        plt.imshow(agent_counts, interpolation="nearest")
        plt.colorbar()
        plt.show()

    def step(self):
        # Advance the model by one step
        self.datacollector.collect(self)
        self.schedule.step()
        self.plot_grid()

    def check_agent_status(self):
        for i in range(len(self.schedule.agents)):
            id = self.schedule.agents[i].unique_id
            wealth = self.schedule.agents[i].wealth
            logger.info("Agent " + str(id) + " has money: " + str(wealth))
Exemplo n.º 34
0
class BirdModel(Model):
    def __init__(self, n, width, height, algorithm="Dummy"):
        self.score_for_food = 10
        self.score_for_death = 100
        self.num_agents = n
        self.num_predator = round(n/4)
        self.growth_time = 2
        self.grid = Space(width, height, True)
        self.schedule = Activation(self)
        self.max_food_id = 0
        self.running = True
        for i in range(self.num_agents):
            if algorithm == "Dummy":
                bird = BirdAgent(i, self)
            elif algorithm == "Q":
                raise NotImplementedError
            elif algorithm == "GA":
                raise NotImplementedError
            elif algorithm == "DRL":
                raise NotImplementedError
            self.schedule.add(bird)
            x = random.randint(0, self.grid.width-1)
            y = random.randint(0, self.grid.height-1)
            self.grid.place_agent(bird, (x, y))

        for j in range(i + 1, i + 1 + self.num_predator):
            predator = PredatorAgent(j, self)
            self.schedule.add(predator)
            x = random.randint(0, self.grid.width - 1)
            y = random.randint(0, self.grid.height - 1)
            self.grid.place_agent(predator, (x, y))

        self.dc = DataCollector(
            model_reporters={"TotalScore": total_score},
            agent_reporters={"Score": "score"})

    def step(self):
        if self.schedule.time % self.growth_time == 0:
            self.max_food_id += 1
            food = FoodAgent(self.max_food_id, self)
            x = random.randint(0, self.grid.width-1)
            y = random.randint(0, self.grid.height-1)
            self.grid.place_agent(food, (x, y))
        self.dc.collect(self)
        self.schedule.step()
Exemplo n.º 35
0
class Disease_Model(Model):
    # 2D Model initialisation function - initialise with N agents, and
    # specified width and height
    """A model of disease spread.  For training purposes only."""
    def __init__(self, N, width, height, initial_infection, transmissibility,
                 level_of_movement, mean_length_of_disease):
        self.running = True  # required for BatchRunner
        self.num_agents = N  # assign number of agents at initialisation
        self.grid = MultiGrid(width, height, True)  # setup Toroidal multi-grid
        # set up a scheduler with random order of agents being activated
        # each turn
        self.schedule = RandomActivation(self)

        # Create agents up to number specified
        for i in range(self.num_agents):
            # Create agent with ID taken from for loop
            a = Person_Agent(i, self, initial_infection, transmissibility,
                             level_of_movement, mean_length_of_disease)
            self.schedule.add(a)  # add agent to the schedule

            # Try adding the agent to a random empty cell
            try:
                start_cell = self.grid.find_empty()
                self.grid.place_agent(a, start_cell)
            # If you can't find an empty cell, just pick any cell at random
            except:
                x = random.randrange(self.grid.width)
                y = random.randrange(self.grid.height)
                self.grid.place_agent(a, (x, y))

        # Create a new datacollector, and pass in a model reporter as a
        # dictionary entry, with the index value as the name of the result
        # (which we'll refer to by this name elsewhere) and the lookup value
        # as the name of the function we created below that will calculate
        # the result we're reporting
        self.datacollector = DataCollector(
            model_reporters={"Total_Infected": calculate_number_infected},
            agent_reporters={})

    # Function to advance the model by one step
    def step(self):
        self.schedule.step()
        # Tell the datacollector to collect data from the specified model
        # and agent reporters
        self.datacollector.collect(self)
Exemplo n.º 36
0
class ShapesModel(Model):
    def __init__(self, N, width=20, height=10):
        self.running = True
        self.N = N  # num of agents
        self.headings = ((1, 0), (0, 1), (-1, 0), (0, -1))  # tuples are fast
        self.grid = SingleGrid(width, height, torus=False)
        self.schedule = RandomActivation(self)
        load_scene('shape_model/crossing.txt', self.grid, self)
        """
        self.grid.place_agent(
            Walker(1911, self, (4, 4), type="wall"),
            (4, 4)
        )
        self.make_walls()
        self.make_walker_agents()
        """

    def make_walls(self):
        for i in range(0, 50):
            self.grid.place_agent(Walker(1911, self, (i, 5), type="wall"),
                                  (i, 5))

    def make_walker_agents(self):
        unique_id = 0
        while True:
            if unique_id == self.N:
                break
            x = random.randrange(self.grid.width)
            y = random.randrange(self.grid.height)
            pos = (x, y)
            heading = random.choice(self.headings)
            # heading = (1, 0)
            if self.grid.is_cell_empty(pos):
                print("Creating agent {2} at ({0}, {1})".format(
                    x, y, unique_id))
                a = Walker(unique_id, self, pos, heading)
                self.schedule.add(a)
                self.grid.place_agent(a, (x, y))
                self.grid.place_agent(a, (x + 1, y))
                self.grid.place_agent(a, (x, y + 1))
                self.grid.place_agent(a, (x + 1, y + 1))
                unique_id += 1

    def step(self):
        self.schedule.step()
class MoneyModel(Model):
    """A model with some number of agents."""
    def __init__(self, N, width, height):
        self.num_agents = N
        self.grid = MultiGrid(width, height, True)
        self.schedule = RandomActivation(self)
        self.running = True
        # Create agents
        for i in range(self.num_agents):
            a = MoneyAgent(i, self)
            self.schedule.add(a)
            # Add the agent to a random grid cell
            x = self.random.randrange(self.grid.width)
            y = self.random.randrange(self.grid.height)
            self.grid.place_agent(a, (x, y))

    def step(self):
        self.schedule.step()
Exemplo n.º 38
0
class CivModel(Model):
    """A model with some number of agents."""
    def __init__(self, N, width, height):
        self.num_agents = N
        self.grid = MultiGrid(width, height, True)
        self.schedule = RandomActivation(self)  # Créer une timeline

        for i in range(self.num_agents):

            agent = CivAgent(i, self)
            self.schedule.add(agent)  # ajoute N agent à la timeline
            # positionne aléatoirement l'agent sur la grille
            x = self.random.randrange(self.grid.width)
            y = self.random.randrange(self.grid.height)
            self.grid.place_agent(agent, (x, y))

    def step(self):
        self.schedule.step()
Exemplo n.º 39
0
class mkt(Model):
    def __init__(self, N, K):
        super().__init__()
        self.N = N
        self.K = K
        self.consume = False
        self.trade = True
        self.solo_update = True
        self.money = False
        self.history = []
        self.schedule = RandomActivation(self)
        # create agents
        for a in range(self.N):
            a = ant(a, self)
            self.schedule.add(a)

    def step(self):
        self.schedule.step()
class TaxiModel(Model):
    """A model with some number of agents."""
    def __init__(self, N):
        self.schedule = RandomActivation(self)
        
        call_center = CallCenterAgent(1,N,self)
        self.schedule.add(call_center)
        
        self.datacollector = DataCollector(
            agent_reporters={
            "Wealth": lambda call_center: call_center.wealth, 
            "Mu": lambda call_center: call_center.mu,
            "Number_Agent": lambda call_center: call_center.number_taxi_working,
            "Taxi": lambda call_center: call_center.list_taxis_wealth
            })
    def step(self):
        self.schedule.step()
        self.datacollector.collect(self)
Exemplo n.º 41
0
class PredictionMarketModel(Model):
    """A simple model of a market where people bid/ask for prediciton shares.
    """
    def __init__(self, N=100):
        self.num_agents = N
        self.schedule = RandomActivation(self)
        self.datacollector = DataCollector(model_reporters={
            "bid_price": get_highest_bid,
            "ask_price": get_lowest_ask,
            "volume": compute_volume
        },
                                           agent_reporters={
                                               "Certainty": "prob",
                                               "Bids": "bid",
                                               "Asks": "ask"
                                           })
        self.bidders = OrderedDict()
        self.askers = OrderedDict()
        self.volume = 0
        # Create agents
        print('creating {} agents..'.format(self.num_agents))
        for i in range(self.num_agents):
            # Create probability distribution
            #prob = np.random.normal(mu, sigma)
            #prob = np.random.uniform(0.01, 0.99)
            if random.randint(0, 1):
                prob = np.random.normal(0.83, 0.05)
            else:
                prob = np.random.normal(0.53, 0.05)
            a = PredictionAgent(prob, i, self)
            self.schedule.add(a)

        print('running model...')
        self.running = True

    def step(self):
        self.volume = 0
        self.schedule.step()
        # collect data
        self.datacollector.collect(self)

    def run_model(self, n):
        for i in range(n):
            self.step()
Exemplo n.º 42
0
class Disease_Model(Model):
    # 2D Model initialisation function - initialise with N agents, and
    # specified width and height.  Also pass in the things we need to pass
    # to our agents when instantiating them.
    # The comment below which uses triple " will get picked up by the server
    # if we run a live display of the model.
    """A model of disease spread.  For training purposes only."""
    def __init__(self, N, width, height, initial_infection, transmissibility,
                 level_of_movement, mean_length_of_disease):
        self.running = True  # required for BatchRunner
        self.num_agents = N  # assign number of agents at initialisation

        # Set up a Toroidal multi-grid (Toroidal = if the agent is in a cell
        # on the border of the grid, and moves towards the border, they'll
        # come out the other side.  Think PacMan :) The True Boolean passed in
        # switches that on.  Multi-Grid just means we can have more than one
        # agent per cell)
        self.grid = MultiGrid(width, height, True)
        # set up a scheduler with random order of agents being activated
        # each turn.  Remember order is important here - if an infected agent
        # is going to move into a cell with an uninfected agent, but that
        # uninfected agent moves first, they'll escape infection.
        self.schedule = RandomActivation(self)

        # Create person_agent objects up to number specified
        for i in range(self.num_agents):
            # Create agent with ID taken from for loop
            a = Person_Agent(i, self, initial_infection, transmissibility,
                             level_of_movement, mean_length_of_disease)
            self.schedule.add(a)  # add agent to the schedule

            # Try adding the agent to a random empty cell
            try:
                start_cell = self.grid.find_empty()
                self.grid.place_agent(a, start_cell)
            # If you can't find an empty cell, just pick any cell at random
            except:
                x = random.randrange(self.grid.width)
                y = random.randrange(self.grid.height)
                self.grid.place_agent(a, (x, y))

    # Function to advance the model by one step
    def step(self):
        self.schedule.step()
Exemplo n.º 43
0
class mkt(Model):
    def __init__(self, N, K, width=10, height=10, trade=True):
        super().__init__()
        self.N = N
        self.K = K
        self.consume = False
        self.trade = trade
        self.solo_update = True
        self.money = False
        self.running = True
        self.history = []
        self.grid = MultiGrid(width, height, True)
        self.schedule = RandomActivation(self)
        # create agents
        for a in range(self.N):
            a = ant(a, self)
            self.schedule.add(a)
            x = self.random.randrange(self.grid.width)
            y = self.random.randrange(self.grid.height)
            self.grid.place_agent(a, (x, y))
        all_utility = [agent.utility() for agent in self.schedule.agents]
        self.mean_utility = sum(all_utility) / self.N
        all_spec = [agent.specialization() for agent in self.schedule.agents]
        self.mean_specialization = sum(all_spec) / self.N
        self.datacollector = DataCollector(model_reporters={
            "Mean_Utility":
            "mean_utility",
            "Mean_Specialization":
            "mean_specialization"
        },
                                           agent_reporters={
                                               "Utility":
                                               utility_reporter,
                                               "Specialization":
                                               specialization_reporter
                                           })

    def step(self):
        self.schedule.step()
        self.datacollector.collect(self)
        all_utility = [agent.utility() for agent in self.schedule.agents]
        self.mean_utility = sum(all_utility) / self.N
        all_spec = [agent.specialization() for agent in self.schedule.agents]
        self.mean_specialization = np.mean(all_spec) / self.N
Exemplo n.º 44
0
class Disease_Model(Model):
    # 2D Model initialisation function - initialise with N agents, and
    # specified width and height
    """A model of disease spread.  For training purposes only."""
    def __init__(self, N, width, height, initial_infection, transmissibility,
                 level_of_movement, mean_length_of_disease, mean_imm_duration,
                 prob_being_immunised):
        self.running = True  # required for BatchRunner
        self.num_agents = N  # assign number of agents at initialisation
        self.grid = MultiGrid(width, height, True)  # setup Toroidal multi-grid
        # set up a scheduler with random order of agents being activated
        # each turn
        self.schedule = RandomActivation(self)

        # Create agents up to number specified
        for i in range(self.num_agents):
            # Create agent with ID taken from for loop
            a = Person_Agent(i, self, initial_infection, transmissibility,
                             level_of_movement, mean_length_of_disease,
                             mean_imm_duration, prob_being_immunised)
            self.schedule.add(a)  # add agent to the schedule

            # Try adding the agent to a random empty cell
            try:
                start_cell = self.grid.find_empty()
                self.grid.place_agent(a, start_cell)
            # If you can't find an empty cell, just pick any cell at random
            except:
                x = random.randrange(self.grid.width)
                y = random.randrange(self.grid.height)
                self.grid.place_agent(a, (x, y))

        self.datacollector = DataCollector(model_reporters={
            "Total_Infected":
            calculate_number_infected,
            "Total_Imm":
            calculate_number_immunised
        },
                                           agent_reporters={})

    # Function to advance the model by one step
    def step(self):
        self.schedule.step()
        self.datacollector.collect(self)
Exemplo n.º 45
0
class MoneyModel(Model):
    """A model with some number of agents"""
    def __init__(self, N):
        self.num_agents = N
        self.schedule = RandomActivation(self)
        #create agents
        for i in range(self.num_agents):
            #here is the agent definition
            a = MoneyAgent(
                i, self
            )  #i becomes the unique id. Use of self here is still a question...
            self.schedule.add(a)

    def step(self):
        '''Ádvance the model by one step'''
        #print(self.num_agents)

        self.schedule.step(
        )  #it shuffles the order of the agents, then activates them all, one at a time.
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
Exemplo n.º 47
0
class MowerModel(Model):
    """A model with 1 Mower."""
    def __init__(self, N, width, height):
        super().__init__(
        )  # !!IMPORTANT : https://github.com/projectmesa/mesa/issues/627
        self.num_agents = N
        self.direction = 'R'
        self.grid = MultiGrid(width, height, True)
        self.schedule = RandomActivation(self)

        # Create agents
        for i in range(self.num_agents):
            a = MowerAgent(i, self)
            self.schedule.add(a)
            # Add the agent to a random grid cell
            self.grid.place_agent(a, tuple([0, 0]))

    def step(self):
        self.schedule.step()
Exemplo n.º 48
0
class MoneyModel(Model):
    def __init__(self,N,width,height):
        self.running = True
        self.num_agents = N
        self.grid = MultiGrid(width, height,True)
        self.schedule = RandomActivation(self)
        for i in range(self.num_agents):
            a=MoneyAgent(i, self)
            self.schedule.add(a)
            x=random.randrange(self.grid.width)
            y=random.randrange(self.grid.height)
            self.grid.place_agent(a,(x,y))
        self.datacollector = DataCollector(
            model_reporters={"Gini": compute_gini},  # A function to call
            agent_reporters={"Wealth": "wealth"})  # An agent attribute

    def step(self):
        self.datacollector.collect(self)
        self.schedule.step()
class MoneyModel(Model):
    """A model with some number of agents."""
    def __init__(self, N):
        self.running = True
        self.num_agents = N
        self.schedule = RandomActivation(self)
        self.create_agents()
        agent_reporters = {"Wealth": lambda a: a.wealth}
        model_reporters = {"Gini": compute_gini}
        self.dc = DataCollector(model_reporters=model_reporters,
                                agent_reporters=agent_reporters)

    def create_agents(self):
        """Method to create all the agents."""
        for i in range(self.num_agents):
            a = MoneyAgent(i)
            self.schedule.add(a)

    def step(self):
        self.schedule.step()
        self.dc.collect(self)
Exemplo n.º 50
0
class LifeTimeModel(Model):
    '''Simple model for running models with a finite life'''
    def __init__(self, agent_lifetime = 1, n_agents = 10):
        super().__init__()
        
        self.agent_lifetime = agent_lifetime
        self.n_agents = n_agents

        ## keep track of the the remaining life of an agent and
        ## how many ticks it has seen
        self.datacollector = DataCollector(
            agent_reporters = {"remaining_life" : lambda a: a.remaining_life,
                               "steps" : lambda a: a.steps})
        
        self.current_ID = 0
        self.schedule = RandomActivation(self)
        
        for _ in range(n_agents):
            self.schedule.add(FiniteLifeAgent(self.next_id(),
                                              self.agent_lifetime,
                                              self))

    def step(self):
        '''Add agents back to n_agents in each step'''
        
        self.datacollector.collect(self)
        self.schedule.step()
        
        if len(self.schedule.agents) < self.n_agents:
            for _ in range(self.n_agents - len(self.schedule.agents)):
                self.schedule.add(FiniteLifeAgent(self.next_id(),
                                                  self.agent_lifetime,
                                                  self))

    def run_model(self, step_count = 100):
        for _ in range(step_count):
            self.step()
Exemplo n.º 51
0
class SchellingModel(Model):
    '''Model class for Schelling segregation model'''

    def __init__(self, height=20, width=20, density=.8, group_ratio=.66, minority_ratio=.5, homophily=3):
        self.height = height
        self.width = width
        self.density = density
        self.group_ratio = group_ratio
        self.minority_ratio = minority_ratio
        self.homophily = homophily
        self.happy = 0
        self.segregated = 0

        self.schedule = RandomActivation(self)
        self.grid = SingleGrid(height, width, torus=False)

        self.place_agents()
        self.datacollector = DataCollector( {'happy': (lambda m: m.happy), 'segregated': (lambda m: m.segregated)})
        self.running = True


    def step(self):
        '''Run one step of model'''
        self.schedule.step()
        self.calculate_stats()
        self.datacollector.collect(self)

        if self.happy == self.schedule.get_agent_count():
            self.running = False


    def place_agents(self):
        for cell in self.grid.coord_iter():
            x, y = cell[1:3]
            if random.random() < self.density:
                if random.random() < self.group_ratio:
                    if random.random() < self.minority_ratio:
                        group = 0
                    else:
                        group = 1
                else:
                    group = 2

                agent = SchellingAgent((x,y), group)
                self.grid.position_agent(agent, (x,y))
                self.schedule.add(agent)

        for agent in self.schedule.agents:
            count = 0
            for neighbour in self.grid.iter_neighbors(agent.pos, moore=False):
                if neighbour.group == agent.group:
                    count += 1
            agent.similar = count


    def calculate_stats(self):
        happy_count = 0
        avg_seg = 0
        for agent in self.schedule.agents:
            avg_seg += agent.similar
            if agent.similar >= self.homophily:
                happy_count += 1

        self.happy = happy_count
        self.segregated = avg_seg/self.schedule.get_agent_count()
Exemplo n.º 52
0
class BankReserves(Model):
    """
    This model is a Mesa implementation of the Bank Reserves model from NetLogo.
    It is a highly abstracted, simplified model of an economy, with only one
    type of agent and a single bank representing all banks in an economy. People
    (represented by circles) move randomly within the grid. If two or more people
    are on the same grid location, there is a 50% chance that they will trade with
    each other. If they trade, there is an equal chance of giving the other agent
    $5 or $2. A positive trade balance will be deposited in the bank as savings.
    If trading results in a negative balance, the agent will try to withdraw from
    its savings to cover the balance. If it does not have enough savings to cover
    the negative balance, it will take out a loan from the bank to cover the
    difference. The bank is required to keep a certain percentage of deposits as
    reserves and the bank's ability to loan at any given time is a function of
    the amount of deposits, its reserves, and its current total outstanding loan
    amount.
    """

    # grid height
    grid_h = 20
    # grid width
    grid_w = 20

    """init parameters "init_people", "rich_threshold", and "reserve_percent"
       are all UserSettableParameters"""
    def __init__(self, height=grid_h, width=grid_w, init_people=2, rich_threshold=10,
                 reserve_percent=50,):
        self.height = height
        self.width = width
        self.init_people = init_people
        self.schedule = RandomActivation(self)
        self.grid = MultiGrid(self.width, self.height, torus=True)
        # rich_threshold is the amount of savings a person needs to be considered "rich"
        self.rich_threshold = rich_threshold
        self.reserve_percent = reserve_percent
        # see datacollector functions above
        self.datacollector = DataCollector(model_reporters={
                                           "Rich": get_num_rich_agents,
                                           "Poor": get_num_poor_agents,
                                           "Middle Class": get_num_mid_agents,
                                           "Savings": get_total_savings,
                                           "Wallets": get_total_wallets,
                                           "Money": get_total_money,
                                           "Loans": get_total_loans},
                                           agent_reporters={
                                           "Wealth": lambda x: x.wealth})

        # create a single bank for the model
        self.bank = Bank(1, self, self.reserve_percent)

        # create people for the model according to number of people set by user
        for i in range(self.init_people):
            # set x, y coords randomly within the grid
            x = self.random.randrange(self.width)
            y = self.random.randrange(self.height)
            p = Person(i, (x, y), self, True, self.bank, self.rich_threshold)
            # place the Person object on the grid at coordinates (x, y)
            self.grid.place_agent(p, (x, y))
            # add the Person object to the model schedule
            self.schedule.add(p)

        self.running = True
        self.datacollector.collect(self)

    def step(self):
        # tell all the agents in the model to run their step function
        self.schedule.step()
        # collect data
        self.datacollector.collect(self)

    def run_model(self):
        for i in range(self.run_time):
            self.step()
Exemplo n.º 53
0
class WolfSheepPredation(Model):
    '''
    Wolf-Sheep Predation Model
    '''

    initial_sheep = 100
    initial_wolves = 50
    sheep_gain_from_food = 4

    grass = False

    wolf_gain_from_food = 20
    sheep_reproduce = 0.04
    wolf_reproduce = 0.05

    height = 20
    width = 20

    def __init__(self, height=20, width=20,
                 initial_sheep=100, initial_wolves=50, sheep_reproduce=0.04,
                 wolf_reproduce=0.05, wolf_gain_from_food=20,
                 grass=False, sheep_gain_from_food=4):
        '''
        Create a new Wolf-Sheep model with the given parameters.

        Args:
            initial_sheep: Number of sheep to start with
            initial_wolves: Number of wolves to start with
            sheep_reproduce: Probability of each sheep reproducing each step
            wolf_reproduce: Probability of each wolf reproducing each step
            wolf_gain_from_food: Energy a wolf gains from eating a sheep
            grass: Whether to have the sheep eat grass for energy
            sheep_gain_from_food: Energy sheep gain from grass, if enabled.
        '''

        # Set parameters
        self.height = height
        self.width = width
        self.initial_sheep = initial_sheep
        self.initial_wolves = initial_wolves
        self.sheep_reproduce = sheep_reproduce
        self.wolf_reproduce = wolf_reproduce
        self.wolf_gain_from_food = wolf_gain_from_food
        self.grass = grass
        self.sheep_gain_from_food = sheep_gain_from_food

        self.schedule = RandomActivation(self)
        self.grid = MultiGrid(self.height, self.width, torus=True)

        # Create sheep:
        for i in range(self.initial_sheep):
            x = random.randrange(self.width)
            y = random.randrange(self.height)
            sheep = Sheep(self.grid, x, y, True)
            self.grid.place_agent(sheep, (x, y))
            self.schedule.add(sheep)

        # Create wolves
        for i in range(self.initial_wolves):
            x = random.randrange(self.width)
            y = random.randrange(self.height)
            energy = random.randrange(2 * self.wolf_gain_from_food)
            wolf = Wolf(self.grid, x, y, True, energy)
            self.grid.place_agent(wolf, (x, y))
            self.schedule.add(wolf)

        self.running = True

    def step(self):
        self.schedule.step()
Exemplo n.º 54
0
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
Exemplo n.º 55
0
class SeparationBarrierModel(Model):
    def __init__(self, height, width, palestinian_density, settlement_density,
                 settlers_violence_rate, settlers_growth_rate, suicide_rate, greed_level,
                 settler_vision=1, palestinian_vision=1, 
                 movement=True, max_iters=1000):

        super(SeparationBarrierModel, self).__init__()
        self.height = height
        self.width = width
        self.palestinian_density = palestinian_density
        self.settler_vision = settler_vision
        self.palestinian_vision = palestinian_vision
        self.settlement_density = settlement_density
        self.movement = movement
        self.running = True
        self.max_iters = max_iters
        self.iteration = 0
        self.schedule = RandomActivation(self)
        self.settlers_violence_rate = settlers_violence_rate
        self.settlers_growth_rate = settlers_growth_rate
        self.suicide_rate = suicide_rate
        self.greed_level = greed_level

        self.total_violence = 0

        self.grid = SingleGrid(height, width, torus=False)

        model_reporters = {
        }
        agent_reporters = {
#           "x": lambda a: a.pos[0],
#           "y": lambda a: a.pos[1],
        }
        self.dc = DataCollector(model_reporters=model_reporters,
                                agent_reporters=agent_reporters)
        self.unique_id = 0

        # Israelis and palestinans split the region in half
        for (contents, x, y) in self.grid.coord_iter():
            if random.random() < self.palestinian_density:
                palestinian = Palestinian(self.unique_id, (x, y), vision=self.palestinian_vision, breed="Palestinian",
                          model=self)
                self.unique_id += 1
                self.grid.position_agent(palestinian, x,y)
                self.schedule.add(palestinian)
            elif ((y > (self.grid.height) * (1-self.settlement_density)) and random.random() < self.settlement_density):
                settler = Settler(self.unique_id, (x, y),
                                  vision=self.settler_vision, model=self, breed="Settler")
                self.unique_id += 1
                self.grid.position_agent(settler, x,y)
                self.schedule.add(settler)

    def add_settler(self, pos):
        settler = Settler(self.unique_id, pos,
                          vision=self.settler_vision, model=self, breed="Settler")
        self.unique_id += 1
        self.grid.position_agent(settler, pos[0], pos[1])
        self.schedule.add(settler)

    def set_barrier(self,victim_pos, violent_pos):
        #print("Set barrier - Greed level", self.greed_level)
        visible_spots = self.grid.get_neighborhood(victim_pos,
                                                        moore=True, radius=self.greed_level + 1)
        furthest_empty  = self.find_furthest_empty_or_palestinian(victim_pos, visible_spots)
        x,y = furthest_empty
        current = self.grid[y][x]
        #print ("Set barrier!!", pos, current)
        free = True
        if (current is not None and current.breed == "Palestinian"):
            #print ("Relocating Palestinian")
           free =  self.relocate_palestinian(current, current.pos)

        if (free):
            barrier = Barrier(-1, furthest_empty, model=self)
            self.grid.position_agent(barrier, x,y)
        
        # Relocate the violent palestinian
        #violent_x, violent_y = violent_pos
        #if violent_pos != furthest_empty:
        #    violent_palestinian = self.grid[violent_y][violent_x]
        #    self.relocate_palestinian(violent_palestinian, furthest_empty)

    def relocate_palestinian(self, palestinian, destination):
        #print ("Relocating Palestinian in ", palestinian.pos, "To somehwhere near ", destination)
        visible_spots = self.grid.get_neighborhood(destination,
                                                        moore=True, radius=palestinian.vision)
        nearest_empty = self.find_nearest_empty(destination, visible_spots)
        #print("First Nearest empty to ", palestinian.pos, " Is ", nearest_empty)
        if (nearest_empty):
            self.grid.move_agent(palestinian, nearest_empty)
        else:
            #print ("Moveing to random empty")
            if (self.grid.exists_empty_cells()):
                self.grid.move_to_empty(palestinian)
            else:
                return False

        return True

    def find_nearest_empty(self, pos, neighborhood):
        nearest_empty = None
        sorted_spots = self.sort_neighborhood_by_distance(pos, neighborhood)
        index = 0
        while (nearest_empty is None and index < len(sorted_spots)):
            if self.grid.is_cell_empty(sorted_spots[index]):
                nearest_empty = sorted_spots[index]
            index += 1

        return nearest_empty

    def find_furthest_empty_or_palestinian(self, pos, neighborhood):
        furthest_empty = None
        sorted_spots = self.sort_neighborhood_by_distance(pos, neighborhood)
        sorted_spots.reverse()
        index = 0
        while (furthest_empty is None and index < len(sorted_spots)):
            spot = sorted_spots[index]
            if self.grid.is_cell_empty(spot) or self.grid[spot[1]][spot[0]].breed == "Palestinian" :
                furthest_empty = sorted_spots[index]
            index += 1

        return furthest_empty



    def sort_neighborhood_by_distance(self, from_pos, neighbor_spots):
        from_x, from_y = from_pos
        return sorted(neighbor_spots, key = lambda spot: self.eucledean_distance(from_x, spot[0], from_y, spot[1], self.grid.width, self.grid.height))


    def eucledean_distance(self, x1,x2,y1,y2,w,h):
        # http://stackoverflow.com/questions/2123947/calculate-distance-between-two-x-y-coordinates
        return math.sqrt(min(abs(x1 - x2), w - abs(x1 - x2)) ** 2 + min(abs(y1 - y2), h - abs(y1-y2)) ** 2)
        

    def step(self):
        """
        Advance the model by one step and collect data.
        """
        self.violence_count = 0
      #  for i in range(100):
        self.schedule.step()
        self.total_violence += self.violence_count
      #  average = self.violence_count / 100
        #print("Violence average %f " % average)
        print("Total Violence: ", self.total_violence)
Exemplo n.º 56
0
class Movement(Model):

    def __init__(self, width = 0, height = 0, torus = False,
                 time = 0, step_in_year = 0,
                 number_of_families = family_setting, number_of_monkeys = 0, monkey_birth_count = 0,
                 monkey_death_count = 0, monkey_id_count = 0,
                 number_of_humans = 0, grid_type = human_setting, run_type = run_setting, human_id_count = 0):
        # change the # of families here for graph.py, but use server.py to change # of families in the movement model
        # torus = False means monkey movement can't 'wrap around' edges
        super().__init__()
        self.width = width
        self.height = height
        self.time = time  # time increases by 1/73 (decimal) each step
        self.step_in_year = step_in_year  # 1-73; each step is 5 days, and 5 * 73 = 365 days in a year
        self.number_of_families = number_of_families
        self.number_of_monkeys = number_of_monkeys  # total, not in each family
        self.monkey_birth_count = monkey_birth_count
        self.monkey_death_count = monkey_death_count
        self.monkey_id_count = monkey_id_count
        self.number_of_humans = number_of_humans
        self.grid_type = grid_type   # string 'with_humans' or 'without_humans'
        self.run_type = run_type  # string with 'normal_run' or 'first_run'
        self.human_id_count = human_id_count

        # width = self._readASCII(vegetation_file)[1] # width as listed at the beginning of the ASCII file
        # height = self._readASCII(vegetation_file)[2] # height as listed at the beginning of the ASCII file
        width = 85
        height = 100

        self.grid = MultiGrid(width, height, torus)  # creates environmental grid, sets schedule
        # MultiGrid is a Mesa function that sets up the grid; options are between SingleGrid and MultiGrid
        # MultiGrid allows you to put multiple layers on the grid

        self.schedule = RandomActivation(self)  # Mesa: Random vs. Staged Activation
        # similar to NetLogo's Ask Agents - determines order (or lack of) in which each agents act

        empty_masterdict = {'Outside_FNNR': [], 'Elevation_Out_of_Bound': [], 'Household': [], 'PES': [], 'Farm': [],
                            'Forest': [], 'Bamboo': [], 'Coniferous': [], 'Broadleaf': [], 'Mixed': [], 'Lichen': [],
                            'Deciduous': [], 'Shrublands': [], 'Clouds': [], 'Farmland': []}

        # generate land
        if self.run_type == 'first_run':
            gridlist = self._readASCII(vegetation_file)[0]  # list of all coordinate values; see readASCII function
            gridlist2 = self._readASCII(elevation_file)[0]  # list of all elevation values
            gridlist3 = self._readASCII(household_file)[0]  # list of all household coordinate values
            gridlist4 = self._readASCII(pes_file)[0]  # list of all PES coordinate values
            gridlist5 = self._readASCII(farm_file)[0]  # list of all farm coordinate values
            gridlist6 = self._readASCII(forest_file)[0]  # list of all managed forest coordinate values
            # The '_populate' function below builds the environmental grid.
            for x in [Elevation_Out_of_Bound]:
                self._populate(empty_masterdict, gridlist2, x, width, height)
            for x in [Household]:
                self._populate(empty_masterdict, gridlist3, x, width, height)
            for x in [PES]:
                self._populate(empty_masterdict, gridlist4, x, width, height)
            for x in [Farm]:
                self._populate(empty_masterdict, gridlist5, x, width, height)
            for x in [Forest]:
                self._populate(empty_masterdict, gridlist6, x, width, height)
            for x in [Bamboo, Coniferous, Broadleaf, Mixed, Lichen, Deciduous,
                      Shrublands, Clouds, Farmland, Outside_FNNR]:
                self._populate(empty_masterdict, gridlist, x, width, height)
            self.saveLoad(empty_masterdict, 'masterdict_veg', 'save')
            self.saveLoad(self.grid, 'grid_veg', 'save')
            self.saveLoad(self.schedule, 'schedule_veg', 'save')

        # Pickling below
        load_dict = {}  # placeholder for model parameters, leave this here even though it does nothing

        if self.grid_type == 'with_humans':
            empty_masterdict = self.saveLoad(load_dict, 'masterdict_veg', 'load')
            self.grid = self.saveLoad(self.grid, 'grid_veg', 'load')

        if self.grid_type == 'without_humans':
            empty_masterdict = self.saveLoad(load_dict, 'masterdict_without_humans', 'load')
            self.grid = self.saveLoad(load_dict, 'grid_without_humans', 'load')
        masterdict = empty_masterdict

        startinglist = masterdict['Broadleaf'] + masterdict['Mixed'] + masterdict['Deciduous']
        # Agents will start out in high-probability areas.
        for coordinate in masterdict['Elevation_Out_of_Bound'] + masterdict['Household'] + masterdict['PES'] \
                    + masterdict['Farm'] + masterdict['Forest']:
                if coordinate in startinglist:
                    startinglist.remove(coordinate)
        # Creation of resources (yellow dots in simulation)
        # These include Fuelwood, Herbs, Bamboo, etc., but right now resource type and frequency are not used
        if self.grid_type == 'with_humans':
            for line in _readCSV('hh_survey.csv')[1:]:  # see 'hh_survey.csv'
                hh_id_match = int(line[0])
                resource_name = line[1]  # frequency is monthly; currently not-used
                frequency = float(line[2]) / 6  # divided by 6 for 5-day frequency, as opposed to 30-day (1 month)
                y = int(line[5])
                x = int(line[6])
                resource = Resource(_readCSV('hh_survey.csv')[1:].index(line),
                                    self, (x, y), hh_id_match, resource_name, frequency)
                self.grid.place_agent(resource, (int(x), int(y)))
                resource_dict.setdefault(hh_id_match, []).append(resource)
                if self.run_type == 'first_run':
                    self.saveLoad(resource_dict, 'resource_dict', 'save')

        # Creation of land parcels
        land_parcel_count = 0

        # individual land parcels in each household (non-gtgp and gtgp)
        for line in _readCSV('hh_land.csv')[2:]:  # exclude headers; for each household:
            age_1 = float(line[45])
            gender_1 = float(line[46])
            education_1 = float(line[47])
            hh_id = int(line[0])
            hh_size = 0  # calculate later

            total_rice = float(line[41])
            if total_rice in [-2, -3, -4]:
                total_rice = 0
            gtgp_rice = float(line[42])
            if gtgp_rice in [-2, -3, -4]:
                gtgp_rice = 0
            total_dry = float(line[43])
            if total_dry in [-2, -3, -4]:
                total_dry = 0
            gtgp_dry = float(line[44])
            if gtgp_dry in [-2, -3, -4]:
                gtgp_dry = 0
            # non_gtgp_area = float(total_rice) + float(total_dry) - float(gtgp_dry) - float(gtgp_rice)
            # gtgp_area = float(gtgp_dry) + float(gtgp_rice)

            for i in range(1, 6):  # for each household, which has up to 5 each of possible non-GTGP and GTGP parcels:
                # non_gtgp_area = float(line[i + 47].replace("\"",""))
                # gtgp_area = float(line[i + 52].replace("\"",""))
                non_gtgp_area = float(total_rice) + float(total_dry) - float(gtgp_dry) - float(gtgp_rice)
                gtgp_area = float(gtgp_dry) + float(gtgp_rice)

                if gtgp_area in [-2, -3, -4]:
                    gtgp_area = 0
                if non_gtgp_area in [-2, -3, -4]:
                    non_gtgp_area = 0

                if non_gtgp_area > 0:
                    gtgp_enrolled = 0
                    non_gtgp_output = float(line[i].replace("\"",""))
                    pre_gtgp_output = 0
                    land_time = float(line[i + 25].replace("\"",""))  # non-gtgp travel time
                    plant_type = float(line[i + 10].replace("\"",""))  # non-gtgp plant type
                    land_type = float(line[i + 30].replace("\"",""))  # non-gtgp land type

                    if land_type not in [-2, -3, -4]:
                        land_parcel_count += 1
                        if non_gtgp_output in [-3, '-3', -4, '-4']:
                            non_gtgp_output = 0
                        if pre_gtgp_output in [-3, '-3', -4, '-4']:
                            pre_gtgp_output = 0
                        lp = Land(land_parcel_count, self, hh_id, gtgp_enrolled,
                                             age_1, gender_1, education_1,
                                             gtgp_dry, gtgp_rice, total_dry, total_rice,
                                             land_type, land_time, plant_type, non_gtgp_output,
                                             pre_gtgp_output, hh_size, non_gtgp_area, gtgp_area)
                        self.schedule.add(lp)

                if gtgp_area > 0:
                    gtgp_enrolled = 1
                    pre_gtgp_output = 0
                    non_gtgp_output = float(line[i].replace("\"",""))
                    land_time = float(line[i + 20].replace("\"",""))  # gtgp travel time
                    plant_type = float(line[i + 15].replace("\"",""))  # gtgp plant type
                    land_type = float(line[i + 35].replace("\"",""))  # gtgp land type
                    if land_type not in [-3, '-3', -4, '-4']:
                        land_parcel_count += 1
                        if non_gtgp_output in [-3, '-3', -4, '-4']:
                            non_gtgp_output = 0
                        if pre_gtgp_output in [-3, '-3', -4, '-4']:
                            pre_gtgp_output = 0
                        lp = Land(land_parcel_count, self, hh_id, gtgp_enrolled,
                                  age_1, gender_1, education_1,
                                  gtgp_dry, gtgp_rice, total_dry, total_rice,
                                  land_type, land_time, plant_type, non_gtgp_output,
                                  pre_gtgp_output, hh_size, non_gtgp_area, gtgp_area)
                        self.schedule.add(lp)

        # Creation of humans (brown dots in simulation)
        self.number_of_humans = 0
        self.human_id_count = 0
        line_counter = 0
        for line in _readCSV('hh_citizens.csv')[1:]:  # exclude headers; for each household:
            hh_id = int(line[0])
            line_counter += 1
            starting_position = (int(_readCSV('household.csv')[line_counter][4]),
                                 int(_readCSV('household.csv')[line_counter][3]))
            try:
                resource = random.choice(resource_dict[str(hh_id)])  # random resource point for human
                resource_position = resource.position
                resource_frequency = resource.frequency
                # to travel to, among the list of resource points reported by that household; may change later
                # to another randomly-picked resource
            except KeyError:
                resource_position = starting_position  # some households don't collect resources
                resource_frequency = 0
            hh_gender_list = line[1:10]
            hh_age_list = line[10:19]
            hh_education_list = line[19:28]
            hh_marriage_list = line[28:37]
            # creation of non-migrants
            for list_item in hh_age_list:
                if str(list_item) == '-3' or str(list_item) == '':
                    hh_age_list.remove(list_item)
            for x in range(len(hh_age_list) - 1):
                person = []
                for item in [hh_age_list, hh_gender_list, hh_education_list, hh_marriage_list]:
                    person.append(item[x])
                age = float(person[0])
                gender = int(person[1])
                education = int(person[2])
                marriage = int(person[3])
                if marriage != 1:
                    marriage = 6
                if 15 < age < 59:
                    work_status = 1
                elif 7 < age < 15:
                    work_status = 5
                else:
                    work_status = 6
                mig_years = 0
                migration_network = int(line[37])
                income_local_off_farm = int(line[57])
                resource_check = 0
                mig_remittances = int(line[48])
                past_hh_id = hh_id
                migration_status = 0
                death_rate = 0
                gtgp_part = 0
                non_gtgp_area = 0

                if str(gender) == '1':
                    if 0 < age <= 10:
                        age_category = 0
                    elif 10 < age <= 20:
                        age_category = 1
                    elif 20 < age <= 30:
                        age_category = 2
                    elif 30 < age <= 40:
                        age_category = 3
                    elif 40 < age <= 50:
                        age_category = 4
                    elif 50 < age <= 60:
                        age_category = 5
                    elif 60 < age <= 70:
                        age_category = 6
                    elif 70 < age <= 80:
                        age_category = 7
                    elif 80 < age <= 90:
                        age_category = 8
                    elif 90 < age:
                        age_category = 9
                elif str(gender) != "1":
                    if 0 < age <= 10:
                        age_category = 10
                    elif 10 < age <= 20:
                        age_category = 11
                    elif 20 < age <= 30:
                        age_category = 12
                    elif 30 < age <= 40:
                        age_category = 13
                    elif 40 < age <= 50:
                        age_category = 14
                    elif 50 < age <= 60:
                        age_category = 15
                    elif 60 < age <= 70:
                        age_category = 16
                    elif 70 < age <= 80:
                        age_category = 17
                    elif 80 < age <= 90:
                        age_category = 18
                    elif 90 < age:
                        age_category = 19
                children = 0
                if gender == 2:
                    if marriage == 1 and age < 45:
                        children = random.randint(0, 4)  # might already have kids
                    birth_plan_chance = random.random()
                    if birth_plan_chance < 0.03125:
                        birth_plan = 0
                    elif 0.03125 <= birth_plan_chance < 0.1875:
                        birth_plan = 1
                    elif 0.1875 <= birth_plan_chance < 0.5:
                        birth_plan = 2
                    elif 0.5 <= birth_plan_chance < 0.8125:
                        birth_plan = 3
                    elif 0.8125 <= birth_plan_chance < 0.96875:
                        birth_plan = 4
                    else:
                        birth_plan = 5
                elif gender != 2:
                    birth_plan = 0
                last_birth_time = random.uniform(0, 1)
                human_demographic_structure_list[age_category] += 1
                if str(person[0]) != '' and str(person[0]) != '-3' and str(person[1]) != '-3':  # sorts out all blanks
                    self.number_of_humans += 1
                    self.human_id_count += 1
                    human = Human(self.human_id_count, self, starting_position, hh_id, age,  # creates human
                                  resource_check, starting_position, resource_position,
                                  resource_frequency, gender, education, work_status,
                                  marriage, past_hh_id, mig_years, migration_status, gtgp_part,
                                  non_gtgp_area, migration_network, mig_remittances,
                                  income_local_off_farm, last_birth_time, death_rate, age_category, children,
                                  birth_plan)
                    if self.grid_type == 'with_humans':
                        self.grid.place_agent(human, starting_position)
                        self.schedule.add(human)

            # creation of migrant
            hh_migrants = line[38:43]  # age, gender, marriage, education of migrants
            if str(hh_migrants[0]) != '' and str(hh_migrants[0]) != '-3'\
                    and str(hh_migrants[1]) != '' and str(hh_migrants[1]) != '-3':
                # if that household has any migrants, create migrant person
                self.number_of_humans += 1
                self.human_id_count += 1
                age = float(hh_migrants[0])
                gender = float(hh_migrants[1])
                education = int(hh_migrants[2])
                marriage = int(hh_migrants[3])
                mig_years = int(hh_migrants[4])
                if 15 < age < 59:
                    work_status = 1
                elif 7 < age < 15:
                    work_status = 5
                else:
                    work_status = 6
                past_hh_id = hh_id
                hh_id = 'Migrated'
                migration_status = 1
                migration_network = int(line[37])

                last_birth_time = random.uniform(0, 1)

                total_rice = float(line[43])
                gtgp_rice = float(line[44])
                total_dry = float(line[45])
                gtgp_dry = float(line[46])
                income_local_off_farm = float(line[57])
                if total_rice in ['-3', '-4', -3, None]:
                    total_rice = 0
                if total_dry in ['-3', '-4', -3, None]:
                    total_dry = 0
                if gtgp_dry in ['-3', '-4', -3, None]:
                    gtgp_dry = 0
                if gtgp_rice in ['-3', '-4', -3, None]:
                    gtgp_rice = 0
                if (gtgp_dry + gtgp_rice) != 0:
                    gtgp_part = 1
                else:
                    gtgp_part = 0
                non_gtgp_area = ((total_rice) + (total_dry)) \
                                - ((gtgp_dry) + (gtgp_rice))
                resource_check = 0
                mig_remittances = int(line[48])
                death_rate = 0
                if gender == 1:  # human male (monkeys are 0 and 1, humans are 1 and 2)
                    if 0 < age <= 10:
                        age_category = 0
                    elif 10 < age <= 20:
                        age_category = 1
                    elif 20 < age <= 30:
                        age_category = 2
                    elif 30 < age <= 40:
                        age_category = 3
                    elif 40 < age <= 50:
                        age_category = 4
                    elif 50 < age <= 60:
                        age_category = 5
                    elif 60 < age <= 70:
                        age_category = 6
                    elif 70 < age <= 80:
                        age_category = 7
                    elif 80 < age <= 90:
                        age_category = 8
                    elif 90 < age:
                        age_category = 9
                elif gender != 1:
                    if 0 < age <= 10:
                        age_category = 10
                    elif 10 < age <= 20:
                        age_category = 11
                    elif 20 < age <= 30:
                        age_category = 12
                    elif 30 < age <= 40:
                        age_category = 13
                    elif 40 < age <= 50:
                        age_category = 14
                    elif 50 < age <= 60:
                        age_category = 15
                    elif 60 < age <= 70:
                        age_category = 16
                    elif 70 < age <= 80:
                        age_category = 17
                    elif 80 < age <= 90:
                        age_category = 18
                    elif 90 < age:
                        age_category = 19
                children = 0
                if gender == 2:
                    if marriage == 1 and age < 45:
                        children = random.randint(0, 4)  # might already have kids
                    birth_plan_chance = random.random()
                    if birth_plan_chance < 0.03125:
                        birth_plan = 0
                    elif 0.03125 <= birth_plan_chance < 0.1875:
                        birth_plan = 1
                    elif 0.1875 <= birth_plan_chance < 0.5:
                        birth_plan = 2
                    elif 0.5 <= birth_plan_chance < 0.8125:
                        birth_plan = 3
                    elif 0.8125 <= birth_plan_chance < 0.96875:
                        birth_plan = 4
                    else:
                        birth_plan = 5
                elif gender != 2:
                    birth_plan = 0
                human_demographic_structure_list[age_category] += 1
                human = Human(self.human_id_count, self, starting_position, hh_id, age,  # creates human
                              resource_check, starting_position, resource_position,
                              resource_frequency, gender, education, work_status,
                              marriage, past_hh_id, mig_years, migration_status, gtgp_part, non_gtgp_area,
                              migration_network, mig_remittances, income_local_off_farm,
                              last_birth_time, death_rate, age_category, children, birth_plan)
                if self.grid_type == 'with_humans':
                    self.grid.place_agent(human, starting_position)
                    self.schedule.add(human)

        # Creation of monkey families (moving agents in the visualization)
        for i in range(self.number_of_families):  # the following code block creates families
            starting_position = random.choice(startinglist)
            saved_position = starting_position
            from families import Family
            family_size = random.randint(25, 45)  # sets family size for each group--random integer
            family_id = i
            list_of_family_members = []
            family_type = 'traditional'  # as opposed to an all-male subgroup
            split_flag = 0  # binary: 1 means its members start migrating out to a new family
            family = Family(family_id, self, starting_position, family_size, list_of_family_members, family_type,
                            saved_position, split_flag)
            self.grid.place_agent(family, starting_position)
            self.schedule.add(family)
            global_family_id_list.append(family_id)

            # Creation of individual monkeys (not in the visualization submodel, but for the demographic submodel)
            for monkey_family_member in range(family_size):   # creates the amount of monkeys indicated earlier
                id = self.monkey_id_count
                gender = random.randint(0, 1)
                if gender == 1:  # gender = 1 is female, gender = 0 is male. this is different than with humans (1 or 2)
                    female_list.append(id)
                    last_birth_interval = random.uniform(0, 2)
                else:
                    male_maingroup_list.append(id)  # as opposed to the all-male subgroup
                    last_birth_interval = -9999  # males will never give birth
                mother = 0  # no parent check for first generation
                choice = random.random()  # 0 - 1 float - age is determined randomly based on weights
                if choice <= 0.11:  # 11% of starting monkey population
                    age = random.uniform(0, 1)  # are randomly aged befween
                    age_category = 0  # ages 0-1
                    demographic_structure_list[0] += 1
                elif 0.11 < choice <= 0.27:  # 16% of starting monkey population
                    age = random.uniform(1, 3)  # are randomly aged befween
                    age_category = 1  # ages 1-3
                    demographic_structure_list[1] += 1
                elif 0.27 < choice <= 0.42:  # 15% of starting monkey population
                    age = random.uniform(3, 7)  # are randomly aged between
                    age_category = 2  # ages 3-7
                    demographic_structure_list[2] += 1
                elif 0.42 < choice <= 0.62:  # 11% of starting monkey population
                    age = random.uniform(7, 10)  # are randomly aged befween
                    age_category = 3  # ages 7-10
                    demographic_structure_list[3] += 1
                elif 0.62 < choice <= 0.96:  # 34% of starting monkey population
                    age = random.uniform(10, 25)  # are randomly aged befween
                    age_category = 4  # ages 10-25
                    demographic_structure_list[4] += 1
                    if gender == 1:
                        if id not in reproductive_female_list:
                            reproductive_female_list.append(id)
                    # starting representation of male defection/gender ratio
                    structure_convert = random.random()
                    if gender == 0:
                        if structure_convert < 0.6:
                            gender = 1
                            last_birth_interval = random.uniform(0, 3)
                            if id not in reproductive_female_list:
                                reproductive_female_list.append(id)
                elif 0.96 < choice:  # 4% of starting monkey population
                    age = random.uniform(25, 30)  # are randomly aged between
                    age_category = 5  # ages 25-30
                    demographic_structure_list[5] += 1
                    gender = 1
                monkey = Monkey(id, self, gender, age, age_category, family, last_birth_interval, mother
                                )
                self.number_of_monkeys += 1
                self.monkey_id_count += 1
                list_of_family_members.append(monkey.unique_id)
                self.schedule.add(monkey)

    def step(self):
        # necessary; tells model to move forward
        self.time += (1/73)
        self.step_in_year += 1
        if self.step_in_year > 73:
            self.step_in_year = 1  # start new year
        self.schedule.step()

    def _readASCII(self, text):
        # reads in a text file that determines the environmental grid setup
        f = open(text, 'r')
        body = f.readlines()
        width = body[0][-4:]  # last 4 characters of line that contains the 'width' value
        height = body[1][-5:]
        abody = body[6:]  # ASCII file with a header
        f.close()
        abody = reversed(abody)
        cells = []
        for line in abody:
            cells.append(line.split(" "))
        return [cells, int(width), int(height)]

    def _populate(self, masterdict, grid, land_type, width, height):
        # places land tiles on the grid - connects color/land cover category with ASCII file values
        counter = 0  # sets agent ID - not currently used
        for y in range(height):  # for each pixel,
            for x in range(width):
                value = float(grid[y][x])  # value from the ASCII file for that coordinate/pixel, e.g. 1550 elevation
                land_grid_coordinate = x, y
                land = land_type(counter, self)
                if land_type.__name__ == 'Elevation_Out_of_Bound':
                    if (value < land_type.lower_bound or value > land_type.upper_bound) and value != -9999:
                        # if elevation is not 1000-2200, but is within the bounds of the FNNR, mark as 'elevation OOB'
                        self.grid.place_agent(land, land_grid_coordinate)
                        masterdict[land.__class__.__name__].append(land_grid_coordinate)
                        counter += 1
                elif land_type.__name__ == 'Forest':
                    if land_type.type == value:
                        self.grid.place_agent(land, land_grid_coordinate)
                        masterdict[land.__class__.__name__].append(land_grid_coordinate)
                        counter += 1
                elif land_type.__name__ == 'PES':
                    if land_type.type == value:
                        self.grid.place_agent(land, land_grid_coordinate)
                        masterdict[land.__class__.__name__].append(land_grid_coordinate)
                        counter += 1
                elif land_type.__name__ == 'Farm':
                    if land_type.type == value:
                        self.grid.place_agent(land, land_grid_coordinate)
                        masterdict[land.__class__.__name__].append(land_grid_coordinate)
                        counter += 1
                elif land_type.__name__ == 'Household':
                    if land_type.type == value:
                        self.grid.place_agent(land, land_grid_coordinate)
                        masterdict[land.__class__.__name__].append(land_grid_coordinate)
                        counter += 1
                else:  # vegetation background
                    if land_type.type == value:
                        self.grid.place_agent(land, land_grid_coordinate)
                        masterdict[land.__class__.__name__].append(land_grid_coordinate)
                        counter += 1

    def saveLoad(self, pickled_file, name, option):
        """ This function pickles an object, which lets it be loaded easily later.
        I haven't figured out how to utilize pickle to pickle class objects (if possible). """
        if option == "save":
            f = open(name, 'wb')
            pickle.dump(pickled_file, f)
            f.close()
        elif option == "load":
            f = open(name, 'rb')
            new_pickled_file = pickle.load(f)
            return new_pickled_file
        else:
            print('Invalid saveLoad option')
Exemplo n.º 57
0
class DDAModel(Model):
    """A simple DDA model"""

    _width = _WIDTH  # width and height of the world. These shouldn't be changed
    _height = _HEIGHT

    def __init__(self, N, iterations, bleedout_rate=np.random.normal(0.5, scale=0.1), mp=False):
        """
        Create a new instance of the DDA model.
        
        Parameters:
            N - the number of agents
            iterations - the number of iterations to run the model for
            blr - the bleedout rate (the probability that agents leave at the midpoint) (default normal distribution
            with mean=0.5 and sd=0.1)
            mp - whether to use multiprocess (agents call step() method at same time) (doesn't work!) (default False)
        """
        self.num_agents = N
        self._bleedout_rate = bleedout_rate
        self.iterations = iterations
        self.mp = mp

        # Locations of important parts of the environment. These shouldn't be changed
        self.graveyard = (0, 0)  # x,y locations of the graveyard
        self.loc_a = (1, 0)  # Location a (on left side of street)
        self.loc_b = (23, 0)  # Location b (on the right side)
        self.loc_mid = (12, 0)  # The midpoint

        # 'Cameras' that store the number of agents who pass them over the course of an hour. The historical counts
        # are saved by mesa using the DataCollector
        self._camera_a = 0  # Camera A
        self._camera_b = 0  # Camera B
        self._camera_m = 0  # The midpoint

        # Set up the scheduler. Note that this isn't actually used (see below re. agent's stepping)
        self.schedule = RandomActivation(self)  # Random order for calling agent's step methods

        # For multiprocess step method
        self.pool = Pool()

        # Create the environment
        self.grid = MultiGrid(DDAModel._width, DDAModel._height, False)

        # Define a variable that can be used to indicate whether the model has finished
        self.running = True

        # Create a distribution that tells us the number of agents to be added to the world at each
        self._agent_dist = DDAModel._make_agent_distribution(N)

        # Create all the agents
        for i in range(self.num_agents):
            a = DDAAgent(i, self)
            self.schedule.add(a)  # Add the agents to the schedule
            # All agents start as 'retired' in the graveyard
            a.state = AgentStates.RETIRED
            self.grid.place_agent(a, self.graveyard)  # All agents start in the graveyard

        print("Created {} agents".format(len(self.schedule.agents)))

        # Define a collector for model data
        self.datacollector = DataCollector(
            model_reporters={"Bleedout rate": lambda m: m.bleedout_rate,
                             "Number of active agents": lambda m: len(m.active_agents()),
                             "Camera A counts": lambda m: m.camera_a,
                             "Camera B counts": lambda m: m.camera_b,
                             "Camera M counts": lambda m: m.camera_m
                             },
            agent_reporters={"Location (x)": lambda agent: agent.pos[0],
                             "State": lambda agent: agent.state
                             }
        )

    def step(self):
        """Advance the model by one step."""
        print("Iteration {}".format(self.schedule.steps))

        self.datacollector.collect(self)  # Collect data about the model

        # See if the model has finished running.
        if self.schedule.steps >= self.iterations:
            self.running = False
            return

        # Things to do every hour.
        #  - 1 - reset the camera counters
        #  - 2 - activate some agents

        num_to_activate = -1
        s = self.schedule.steps  # Number of steps (for convenience)
        if s % 60 == 0:  # On the hour
            # Reset the cameras
            self._reset_cameras()
            # Calculate the number of agents to activate
            num_to_activate = int(self._agent_dist[int((s / 60) % 24)])
            print("\tActivating {} agents on hour {}".format(num_to_activate, s % 60))

        else:
            num_to_activate = 0
            
        assert num_to_activate >= 0, \
            "The number of agents to activate should be greater or equal to 0, not {}".format(num_to_activate)
            
        if num_to_activate > 0:
            # Choose some agents that are currently retired to activate.
            retired_agents = [a for a in self.schedule.agents if a.state == AgentStates.RETIRED]
            assert len(retired_agents) >= num_to_activate, \
                "Too few agents to activate (have {}, need {})".format(len(retired_agents), num_to_activate)
    
            to_activate = np.random.choice(retired_agents, size=num_to_activate, replace=False)
            print("\t\tActivating agents: {}".format(to_activate))
    
            for a in to_activate:
                a.activate()


        #        XXXX HERE - see line 477 om wprlomgca,eras/py

        # Call all agents' 'step' method.

        if not self.mp:  # Not using multiprocess. Do it the mesa way:
            self.schedule.step()
        else:
            # Better to do it a different way to take advantage of multicore processors and to ignore agents who are not
            # active (no need for them to step at all)
            # NOTE: Doesn't work! The problem is that the DDAAgent needs the DDAModel class, which means
            # that this class needs to be pickled and copied to the child processes. The first problem (which can be
            # fixed by creating functions rather than using lambda, although this is messy) is that DDAModel uses
            # lambda functions, that can't be pickled. Second and more difficult problem is that the Pool object itself
            # cannot be shared. Possible solution here:
            # https://stackoverflow.com/questions/25382455/python-notimplementederror-pool-objects-cannot-be-passed-between-processes
            # but for the meantime I'm not going to try to fix this.
            active_agents = self.active_agents()  # Get all of the active agents
            random.shuffle(active_agents)

            if active_agents is None:
                print("\tNo agents are active")  # Nothing to do
            else:
                p = Pool()
                p.map(DDAAgent._step_agent, active_agents)  # Calls step() for all agents

            # As not using the proper schedule method, need to update time manually.
            self.schedule.steps += 1
            self.schedule.time += 1

    def increment_camera_a(self):
        """Used by agents to tell the model that they have just passed the camera at location A. It would be neater
        to have the cameras detect the agents, but I think that this would be quite expensive."""
        self._camera_a += 1  # Increment the count of the current hour (most recent)

    def increment_camera_b(self):
        """Used by agents to tell the model that they have just passed the camera at location B. It would be neater
        to have the cameras detect the agents, but I think that this would be quite expensive."""
        self._camera_b += 1  # Increment the count of the current hour (most recent)

    def increment_camera_m(self):
        """Used by agents to tell the model that they have just passed the camera at the midpoint. This is only for
        information really, in this scenario there is no camera at the midpoint"""
        self._camera_m += 1  # Increment the count of the current hour (most recent)

    @property
    def camera_a(self) -> int:
        """Getter for the count of the camera at location A"""
        return self._camera_a

    @property
    def camera_b(self) -> int:
        """Getter for the count of the camera at location B"""
        return self._camera_b

    @property
    def camera_m(self) -> int:
        """Getter for the count of the camera at the midpoint"""
        return self._camera_m

    def _reset_cameras(self):
        """Reset the cameras to zero. Done on the hour"""
        self._camera_a = 0
        self._camera_b = 0
        self._camera_m = 0

    @staticmethod
    def _step_agent(a):
        """Call the given agent's step method. Only required because Pool.map doesn't take lambda functions."""
        a.step()

    # bleedout rate is defined as a property: http://www.python-course.eu/python3_properties.php
    @property
    def bleedout_rate(self):
        """Get the current bleedout rate"""
        return self._bleedout_rate

    @bleedout_rate.setter
    def bleedout_rate(self, blr: float) -> None:
        """Set the bleedout rate. It must be between 0 and 1 (inclusive). Failure
        to do that raises a ValueError."""
        if blr < 0 or blr > 1:
            raise ValueError("The bleedout rate must be between 0 and 1, not '{}'".format(blr))
        self._bleedout_rate = blr

    def active_agents(self) -> List[DDAAgent]:
        """Return a list of the active agents (i.e. those who are not retired)"""
        return [a for a in self.schedule.agents if a.state != AgentStates.RETIRED]

    @classmethod
    def _make_agent_distribution(cls, N):
        """Create a distribution that tells us the number of agents to be created at each hour"""
        a = np.arange(0, 24, 1)  # Create an array with one item for each hour
        rv1 = norm(loc=12., scale=6.0)  # A continuous, normal random variable with a peak at 12
        dist = rv1.pdf(a)  # Draw from the random variable pdf, taking values from a
        return [round(item * N, ndigits=0) for item in dist]  # Return a rounded list (the number of agents at each hour)