Example #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
Example #2
0
File: model.py Project: 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()
Example #3
0
File: model.py Project: 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()
Example #4
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()
Example #5
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
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)
Example #7
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()
Example #8
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()
Example #9
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()
Example #10
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()
Example #11
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
Example #12
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
Example #13
0
File: model.py Project: 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()
Example #14
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()
Example #15
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()
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
Example #17
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
Example #18
0
    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)
        self.factors = dict(cohere=cohere, separate=separate, match=match)
        self.make_agents()
        self.running = True
Example #19
0
 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)
     
     # Place a tree in each cell with Prob = density
     for x in range(self.width):
         for y in range(self.height):
             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[y][x] = new_tree
                 self.schedule.add(new_tree)
     self.running = True
Example #20
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)
Example #21
0
    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)
Example #22
0
 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 __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
Example #24
0
    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
Example #25
0
File: model.py Project: GeoESW/mesa
 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()
Example #26
0
    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 __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
Example #28
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()
 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 __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 __init__(self, city_to_country, no_people, total_area, city_to_country_area, countryside, no_agents, Nc_N):
        self.num_agents = no_agents
        grid_size = round(math.sqrt((self.num_agents / no_people) * total_area) * 100)
        self.grid = MultiGrid(grid_size, grid_size, False)
        self.schedule = RandomActivation(self)
        self.running = True

        centers = np.zeros((1, 2))
        centers[0, :] = random.randrange(10, self.grid.width - 10), random.randrange(10, self.grid.height - 10)
        x = np.zeros((1, round(int(city_to_country * self.num_agents))))
        y = np.zeros((1, round(int(city_to_country * self.num_agents))))
        x[0, :] = np.around(np.random.normal(centers[0, 0], 3, round(int(city_to_country * self.num_agents))))
        y[0, :] = np.around(np.random.normal(centers[0, 1], 3, round(int(city_to_country * self.num_agents))))

        count = 0
        countryside_count = 0
        while countryside_count < (countryside * self.num_agents):
            countryside_count += counter(x)
            runner = True
            while runner:
                new_center = (random.randrange(10, self.grid.width - 10), random.randrange(10, self.grid.height - 10))
                if dist_check(new_center, centers):
                    centers = np.vstack((centers, new_center))
                    runner = False

            new_x = np.around(
                np.random.normal(centers[count, 0], (1 / (6 * city_to_country_area * (math.sqrt(count + 1))))
                                 * self.grid.width, round(int(city_to_country * self.num_agents)
                                                          / (count + 2))))
            new_y = np.around(
                np.random.normal(centers[count, 1], (1 / (6 * city_to_country_area * (math.sqrt(count + 1))))
                                 * self.grid.height, round(int(city_to_country * self.num_agents)
                                                           / (count + 2))))
            while len(new_x) < round(int(city_to_country * self.num_agents)):
                new_x = np.append(new_x, -1)
                new_y = np.append(new_y, -1)

            x = np.vstack((x, new_x))
            y = np.vstack((y, new_y))
            count += 1

        label = city_labeler(x)
        for i in range(len(label)):
            city_label[i] = label[i]

        new_x = np.delete(x.flatten(), np.where(x.flatten() == -1))
        new_y = np.delete(y.flatten(), np.where(y.flatten() == -1))

        x_countryside = np.around(np.random.uniform(0, self.grid.width - 1, int(self.num_agents - len(new_x))))
        y_countryside = np.around(np.random.uniform(0, self.grid.height - 1, int(self.num_agents - len(new_y))))

        all_x = np.concatenate((new_x, x_countryside))
        all_y = np.concatenate((new_y, y_countryside))

        for i in range(self.num_agents):
            a = Agent(i, self)
            self.schedule.add(a)
            self.grid.place_agent(a, (int(all_x[i]), int(all_y[i])))
            home_store1[i, :] = int(all_x[i]), int(all_y[i])

            if i == 1:
                a.infected = 1
                #a.working = 1

        n = 50
        flux_store = np.zeros((1, 3))

        for i in range(round(len(centers) / 2)):
            n_cities = random.sample(range(1, round(len(centers) / 3)), n)

            for j in range(len(n_cities)):
                mi = np.count_nonzero(city_label == i+1)
                nj = np.count_nonzero(city_label == n_cities[j])
                radius = math.sqrt((centers[i, 0] - centers[n_cities[j], 0]) ** 2 +
                                   (centers[i, 1] - centers[n_cities[j], 1]) ** 2)
                sij = 0

                for k in range(len(all_x)):
                    if (all_x[k] - centers[i, 0]) ** 2 + (all_y[k] - centers[i, 1]) ** 2 < radius ** 2:
                        sij += 1

                sij = sij - mi - nj
                if sij < 0:
                    sij = 0

                try:
                    Tij = (mi * Nc_N * mi * nj) / ((mi + sij) * (mi + nj + sij))*10
                except ZeroDivisionError:
                    Tij = 0

                if Tij > 75:
                    Tij = 75

                if Tij > 1 and (i != n_cities[j]):
                    flux_store = np.vstack((flux_store, (Tij, i+1, n_cities[j])))

        work_place = np.zeros(self.num_agents)
        work_store1 = np.zeros((num, 2))
        flux_store = np.delete(flux_store, 0, 0)

        for i in np.unique(flux_store[:, 1]):
            place = np.where(flux_store[:, 1] == i)[0]
            place1 = np.where(city_label == i)[0]
            for j in place1:
                for k in place:
                    if random.uniform(0, 100) < flux_store[k, 0]:
                        work_place[j] = flux_store[k, 2]

        for i in range(len(work_store1)):
            if work_place[i] != 0:
                n = int(work_place[i])
                work_store1[i, :] = centers[n, 0], centers[n, 1]

        global work_store, home_store
        work_store = np.int64(work_store1)
        home_store = np.int64(home_store1)

        self.datacollector = DataCollector(
            model_reporters={"Tot informed": compute_informed},
            agent_reporters={"Infected": "infected"})
Example #32
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,
        education_boost=0,
        education_pc=0.2,
        seed=None,
    ):
        """Seed is used to set randomness in the __new__ function of the Model superclass."""
        # pylint: disable-msg=unused-argument,super-init-not-called

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

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

                agent_homophily = homophily
                if self.random.random() < self.education_pc:
                    agent_homophily += self.education_boost

                agent = SchellingAgent((x_coord, y_coord), self, agent_type,
                                       agent_homophily)
                self.grid.position_agent(agent, (x_coord, y_coord))
                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
Example #33
0
class EpsteinCivilViolence(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=40,
        width=40,
        citizen_density=0.7,
        cop_density=0.074,
        citizen_vision=7,
        cop_vision=7,
        legitimacy=0.8,
        max_jail_term=1000,
        active_threshold=0.1,
        arrest_prob_constant=2.3,
        movement=True,
        initial_unemployment_rate=0.1,
        corruption_level=0.1,
        susceptible_level=0.3,
        honest_level=0.6,
        max_iters=1000,
    ):

        super().__init__()
        self.height = height
        self.width = width
        self.citizen_density = citizen_density
        self.cop_density = cop_density
        self.citizen_vision = citizen_vision
        self.cop_vision = cop_vision
        self.legitimacy = legitimacy
        self.max_jail_term = max_jail_term
        self.active_threshold = active_threshold
        self.arrest_prob_constant = arrest_prob_constant
        self.movement = movement
        self.initial_unemployment_rate = initial_unemployment_rate
        self.corruption_level = corruption_level
        self.susceptible_level = susceptible_level
        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),
            "Employed":
            lambda m: self.count_employed(m),
            "Corrupted":
            lambda m: self.count_moral_type_citizens(m, "Corrupted"),
            "Honest":
            lambda m: self.count_moral_type_citizens(m, "Honest"),
            "Susceptible":
            lambda m: self.count_moral_type_citizens(m, "Susceptible")
        }
        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),
            "is_employed": lambda a: getattr(a, "is_employed", None),
            "moral_condition": lambda a: getattr(a, "moral_condition", None),
        }
        self.datacollector = DataCollector(model_reporters=model_reporters,
                                           agent_reporters=agent_reporters)
        unique_id = 0
        if self.cop_density + self.citizen_density > 1:
            raise ValueError(
                "Cop density + citizen density must be less than 1")

        if self.initial_unemployment_rate > 1:
            raise ValueError(
                "initial_unemployment_rate must be between [0,1] ")

        if self.corruption_level + self.susceptible_level > 1:
            raise ValueError("moral level must be less than 1 ")

        for (contents, x, y) in self.grid.coord_iter():
            if self.random.random() < self.cop_density:
                cop = Cop(unique_id, self, (x, y), vision=self.cop_vision)
                unique_id += 1
                self.grid[y][x] = cop
                self.schedule.add(cop)
            elif self.random.random() < (self.cop_density +
                                         self.citizen_density):
                moral_state = "Honest"
                is_employed = 1
                if self.random.random() < self.initial_unemployment_rate:
                    is_employed = 0
                p = self.random.random()
                if p < self.corruption_level:
                    moral_state = "Corrupted"
                elif p < self.corruption_level + self.susceptible_level:
                    moral_state = "Susceptible"

                citizen = Citizen(
                    unique_id,
                    self,
                    (x, y),
                    #updated hardship formula: if agent is employed hardship is alleviated
                    hardship=self.random.random() -
                    (is_employed * self.random.uniform(0.05, 0.15)),
                    legitimacy=self.legitimacy,
                    #updated regime legitimacy, so inital corruption rate is taken into consideration
                    regime_legitimacy=self.legitimacy - self.corruption_level,
                    risk_aversion=self.random.random(),
                    active_threshold=self.active_threshold,
                    #updated threshold: if agent is employed threshold for rebelling is raised
                    threshold=self.active_threshold +
                    (is_employed * self.random.uniform(0.05, 0.15)),
                    vision=self.citizen_vision,
                    is_employed=is_employed,
                    moral_state=moral_state,
                )
                unique_id += 1
                self.grid[y][x] = citizen
                self.schedule.add(citizen)

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

    def step(self):
        """
        Advance the model by one step and collect data.
        """
        self.schedule.step()
        # collect data
        self.datacollector.collect(self)
        self.iteration += 1
        if self.iteration > self.max_iters:
            self.running = False

    @staticmethod
    def count_type_citizens(model, condition, exclude_jailed=False):
        """
        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_moral_type_citizens(model,
                                  moral_condition,
                                  exclude_jailed=False):
        """
        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.moral_state == moral_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

    @staticmethod
    def count_employed(model):
        """
        Helper method to count employed agents.
        """
        count = 0
        for agent in model.schedule.agents:
            if agent.breed == "cop":
                continue
            if agent.is_employed == 1:
                count += 1
        return count

    @staticmethod
    def count_corrupted(model):
        """
        Helper method to count corrupted agents.
        """
        count = 0
        for agent in model.schedule.agents:
            if agent.breed == "cop":
                continue
            if agent.is_corrupted == 1:
                count += 1
        return count
Example #34
0
 def __init__(self, N, maxaffinity, maxeconomic, maxmilitary):
     self.numagents = N
     self.schedule = RandomActivation(self)
     for i in range(self.numagents):
         a = TestAgent(i, self, maxaffinity, maxeconomic, maxmilitary)
         self.schedule.add(a)
class HITLAdopt(Model):

    #modify init method to accout for new parameters and constants
    def __init__(self, height, width, density, wms, wts, wus, td, ve, ae):

        # Initialize model parameters
        self.height = height
        self.width = width
        self.density = density
        self.weeklyCampaignSpend = wms
        self.weeklyTrainingSpend = wts
        self.weeklyUsabilitySpend = wus

        #initialize HITL related parameters
        self.trainingDataWeeklyInput = td
        self.vizEffect = ve

        self.learningRate = 0
        self.dataInstances = 10000
        self.algoAccuracy = ae

        self.algoEffect = self.algoAccuracy *0.1


        # Set up model objects

        #this sets the activation order of the agents (when they make their moves) to be random each step
        self.schedule = RandomActivation(self)

        #this creates the physical grid we are using to simulate word of mouth spread of the model
        self.grid = Grid(height, width, torus=False)

        #these use the Mesa DataCollector method to create several trackers to collect data from the model run
        self.dc_output = DataCollector(model_reporters={"Avg Output Value Per Person Per Week": compute_avg_output})
        self.dc_tracker = DataCollector(model_reporters={"Average IA": compute_avg_ia})
        self.dc_adoption = DataCollector({"Potential Trialer": lambda m: self.count_type(m, "Potential Trialer"),
                                "Trialer": lambda m: self.count_type(m, "Trialer"),
                                "Adopter": lambda m: self.count_type(m, "Adopter"), "Defector": lambda m: self.count_type(m, "Defector"), "Evangelist": lambda m: self.count_type(m, "Evangelist")})
        self.dc_trialers =DataCollector({"Trialer": lambda m: self.count_type(m, "Trialer")})
        self.dc_algo = DataCollector({"Learning Rate": compute_learning_rate})

        self.dc_master=DataCollector({"Potential Trialer": lambda m: self.count_type(m, "Potential Trialer"),
                                "Trialer": lambda m: self.count_type(m, "Trialer"),
                                "Adopter": lambda m: self.count_type(m, "Adopter"),
                                "Defector": lambda m: self.count_type(m, "Defector"),
                                "Evangelist": lambda m: self.count_type(m, "Evangelist"),
                                "Avg Output Value Per Person": compute_avg_output,
                                "Total Differential in Population": hitl_adv_differential,
                                "Algo Accuracy": compute_algo_accuracy,
                                "Algo Accuracy Increase": compute_learning_rate,
                                "Total Dataset Size": compute_data_instances,
                                "Algorithm Effect": compute_algo_effect,
                                "Avg Data Collection Ouput": compute_avg_dc,
                                "Avg Data Interpretation/Analysis Output": compute_avg_di,
                                "Avg Interpreting Actions Output": compute_avg_ia,
                                "Avg Coaching Output": compute_avg_coaching,
                                "Avg Review Output": compute_avg_review})

        #the logic for the creation of the agents, as well as setting the initial values of the agent parameters
        for x in range(self.width):
                for y in range(self.height):
                    if random.random() < self.density:
                        new_consultant = Consultant(self, (x, y), np.random.normal(60, 10), np.random.normal(70, 10), 0)
                        if y == 0:
                            new_consultant.condition = "Trialer"
                        self.grid[y][x] = new_consultant
                        self.schedule.add(new_consultant)

        #run the model when the class is called
        self.running = True




    #define logic of what happens with each time step model-wide
    def step(self):
        ##update algorithm accuracy, data instances, and effect for new weekly data input
        self.learningRate = 10000/self.dataInstances/13 - ((self.count_type(self, "Trialer") +
                                                           self.count_type(self, "Adopter") +
                                                           self.count_type(self, "Evangelist"))/2000000)
        self.algoAccuracy += self.learningRate
        self.dataInstances += self.trainingDataWeeklyInput
        self.algoEffect = self.algoAccuracy * 0.1
        #logic for adoption from marketing, For every 1000 of additional weekly marketing spend, we get 1 new trialer consultant each week
        for i in range (1,(int(self.weeklyCampaignSpend/100))):
            prospect = random.choice(self.schedule.agents)
            #change that agent's state to the next one up
            if prospect.condition == "Potential Trialer":
                prospect.condition = "Trialer"
            if prospect.condition == "Trialer":
                prospect.condition = "Adopter"
       #an abandoned idea for trial abandonment...I instead decided to model this at an agent level in that class (See above)
        '''for i in range (1,(int(self.weeklyMarketingSpend/50))):
            #take a random agent that's a trialer and log their x y location
            prospect = random.choice(model.schedule.agents)
            #change that agent's state to the next one up depending on what it is
            random_num = np.random.randint(1,100)
            if prospect.condition == "Trialer":
                if (prospect.techFluencyScore <70):
                    if random_num > 50:
                        prospect.condition = "PotentialTrialer"
        '''
        #sets the step count
        self.schedule.step()
        #logs appropriate data in each of the data collectors
        self.dc_output.collect(self)
        self.dc_adoption.collect(self)
        self.dc_tracker.collect(self)
        self.dc_algo.collect(self)
        self.dc_trialers.collect(self)
        self.dc_master.collect(self)
        #abandoned logic for stopping model - it was originally when there were no more trialers, now we just give it a set number of steps
    #method for counting the agents and their conditions so we can track adoption methods
    @staticmethod
    def count_type(model, consultant_condition):
        count = 0
        for consultant in model.schedule.agents:
            if consultant.condition == consultant_condition:
                count += 1
        return count
Example #36
0
File: model.py Project: o-date/abm
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 = 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()
    def __init__(self,
                 seed=None,
                 num_nodes=50,
                 preference='attractiveness',
                 mean_male=5,
                 sd_male=1,
                 mean_female=5,
                 sd_female=1,
                 corr_results=pd.DataFrame()):

        self.uid = next(self.id_gen)
        self.num_nodes = num_nodes
        self.preference = preference
        self.mean_male = mean_male
        self.sd_male = sd_male
        self.mean_female = mean_female
        self.sd_female = sd_female
        self.corr_results = corr_results
        self.step_count = 0
        self.G = nx.erdos_renyi_graph(n=self.num_nodes, p=0)
        self.grid = NetworkGrid(self.G)
        self.schedule = RandomActivation(self)
        self.datacollector = DataCollector(model_reporters={
            "number_single": number_single,
            "number_female": number_female,
            "number_union": number_union,
            "mean_attractiveness": mean_attractiveness,
            "corr_results": calculate_correlations,
            "Model Params": track_params,
            "Run": track_run
        },
                                           agent_reporters={
                                               "name":
                                               lambda x: x.name,
                                               "sex":
                                               lambda x: x.S,
                                               "attractiveness":
                                               lambda x: x.A,
                                               "relationship":
                                               lambda x: x.R,
                                               "Model Params":
                                               lambda x: track_params(x.model),
                                               "Run":
                                               lambda x: track_run(x.model)
                                           })

        # Create agents
        for i, node in enumerate(self.G.nodes()):
            person = Human(
                i,
                self,
                "MALE",
                0,
                "SINGLE",
            )
            self.schedule.add(person)
            # Add the agent to the node
            self.grid.place_agent(person, node)
        # convert half of agents to "FEMALE"
        # this need number of agents to always be dividable by 2
        # as set in the user-settable slider
        female_nodes = self.random.sample(self.G.nodes(),
                                          (int(self.num_nodes / 2)))
        for a in self.grid.get_cell_list_contents(female_nodes):
            a.S = "FEMALE"
        # here assign attractiveness based on normal distributions
        for a in self.schedule.agents:
            if a.S == 'MALE':
                A2use = np.random.normal(self.mean_male, self.sd_male, 1)[0]
                while A2use < 1 or A2use > 10:
                    A2use = np.random.normal(self.mean_male, self.sd_male,
                                             1)[0]
                a.A = A2use
            else:
                A2use = np.random.normal(self.mean_female, self.sd_female,
                                         1)[0]
                while A2use < 1 or A2use > 10:
                    A2use = np.random.normal(self.mean_female, self.sd_female,
                                             1)[0]
                a.A = A2use

        self.running = True
        self.datacollector.collect(self)
Example #38
0
    def __init__(self,
                 number_of_customers: list,
                 number_of_infected: list,
                 entry_times: list,
                 social_distance_prob=0.80,
                 size='small'):

        super(SupermarketModel).__init__()

        if isinstance(number_of_customers, int):
            self._num_customers = [number_of_customers]
        elif isinstance(number_of_customers, (list, tuple)):
            self._num_customers = number_of_customers
        if isinstance(number_of_infected, int):
            self._num_infected = [number_of_infected]
        elif isinstance(number_of_infected, (list, tuple)):
            self._num_infected = number_of_infected
        if isinstance(entry_times, int):
            self._entry_times = [entry_times]
        elif isinstance(entry_times, (list, tuple)):
            self._entry_times = entry_times

        assert len(self._num_customers) == len(self._num_infected) == len(
            self._entry_times)

        self._step_count = 0

        #  store environment
        self.width, self.height = STORE_SIZES[size][0] // 2, STORE_SIZES[size][
            1] // 2
        floor_area = self.width * self.height
        #  TODO: Environment should become non-toroidal.
        self.space = ContinuousSpace(self.width, self.height, True)
        model_description = {  # this gets updated during store planning
            "area": floor_area,
            "width": self.width,
            "height": self.height,
        }
        self._store_environment = Store(model_description)
        self.shelves = self._store_environment.generate_store()
        self._generate_store_shelves()

        #  scheduler
        self.schedule = RandomActivation(self)
        if social_distance_prob > 1.0:
            social_distance_prob = social_distance_prob / 100
        self._social_distance_prob = social_distance_prob

        #  data collector
        self._simulated_dataset = pd.DataFrame()
        self.datacollector = DataCollector({
            "Healthy":
            lambda m: self.count_agents_with_state(m, "Healthy"),
            "Risky":
            lambda m: self.count_agents_with_state(m, "Risky"),
            "Exposed":
            lambda m: self.count_agents_with_state(m, "Exposed"),
            "Infected":
            lambda m: self.count_agents_with_state(m, "Infected"),
        })

        #  add shoppers into the supermarket
        self.add_agents(self._num_customers[0], self._num_infected[0])
        del self._num_customers[0]
        del self._num_infected[0]
        self.running = True
        self.datacollector.collect(self)
Example #39
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()
Example #40
0
    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, moore = "Neumann"):
        super().__init__()
        self.height = height
        self.width = width
        self.citizen_density = citizen_density
        self.cop_density = cop_density
        self.citizen_vision = citizen_vision
        self.cop_vision = cop_vision
        self.legitimacy = legitimacy
        self.max_jail_term = max_jail_term
        self.active_threshold = active_threshold
        self.arrest_prob_constant = arrest_prob_constant
        self.movement = movement
        self.running = True
        self.max_iters = max_iters
        self.iteration = 0
        self.schedule = RandomActivation(self)
        self.grid = Grid(height, width, torus=True)
        if moore == "Moore":
            self.moore = 1
        else:
            self.moore = 0

        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, self, (x, y), vision=self.cop_vision)
                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, self, (x, y),
                                  hardship=random.random(),
                                  regime_legitimacy=self.legitimacy,
                                  risk_aversion=random.random(),
                                  threshold=self.active_threshold,
                                  vision=self.citizen_vision)
                unique_id += 1
                self.grid[y][x] = citizen
                self.schedule.add(citizen)
Example #41
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 citizen can inspect, 
            either von Neumann or Moore neighborhood.
        cop_vision: number of cells in each direction that cop can inspect,
            either von Neumann or Moore neighborhood.
        legitimacy:  (L) citizens' perception of regime legitimacy, equal
            across all citizens
        max_jail_term: (J_max), actual jail terms are intergers uniformly distributed from 0 to 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, moore = "Neumann"):
        super().__init__()
        self.height = height
        self.width = width
        self.citizen_density = citizen_density
        self.cop_density = cop_density
        self.citizen_vision = citizen_vision
        self.cop_vision = cop_vision
        self.legitimacy = legitimacy
        self.max_jail_term = max_jail_term
        self.active_threshold = active_threshold
        self.arrest_prob_constant = arrest_prob_constant
        self.movement = movement
        self.running = True
        self.max_iters = max_iters
        self.iteration = 0
        self.schedule = RandomActivation(self)
        self.grid = Grid(height, width, torus=True)
        if moore == "Moore":
            self.moore = 1
        else:
            self.moore = 0

        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, self, (x, y), vision=self.cop_vision)
                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, self, (x, y),
                                  hardship=random.random(),
                                  regime_legitimacy=self.legitimacy,
                                  risk_aversion=random.random(),
                                  threshold=self.active_threshold,
                                  vision=self.citizen_vision)
                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
    def __init__(self, city_to_country, no_people, total_area,
                 city_to_country_area, countryside):
        self.num_agents = 2000
        grid_size = round(
            math.sqrt((self.num_agents / no_people) * total_area) * 100)
        self.grid = MultiGrid(grid_size, grid_size, False)
        self.schedule = RandomActivation(self)
        self.running = True

        centers = np.zeros((1, 2))
        centers[0, :] = random.randrange(
            10,
            self.grid.width - 10), random.randrange(10, self.grid.height - 10)
        x = np.zeros((1, round(int(city_to_country * self.num_agents))))
        y = np.zeros((1, round(int(city_to_country * self.num_agents))))
        x[0, :] = np.around(
            np.random.normal(centers[0, 0], 3,
                             round(int(city_to_country * self.num_agents))))
        y[0, :] = np.around(
            np.random.normal(centers[0, 1], 3,
                             round(int(city_to_country * self.num_agents))))

        count = 0
        countryside_count = 0
        while countryside_count < (countryside * self.num_agents):
            countryside_count += counter(x)
            runner = True
            while runner:
                new_center = (random.randrange(10, self.grid.width - 10),
                              random.randrange(10, self.grid.height - 10))
                if dist_check(new_center, centers):
                    centers = np.vstack((centers, new_center))
                    runner = False

            new_x = np.around(
                np.random.normal(
                    centers[count, 0],
                    (1 / (6 * city_to_country_area *
                          (math.sqrt(count + 1)))) * self.grid.width,
                    round(
                        int(city_to_country * self.num_agents) / (count + 2))))
            new_y = np.around(
                np.random.normal(
                    centers[count, 1],
                    (1 / (6 * city_to_country_area *
                          (math.sqrt(count + 1)))) * self.grid.height,
                    round(
                        int(city_to_country * self.num_agents) / (count + 2))))
            while len(new_x) < round(int(city_to_country * self.num_agents)):
                new_x = np.append(new_x, -1)
                new_y = np.append(new_y, -1)

            x = np.vstack((x, new_x))
            y = np.vstack((y, new_y))
            count += 1

        new_x = np.delete(x.flatten(), np.where(x.flatten() == -1))
        new_y = np.delete(y.flatten(), np.where(y.flatten() == -1))

        x_countryside = np.around(
            np.random.uniform(0, self.grid.width - 1,
                              int(self.num_agents - len(new_x))))
        y_countryside = np.around(
            np.random.uniform(0, self.grid.height - 1,
                              int(self.num_agents - len(new_y))))

        all_x = np.concatenate((new_x, x_countryside))
        all_y = np.concatenate((new_y, y_countryside))

        for i in range(self.num_agents):
            a = Agent(i, self)
            self.schedule.add(a)
            self.grid.place_agent(a, (int(all_x[i]), int(all_y[i])))

            if i == 1:
                a.infected = 1

        self.datacollector = DataCollector(
            model_reporters={"Tot informed": compute_informed},
            agent_reporters={"Infected": "infected"})
Example #43
0
class ContactModel(Model):
    def __init__(self, N, height, width, exponent, steps, seed=None):
        self.number_of_agents = N
        self.height = height
        self.width = width
        self.exponent = exponent

        self.current_step_contacts=[]
        self.adjacency_matrix = np.zeros((N, N))
        self.grid = MultiGrid(self.width, self.height, torus=False)
        self.schedule = RandomActivation(self)

         # Add N pedestrians to model (schedule, grid)
        taken_pos = []
        for i in range(self.number_of_agents):
            while True:
                x = self.random.randrange(1, self.grid.width-1)
                y = self.random.randrange(1, self.grid.height-1)
                pos = (x,y)
                if not pos in taken_pos:
                    break

            new_human = Pedestrian(i, self, pos, self.exponent)
            self.schedule.add(new_human)

            self.grid.place_agent(new_human, pos)
            taken_pos.append(pos)

        self.data_collector=DataCollector()

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

    def contact_update(self, contact_ids):

        contact_ids  =sorted(contact_ids)
        if contact_ids not in self.current_step_contacts:
            self.current_step_contacts.append(contact_ids)


    def update_adjecency_matrix(self):

        #TODO: order agent steps, order updates, double or not
        for id_tuple in self.current_step_contacts:
            self.adjacency_matrix[id_tuple[0], id_tuple[1]]+=1

    def step(self):
        self.schedule.step()
        self.update_adjecency_matrix()
        self.current_step_contacts=[]
        self.data_collector.collect(self)

    def run(self, N):
        for i in range(N):

            self.step()
            if i%100 == 0:
                print(i)

        #distances = []
        #lengths = []
        global_test=[]
        global_trip_info=[]

        for agent in self.schedule.agents:
            agent.trip_info.pop()
            global_trip_info.append(agent.trip_info)

        return global_trip_info
Example #44
0
    def __init__(self, no_people, total_area, no_agents, Nc_N, n, all_x, all_y,
                 centers, infection_rate, city_label, first_infected,
                 mobility_data):
        self.num_agents = no_agents
        grid_size = round(
            math.sqrt((self.num_agents / no_people) * total_area) * 100)
        self.grid = MultiGrid(grid_size, grid_size, False)
        self.schedule = RandomActivation(self)
        self.running = True

        flux_store = np.zeros((1, 3))
        home_store1 = np.zeros((self.num_agents, 2))

        for i in range(round(len(centers) / 2)):
            print(i, datetime.datetime.now() - begin_time)
            n_cities = random.sample(range(1, round(len(centers) / 2)), n)

            for j in range(len(n_cities)):
                mi = np.count_nonzero(city_label == i + 1)
                nj = np.count_nonzero(city_label == n_cities[j])
                radius = math.sqrt(
                    (centers[i, 0] - centers[n_cities[j], 0])**2 +
                    (centers[i, 1] - centers[n_cities[j], 1])**2)
                sij = 0

                for k in range(len(all_x)):
                    if (all_x[k] - centers[i, 0])**2 + (
                            all_y[k] - centers[i, 1])**2 < radius**2:
                        sij += 1

                sij = sij - mi - nj
                if sij < 0:
                    sij = 0

                try:
                    Tij = (mi * Nc_N * mi * nj) / ((mi + sij) *
                                                   (mi + nj + sij)) * 10
                except ZeroDivisionError:
                    Tij = 0

                if Tij > 75:
                    Tij = 75

                if Tij > 1 and (i != n_cities[j]):
                    flux_store = np.vstack(
                        (flux_store, (Tij, i + 1, n_cities[j])))

        work_place = np.zeros(self.num_agents)
        work_store1 = np.zeros((num, 2))
        flux_store = np.delete(flux_store, 0, 0)

        for i in np.unique(flux_store[:, 1]):
            place = np.where(flux_store[:, 1] == i)[0]
            place1 = np.where(city_label == i)[0]
            for j in place1:
                for k in place:
                    if random.uniform(0, 100) < flux_store[k, 0]:
                        work_place[j] = flux_store[k, 2]

        for i in range(len(work_store1)):
            if work_place[i] != 0:
                n = int(work_place[i])
                work_store1[i, :] = centers[n, 0], centers[n, 1]

        for i in range(self.num_agents):
            home_store1[i, :] = int(all_x[i]), int(all_y[i])

        work_store = np.int64(work_store1)
        home_store = np.int64(home_store1)

        for i in range(self.num_agents):
            if mobility_data:
                a = Agent(i, self, infection_rate, work_store, home_store)
                self.schedule.add(a)
                self.grid.place_agent(a, (int(all_x[i]), int(all_y[i])))
            else:
                a = Agent1(i, self, infection_rate, work_store, home_store)
                self.schedule.add(a)
                self.grid.place_agent(a, (int(all_x[i]), int(all_y[i])))

            if i == first_infected:
                a.infected = 1

        self.datacollector = DataCollector(
            model_reporters={"Tot infections": compute_informed},
            agent_reporters={
                "Infected": "infected",
                "R-Number": "rnumber"
            })
Example #45
0
class BankReservesModel(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 coordinate as a random number within the width of the grid
            x = random.randrange(self.width)
            # set y coordinate as a random number within the height of the grid
            y = 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

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

    def run_model(self):
        for i in range(self.run_time):
            self.step()
Example #46
0
class SupermarketModel(Model):
    """
    The generic supermarket model using a continuous environment.
    """

    unique_id = 0

    def __init__(self,
                 number_of_customers: list,
                 number_of_infected: list,
                 entry_times: list,
                 social_distance_prob=0.80,
                 size='small'):

        super(SupermarketModel).__init__()

        if isinstance(number_of_customers, int):
            self._num_customers = [number_of_customers]
        elif isinstance(number_of_customers, (list, tuple)):
            self._num_customers = number_of_customers
        if isinstance(number_of_infected, int):
            self._num_infected = [number_of_infected]
        elif isinstance(number_of_infected, (list, tuple)):
            self._num_infected = number_of_infected
        if isinstance(entry_times, int):
            self._entry_times = [entry_times]
        elif isinstance(entry_times, (list, tuple)):
            self._entry_times = entry_times

        assert len(self._num_customers) == len(self._num_infected) == len(
            self._entry_times)

        self._step_count = 0

        #  store environment
        self.width, self.height = STORE_SIZES[size][0] // 2, STORE_SIZES[size][
            1] // 2
        floor_area = self.width * self.height
        #  TODO: Environment should become non-toroidal.
        self.space = ContinuousSpace(self.width, self.height, True)
        model_description = {  # this gets updated during store planning
            "area": floor_area,
            "width": self.width,
            "height": self.height,
        }
        self._store_environment = Store(model_description)
        self.shelves = self._store_environment.generate_store()
        self._generate_store_shelves()

        #  scheduler
        self.schedule = RandomActivation(self)
        if social_distance_prob > 1.0:
            social_distance_prob = social_distance_prob / 100
        self._social_distance_prob = social_distance_prob

        #  data collector
        self._simulated_dataset = pd.DataFrame()
        self.datacollector = DataCollector({
            "Healthy":
            lambda m: self.count_agents_with_state(m, "Healthy"),
            "Risky":
            lambda m: self.count_agents_with_state(m, "Risky"),
            "Exposed":
            lambda m: self.count_agents_with_state(m, "Exposed"),
            "Infected":
            lambda m: self.count_agents_with_state(m, "Infected"),
        })

        #  add shoppers into the supermarket
        self.add_agents(self._num_customers[0], self._num_infected[0])
        del self._num_customers[0]
        del self._num_infected[0]
        self.running = True
        self.datacollector.collect(self)

    def _check_removed_agent(self):
        """
        Removes an agent from the model's space, once the agent is no longer in the store.

        :return:
        """
        for index in range(len(self.schedule.agents)):
            if self.schedule.agents[index].pos is None:
                self.schedule.agents.pop(index)

    def _generate_store_shelves(self):
        """
        Generates the shelves in the store. The coordinates of these shelves will be marked on the model's space.
        Agents cannot move over these coordinates.

        :return:
        """
        for shelf in range(len(self.shelves)):
            pos = self.shelves[shelf]
            a = StoreShelf(shelf, self, pos=pos)
            self.space.place_agent(a, pos)

    def _save_data(self):
        """
        Fetches the collected data from DataRep, converts the into a dict type and then stores them as pandas DataFrame.
        :return:
        """
        self._check_removed_agent()
        self._simulated_dataset = self._simulated_dataset.append(
            pd.DataFrame(
                asdict(agent.collect_data(self._step_count))
                for agent in self.schedule.agents),
            ignore_index=True)

    def add_agents(self, number_of_shoppers, number_of_infected):
        """
        Creates an instance of the Shopper class, and adds that (along with its attributes) into the model's space.

        :param number_of_shoppers:
        :param number_of_infected:
        :return:
        """
        for agent in range(number_of_shoppers):
            occupy_flag = True
            while occupy_flag:
                x = self.random.randrange(self.space.width)
                y = self.random.randrange(self.space.height)
                if (x, y) not in self.shelves:
                    position = (x, y)
                    occupy_flag = False
                    is_social_distancing = self.random.random(
                    ) < self._social_distance_prob
                    a = Shopper(self,
                                position=position,
                                exit_cell=None,
                                social_distancing=is_social_distancing)

                    if agent <= number_of_infected:
                        a.state = State.INFECTED
                        is_social_distancing = self.random.random(
                        ) < self._social_distance_prob
                        a.social_distancing = is_social_distancing

                    self.space.place_agent(a, (x, y))
                    self.schedule.add(a)

    @staticmethod
    def count_agents_with_state(model, state):
        """
        Helper method to count number of agents in a given state.

        :param model: model instance.
        :param state: given state.
        :return:
        """
        count = 0
        for agent in model.schedule.agents:
            if agent.state.value == state:
                count += 1
        return count

    def get_simulation_result(self):
        """
        Get the result from the simulation.
        :return:
        """
        return self._simulated_dataset

    def step(self):
        """
        Run the model with one step (day).
        """
        self._step_count += 1
        self._save_data()
        self.schedule.step()
        self.datacollector.collect(self)

        if self._step_count in self._entry_times:
            print("{} agents have been added at {}th time step".format(
                self._num_customers[0], self._step_count))
            self.add_agents(self._num_customers[0], self._num_infected[0])
            del self._num_customers[0]
            del self._num_infected[0]
class KalickHamilton(Model):
    """A model following Andre Grow's Netlogo tutorial of Kalick Hamilton 1986
    replicated using Mesa"""

    # id generator to track run number in batch run data
    id_gen = itertools.count(1)

    def __init__(self,
                 seed=None,
                 num_nodes=50,
                 preference='attractiveness',
                 mean_male=5,
                 sd_male=1,
                 mean_female=5,
                 sd_female=1,
                 corr_results=pd.DataFrame()):

        self.uid = next(self.id_gen)
        self.num_nodes = num_nodes
        self.preference = preference
        self.mean_male = mean_male
        self.sd_male = sd_male
        self.mean_female = mean_female
        self.sd_female = sd_female
        self.corr_results = corr_results
        self.step_count = 0
        self.G = nx.erdos_renyi_graph(n=self.num_nodes, p=0)
        self.grid = NetworkGrid(self.G)
        self.schedule = RandomActivation(self)
        self.datacollector = DataCollector(model_reporters={
            "number_single": number_single,
            "number_female": number_female,
            "number_union": number_union,
            "mean_attractiveness": mean_attractiveness,
            "corr_results": calculate_correlations,
            "Model Params": track_params,
            "Run": track_run
        },
                                           agent_reporters={
                                               "name":
                                               lambda x: x.name,
                                               "sex":
                                               lambda x: x.S,
                                               "attractiveness":
                                               lambda x: x.A,
                                               "relationship":
                                               lambda x: x.R,
                                               "Model Params":
                                               lambda x: track_params(x.model),
                                               "Run":
                                               lambda x: track_run(x.model)
                                           })

        # Create agents
        for i, node in enumerate(self.G.nodes()):
            person = Human(
                i,
                self,
                "MALE",
                0,
                "SINGLE",
            )
            self.schedule.add(person)
            # Add the agent to the node
            self.grid.place_agent(person, node)
        # convert half of agents to "FEMALE"
        # this need number of agents to always be dividable by 2
        # as set in the user-settable slider
        female_nodes = self.random.sample(self.G.nodes(),
                                          (int(self.num_nodes / 2)))
        for a in self.grid.get_cell_list_contents(female_nodes):
            a.S = "FEMALE"
        # here assign attractiveness based on normal distributions
        for a in self.schedule.agents:
            if a.S == 'MALE':
                A2use = np.random.normal(self.mean_male, self.sd_male, 1)[0]
                while A2use < 1 or A2use > 10:
                    A2use = np.random.normal(self.mean_male, self.sd_male,
                                             1)[0]
                a.A = A2use
            else:
                A2use = np.random.normal(self.mean_female, self.sd_female,
                                         1)[0]
                while A2use < 1 or A2use > 10:
                    A2use = np.random.normal(self.mean_female, self.sd_female,
                                             1)[0]
                a.A = A2use

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

    def single_union_ratio(self):
        try:
            return number_state(self, "SINGLE") / number_state(self, "UNION")
        except ZeroDivisionError:
            return math.inf

    def do_match_singles(self):
        for a in self.schedule.agents:
            if a.S == 'MALE' and a.R == 'SINGLE':
                a.date_someone()

    def do_calculate_decision_probabilities(self):
        for a in self.schedule.agents:
            if a.R == 'SINGLE':
                a.calculate_decision_probabilities()

    def do_union_decisions(self):
        for a in self.schedule.agents:
            if a.S == 'MALE' and a.R == 'SINGLE':
                a.take_union_decision()

    def step(self):
        # add to step counter
        self.step_count += 1
        self.schedule.step()
        self.do_match_singles()
        self.do_calculate_decision_probabilities()
        self.do_union_decisions()
        # collect data
        self.datacollector.collect(self)
        # if all agents in union or 51 steps past, stop.
        if number_single(self) == 0 or self.step_count == 51:
            self.running = False

    def run_model(self, n):
        for i in range(n):
            self.step()
Example #48
0
class SOCEconModel(Model):
    def __init__(self, num_agents, production_levels, p_consumers, p_orders,
                 do_rewire, fix_demand):
        #random seeds for checkpointing model runs if necessary
        #random.seed(1234)
        #random.seed(4321)

        #model variables
        self.num_agents = num_agents
        self.num_products = 5
        self.p_consumers = p_consumers
        self.num_consumers = 0
        self.p_orders = p_orders
        self.do_rewire = do_rewire
        self.fix_demand = fix_demand
        self.products = []
        self.production_levels = production_levels
        self.num_suppliers = 2
        self.period_demand = 0
        self.period_income = 0
        self.total_income = 0
        self.cascades = {}
        #self.reactions = []

        self.schedule = RandomActivation(self)

        #data collector for visualization
        self.data_collector = DataCollector(model_reporters={
            "Income": get_period_income,
            "Demand": get_period_demand
        })

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

        #assign each producer to two suppliers
        for l in range(0, self.production_levels):
            print("Agents at level ", l)
            next_level_p = []
            for agent in self.schedule.agents:
                if agent.producer_level == l + 1:
                    next_level_p.append(agent)
            for agent in self.schedule.agents:
                if agent.producer_level == l:
                    for supp_num in range(1, self.num_suppliers + 1):
                        agent.suppliers.append(random.choice(next_level_p))

        for agent in self.schedule.agents:
            #debugging output
            #if agent.producer_level < self.production_levels:
            #print('Agent ', agent.unique_id, 'has production level ', agent.producer_level, ' and suppliers: ', agent.suppliers[0].unique_id, agent.suppliers[1].unique_id)
            #print('Agent ', agent.unique_id, 'has production level ', agent.producer_level, ' and suppliers: ', agent.suppliers)
            do_something = False

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

    def step(self):
        #step model forward
        self.period_income = 0
        self.period_demand = 0
        self.order_agents = []
        #calculate number of orders for specified demand p
        self.num_orders = int(self.p_orders * self.num_consumers)
        self.consumers = [
            a.unique_id for a in self.schedule.agents if a.producer_level == 0
        ]
        while len(self.order_agents) < self.num_orders:
            this_agent = random.choice(self.consumers)
            if not this_agent in self.order_agents:
                self.order_agents.append(this_agent)
        if self.fix_demand == False:
            for ra in range(int(.1 * len(self.order_agents))):
                self.order_agents.append(random.choice(self.consumers))

        #print(self.order_agents, len(self.order_agents))
        #add agent (population growth)
        #turned off for now
        if random.random() < 0:
            a = EconAgent(self.num_agents, self)
            self.schedule.add(a)
            self.num_agents += 1
        self.schedule.step()
        self.data_collector.collect(self)
    def __init__(self, height, width, density, wms, wts, wus, td, ve, ae):

        # Initialize model parameters
        self.height = height
        self.width = width
        self.density = density
        self.weeklyCampaignSpend = wms
        self.weeklyTrainingSpend = wts
        self.weeklyUsabilitySpend = wus

        #initialize HITL related parameters
        self.trainingDataWeeklyInput = td
        self.vizEffect = ve

        self.learningRate = 0
        self.dataInstances = 10000
        self.algoAccuracy = ae

        self.algoEffect = self.algoAccuracy *0.1


        # Set up model objects

        #this sets the activation order of the agents (when they make their moves) to be random each step
        self.schedule = RandomActivation(self)

        #this creates the physical grid we are using to simulate word of mouth spread of the model
        self.grid = Grid(height, width, torus=False)

        #these use the Mesa DataCollector method to create several trackers to collect data from the model run
        self.dc_output = DataCollector(model_reporters={"Avg Output Value Per Person Per Week": compute_avg_output})
        self.dc_tracker = DataCollector(model_reporters={"Average IA": compute_avg_ia})
        self.dc_adoption = DataCollector({"Potential Trialer": lambda m: self.count_type(m, "Potential Trialer"),
                                "Trialer": lambda m: self.count_type(m, "Trialer"),
                                "Adopter": lambda m: self.count_type(m, "Adopter"), "Defector": lambda m: self.count_type(m, "Defector"), "Evangelist": lambda m: self.count_type(m, "Evangelist")})
        self.dc_trialers =DataCollector({"Trialer": lambda m: self.count_type(m, "Trialer")})
        self.dc_algo = DataCollector({"Learning Rate": compute_learning_rate})

        self.dc_master=DataCollector({"Potential Trialer": lambda m: self.count_type(m, "Potential Trialer"),
                                "Trialer": lambda m: self.count_type(m, "Trialer"),
                                "Adopter": lambda m: self.count_type(m, "Adopter"),
                                "Defector": lambda m: self.count_type(m, "Defector"),
                                "Evangelist": lambda m: self.count_type(m, "Evangelist"),
                                "Avg Output Value Per Person": compute_avg_output,
                                "Total Differential in Population": hitl_adv_differential,
                                "Algo Accuracy": compute_algo_accuracy,
                                "Algo Accuracy Increase": compute_learning_rate,
                                "Total Dataset Size": compute_data_instances,
                                "Algorithm Effect": compute_algo_effect,
                                "Avg Data Collection Ouput": compute_avg_dc,
                                "Avg Data Interpretation/Analysis Output": compute_avg_di,
                                "Avg Interpreting Actions Output": compute_avg_ia,
                                "Avg Coaching Output": compute_avg_coaching,
                                "Avg Review Output": compute_avg_review})

        #the logic for the creation of the agents, as well as setting the initial values of the agent parameters
        for x in range(self.width):
                for y in range(self.height):
                    if random.random() < self.density:
                        new_consultant = Consultant(self, (x, y), np.random.normal(60, 10), np.random.normal(70, 10), 0)
                        if y == 0:
                            new_consultant.condition = "Trialer"
                        self.grid[y][x] = new_consultant
                        self.schedule.add(new_consultant)

        #run the model when the class is called
        self.running = True
Example #50
0
class Anthill(Model):
    def __init__(self):

        self.grid = SingleGrid(WIDTH, HEIGHT, False)
        self.schedule = RandomActivation(self)
        self.running = True
        self.internalrate = 0.2
        self.ant_id = 1
        self.tau = np.zeros((WIDTH, HEIGHT))
        self.datacollector = DataCollector({
            "Total number of Ants":
            lambda m: self.get_total_ants_number(),
            "mean tau":
            lambda m: self.evaluation1(),
            "sigma":
            lambda m: self.evaluation2(),
            "sigma*":
            lambda m: self.evaluation3(),
        })

        # List containing all coordinates of the boundary, initial ants location and brood location
        self.bound_vals = []
        self.neigh_bound = []
        self.datacollector.collect(self)

        # Make the bound_vals and neigh_bound lists by one of the following:
        # self.nowalls()
        self.onewall()
        # self.twowalls()
        # self.threewalls()

        # Make a Fence boundary
        b = 0
        for h in self.bound_vals:
            br = Fence(b, self)

            self.grid.place_agent(br, (h[0], h[1]))
            b += 1

    def step(self):
        '''Advance the model by one step.'''
        # Add new ants into the internal area ont he boundary

        for xy in self.neigh_bound:

            # Add with probability internal rate and if the cell is empty
            if self.random.uniform(
                    0, 1) < self.internalrate and self.grid.is_cell_empty(
                        xy) == True:

                a = Ant(self.ant_id, self)

                self.schedule.add(a)
                self.grid.place_agent(a, xy)

                self.ant_id += 1

        # Move the ants
        self.schedule.step()
        self.datacollector.collect(self)

        # Remove all ants in neigh_bound

        for (agents, i, j) in self.grid.coord_iter():
            if (i, j) in self.neigh_bound and type(agents) is Ant:

                self.grid.remove_agent(agents)
                self.schedule.remove(agents)

        data_tau.append(self.mean_tau_ant)
        data_sigma.append(np.sqrt(self.sigma))
        data_sigmastar.append(self.sigmastar)

        if len(data_sigmastar) > 2000:
            if abs(data_sigmastar[-2] - data_sigmastar[-1]) < 0.0000001:
                try:
                    # TAU
                    with open("results/m1_tau_inf.pkl", 'rb') as f:
                        tau_old = pickle.load(f)
                        tau_old[int(len(tau_old) + 1)] = data_tau
                        f.close()
                    pickle.dump(tau_old, open("results/m1_tau_inf.pkl", 'wb'))

                except:
                    pickle.dump({1: data_tau},
                                open("results/m1_tau_inf.pkl", 'wb'))

                try:
                    # SIGMA
                    with open("results/m1_sigma_inf.pkl", 'rb') as f:
                        sigma_old = pickle.load(f)
                        sigma_old[int(len(sigma_old) + 1)] = data_sigma
                        f.close()
                    pickle.dump(sigma_old,
                                open("results/m1_sigma_inf.pkl", 'wb'))

                except:
                    pickle.dump({1: data_sigma},
                                open("results/m1_sigma_inf.pkl", 'wb'))

                try:
                    # SIGMASTAR
                    with open("results/m1_sigmastar_inf.pkl", 'rb') as f:
                        sigmastar_old = pickle.load(f)
                        sigmastar_old[int(len(sigmastar_old) +
                                          1)] = data_sigmastar
                        f.close()
                    pickle.dump(sigmastar_old,
                                open("results/m1_sigmastar_inf.pkl", 'wb'))

                except:
                    pickle.dump({1: data_sigmastar},
                                open("results/m1_sigmastar_inf.pkl", 'wb'))

                try:
                    # MATRIX
                    with open("results/m1_matrix_inf.pkl", 'rb') as f:
                        matrix_old = pickle.load(f)
                        matrix_old[int(len(matrix_old) + 1)] = self.tau
                        f.close()
                    pickle.dump(matrix_old,
                                open("results/m1_matrix_inf.pkl", 'wb'))

                except:
                    pickle.dump({1: self.tau},
                                open("results/m1_matrix_inf.pkl", 'wb'))

                self.running = False

        # with open("tau2_new.txt", "a") as myfile:
        #     myfile.write(str(self.mean_tau_ant) + '\n')
        # with open("sigma2_new.txt", "a") as myfile:
        #     myfile.write(str(np.sqrt(self.sigma)) + '\n')
        # with open("datasigmastar2_new.txt","a") as myfile:
        #     myfile.write(str(self.sigmastar) + "\n")

    def nowalls(self):
        # For model without walls:
        for i in range(WIDTH):
            for j in range(HEIGHT):
                if i == 0 or j == 0 or i == WIDTH - 1 or j == HEIGHT - 1:
                    self.bound_vals.append((i, j))
                if i == 1 or i == WIDTH - 2 or j == 1 or j == HEIGHT - 2:
                    self.neigh_bound.append((i, j))

    def onewall(self):
        # For model with ONE wall:
        for i in range(WIDTH):
            for j in range(HEIGHT):
                if i == 0 or j == 0 or i == WIDTH - 1 or j == HEIGHT - 1:
                    self.bound_vals.append((i, j))
                if i == WIDTH - 2 or j == 1 or j == HEIGHT - 2:
                    self.neigh_bound.append((i, j))

    def twowalls(self):
        # For model with TWO walls:
        for i in range(WIDTH):
            for j in range(HEIGHT):
                if i == 0 or j == 0 or i == WIDTH - 1 or j == HEIGHT - 1:
                    self.bound_vals.append((i, j))
                if j == 1 or j == HEIGHT - 2:
                    self.neigh_bound.append((i, j))

    def threewalls(self):
        # For model with THREE walls:
        for i in range(WIDTH):
            for j in range(HEIGHT):
                if i == 0 or j == 0 or i == WIDTH - 1 or j == HEIGHT - 1:
                    self.bound_vals.append((i, j))
                if j == HEIGHT - 2:
                    self.neigh_bound.append((i, j))

    def get_total_ants_number(self):
        total_ants = 0
        for (agents, _, _) in self.grid.coord_iter():
            if type(agents) is Ant:
                total_ants += 1
        return total_ants

    def evaluation1(self):

        ##creat a empty grid to store currently information
        total_ants = np.zeros((WIDTH, HEIGHT))

        ## count the number of currently information
        for (agents, i, j) in self.grid.coord_iter():

            if type(agents) is Ant:
                total_ants[i][j] = 1
            else:
                total_ants[i][j] = 0

        ##update the tau
        self.tau = self.tau + total_ants

        ##calcualte the mean tau
        self.mean_tau_ant = self.tau.sum() / ((WIDTH - 2)**2)

        return self.mean_tau_ant

    def evaluation2(self):

        ## we need to minus the mean tau so we need to ensure the result of boundary is zero
        ## so we let the bounday equal mean_tau_ant in this way the (tau-mean_tau_ant) is zero of boundary
        for site in self.bound_vals:
            self.tau[site[0]][site[1]] = self.mean_tau_ant

        ## calculate the sigmaa
        self.sigma = ((self.tau - self.mean_tau_ant)**2).sum() / (
            (WIDTH - 2)**2)

        ## rechange the boundaryy
        for site in self.bound_vals:
            self.tau[site[0]][site[1]] = 0

        return np.sqrt(self.sigma)

    def evaluation3(self):
        ## calculate the sigmastar
        self.sigmastar = np.sqrt(self.sigma) / self.mean_tau_ant

        return self.sigmastar
Example #51
0
    def __init__(self,
                 background_opinion=Opinion.NO,
                 seeded_opinion=Opinion.YES,
                 num_people=50,
                 num_subcultures=10,
                 avg_node_degree=5,
                 initial_seed_size=3,
                 opinion_change_chance=0.4,
                 opinion_check_frequency=0.4):

        self.num_people = num_people
        self.num_subcultures = num_subcultures
        total_degrees = avg_node_degree * self.num_people
        subculture_degrees = []
        for i in range(self.num_subcultures):
            degrees_left = total_degrees - sum(subculture_degrees)
            subcultures_left = self.num_subcultures - i
            subculture_degrees.append(
                random.randrange(1, degrees_left - subcultures_left
                                 ) if subcultures_left > 1 else degrees_left)

        self.G = bipartite.configuration_model(
            [avg_node_degree] * self.num_people, subculture_degrees)
        people, subcultures = bipartite.sets(self.G)

        self.grid = NetworkGrid(self.G)
        self.schedule = RandomActivation(self)

        self.background_opinion = next(
            (opinion
             for opinion in Opinion if opinion.name == background_opinion),
            None)
        self.seeded_opinion = next(
            (opinion for opinion in Opinion if opinion.name == seeded_opinion),
            None)
        self.initial_seed_size = min(initial_seed_size,
                                     self.num_people + self.num_subcultures)
        self.opinion_change_chance = opinion_change_chance
        self.opinion_check_frequency = opinion_check_frequency

        self.datacollector = DataCollector({
            "Neutral":
            lambda model: opinion_count(model, Opinion.NEUTRAL),
            "Yes":
            lambda model: opinion_count(model, Opinion.YES),
            "No":
            lambda model: opinion_count(model, Opinion.NO)
        })

        # Create People
        for i, node in enumerate(people):
            p = Person(i, self, self.background_opinion,
                       self.opinion_change_chance,
                       self.opinion_check_frequency)
            self.schedule.add(p)
            # Add the Person to the node
            self.grid.place_agent(p, node)

        # Create SubCultures
        for i, node in enumerate(subcultures):
            s = SubCulture(i, self)
            self.schedule.add(s)
            # Add the SubCulture to the node
            self.grid.place_agent(s, node)

        # Seed some opinions
        seed = self.random.sample(subcultures, 1)[0]
        seed_network = nx.algorithms.traversal.depth_first_search.dfs_preorder_nodes(
            self.G, seed)
        for node in islice(seed_network, initial_seed_size):
            person = self.G.nodes[node]['agent'][0]
            person.opinion = self.seeded_opinion

        self.running = True
        self.datacollector.collect(self)
Example #52
0
    def __init__(self,number_voters=2000,number_candidates=5,number_seats=20,polarization=0.5,C=0.8, K=0.05,height=50, width=50):
        super().__init__()
        '''
        Initialising the society class with the values given in inputs: number of voters(agents) , 
        number of parties participating in the election, number of seats in the parliament that need to be filled,
        polarization of the society, confirmation bias(c), social influence strength(k) and size of the grid.
        All other parameters in the model are initialised to 0 and will be calculated later.
        '''
        self.height = height
        self.width = width
        self.number_voters = number_voters
        self.polarization = polarization
        self.number_candidates=number_candidates        
        self.number_seats = number_seats
        self.happiness_fp = 0
        self.happiness_scores = 0
        self.happiness_ranking=0
        
        # moderation index for all voting systems
        self.moderation_FP = 0    #??
        self.moderation_Scores = 0
        self.moderation_Ranking = 0
        
        # parliament distribution for all voting systems
        self.parliament_fp = 0
        self.parliament_scores = 0
        self.parliament_ranking = 0
        
        self.has_neighbours = 0
        self.move_count = 0
        self.avg_move_prob = 0
        self.K = K
        self.C=C
        
        # for simplicity we assume that all the parties are equally spaced on the view spectrum (left-right spectrum)
        parties=np.linspace(0,1,number_candidates)
        self.parties = parties
        self.schedule = RandomActivation(self) 
        
        #Initialise the DataCollector
        self.datacollector = DataCollector(
             { "Happiness FP": lambda m: self.happiness_fp, 
              "Happiness Scores": lambda m: self.happiness_scores,
              "Happiness STV": lambda m: self.happiness_ranking,
              "Moderation_FP": lambda m: self.moderation_FP,
             "Moderation_Scores": lambda m: self.moderation_Scores,
              "Moderation_STV": lambda m: self.moderation_Ranking,
             "Parliament FP": lambda m: self.parliament_fp,
             "Parliament Scores": lambda m: self.parliament_scores,
             "Parliament STV": lambda m: self.parliament_ranking,
             'Move count': lambda m: self.move_count,
             'Avg prob moving': lambda m: self.avg_move_prob})
        
        self.grid = SingleGrid(self.width, self.height, torus=1)
        
        # Initialise voter population
        self.init_population(Voter, self.number_voters)

        
        # This is required for the datacollector to work
        self.running = True
Example #53
0
	def __init__(self, ncells, obstacles_dist, ninjured):
		# used in server start
		self.running = True
		self.ncells = ncells
		self.obstacles_dist = obstacles_dist
		self.ninjured = ninjured

		# grid and schedule representation
		self.grid = MultiGrid(ncells + 2, ncells + 2, torus = False)
		self.schedule = RandomActivation(self)
		# unique counter for agents 
		self.agent_counter = 1
		out_grid = {}
		out_grid["Cell"] = {}
		out_grid["Injured"] = {}
		# place a cell agent for store data and visualization on each cell of the grid
		for i in self.grid.coord_iter():
			if i[1] != 0 and i[2] != 0 and i[1] != self.ncells + 1 and i[2] != self.ncells + 1:
				rand = np.random.random_sample()
				obstacle = True if rand < self.obstacles_dist else False
				if obstacle:
					difficulty = "inf"
					explored = -1
					priority = 0
					utility = "-inf"
				else:
					difficulty = np.random.randint(low = 1, high = 13)
					explored = 0
					priority = 0
					utility = 1.0
			else:
				difficulty = np.random.randint(low = 1, high = 13)
				explored = -2
				priority = "-inf"
				utility = "-inf"

			# generate big wall all across the map
			'''
			_, y, x = i
			if x == 200 or x == 199:
				difficulty = "inf"
				explored = -1
				priority = 0
				utility = "-inf"
			if (x == 200 or x ==199) and (y == 150 or y == 50 or y == 250):
				difficulty = np.random.randint(low = 1, high = 13)
				explored = 0
				priority = 0
				utility = 1.0	
			'''	
			# place the agent in the grid
			out_grid["Cell"][i[1:]]= [self.agent_counter, i[1:], difficulty, explored, priority, utility]
			a = Cell(self.agent_counter, self, i[1:], difficulty, explored, priority, utility)
			self.schedule.add(a)
			self.grid.place_agent(a, i[1:])
			self.agent_counter += 1

		# generate buildings structure	
		'''
		for i in range(0, 50):
			x = rnd.randint(20,300)
			y = rnd.randint(20,300)
			for j in range(0,rnd.randint(0,3)):
				for k in range(0, rnd.randint(0,10)):
					cell = [e for e in self.grid.get_cell_list_contents(tuple([x+j, y+k])) if isinstance(e, Cell)][0]
					cell.difficulty = "inf"
					cell.explored = -1
					cell.priority = 0
					cell.utility = "-inf"
					ag_count = out_grid["Cell"][tuple([x+j,y+k])][0]
					out_grid["Cell"][tuple([x+j,y+k])]= [ag_count, cell.pos, cell.difficulty, cell.explored, cell.priority, cell.utility]
		for i in range(0, 50):
			x = rnd.randint(20,300)
			y = rnd.randint(20,300)
			for j in range(0,rnd.randint(0,3)):
				for k in range(0, rnd.randint(0,10)):
					cell = [e for e in self.grid.get_cell_list_contents(tuple([x+k, y+j])) if isinstance(e, Cell)][0]
					cell.difficulty = "inf"
					cell.explored = -1
					cell.priority = 0
					cell.utility = "-inf"
					ag_count = out_grid["Cell"][tuple([x+k,y+j])][0]
					out_grid["Cell"][tuple([x+k,y+j])]= [ag_count, cell.pos, cell.difficulty, cell.explored, cell.priority, cell.utility]
		'''

		# create injured agents
		valid_coord = []
		for i in self.grid.coord_iter():
			cell = [e for e in self.grid.get_cell_list_contents(i[1:]) if isinstance(e, Cell)][0]
			if cell.explored == 0:
				valid_coord.append(cell.pos)
		for i in range(self.agent_counter, + self.agent_counter + self.ninjured):
			inj_index = rnd.choice(valid_coord)
			out_grid["Injured"][inj_index] = [i, inj_index]
			a = Injured(i, self, inj_index)
			self.schedule.add(a)
			self.grid.place_agent(a, inj_index)	
		with open('robot_exploration/maps/mymap.py', 'w') as f:
			f.writelines([str(out_grid), '\n'])
Example #54
0
class Society(Model):
    def __init__(self,number_voters=2000,number_candidates=5,number_seats=20,polarization=0.5,C=0.8, K=0.05,height=50, width=50):
        super().__init__()
        '''
        Initialising the society class with the values given in inputs: number of voters(agents) , 
        number of parties participating in the election, number of seats in the parliament that need to be filled,
        polarization of the society, confirmation bias(c), social influence strength(k) and size of the grid.
        All other parameters in the model are initialised to 0 and will be calculated later.
        '''
        self.height = height
        self.width = width
        self.number_voters = number_voters
        self.polarization = polarization
        self.number_candidates=number_candidates        
        self.number_seats = number_seats
        self.happiness_fp = 0
        self.happiness_scores = 0
        self.happiness_ranking=0
        
        # moderation index for all voting systems
        self.moderation_FP = 0    #??
        self.moderation_Scores = 0
        self.moderation_Ranking = 0
        
        # parliament distribution for all voting systems
        self.parliament_fp = 0
        self.parliament_scores = 0
        self.parliament_ranking = 0
        
        self.has_neighbours = 0
        self.move_count = 0
        self.avg_move_prob = 0
        self.K = K
        self.C=C
        
        # for simplicity we assume that all the parties are equally spaced on the view spectrum (left-right spectrum)
        parties=np.linspace(0,1,number_candidates)
        self.parties = parties
        self.schedule = RandomActivation(self) 
        
        #Initialise the DataCollector
        self.datacollector = DataCollector(
             { "Happiness FP": lambda m: self.happiness_fp, 
              "Happiness Scores": lambda m: self.happiness_scores,
              "Happiness STV": lambda m: self.happiness_ranking,
              "Moderation_FP": lambda m: self.moderation_FP,
             "Moderation_Scores": lambda m: self.moderation_Scores,
              "Moderation_STV": lambda m: self.moderation_Ranking,
             "Parliament FP": lambda m: self.parliament_fp,
             "Parliament Scores": lambda m: self.parliament_scores,
             "Parliament STV": lambda m: self.parliament_ranking,
             'Move count': lambda m: self.move_count,
             'Avg prob moving': lambda m: self.avg_move_prob})
        
        self.grid = SingleGrid(self.width, self.height, torus=1)
        
        # Initialise voter population
        self.init_population(Voter, self.number_voters)

        
        # This is required for the datacollector to work
        self.running = True
        #self.datacollector.collect(self)
        
        
    def init_population(self, agent_type, n):
        '''
        Making a fixed amount of voters
        '''
        for i in range(n):
            agent = agent_type(self.next_id(), self)
            self.grid.position_agent(agent)
        
            getattr(self, f'schedule').add(agent)
            
 
        
    def happiness_calc(self,ideol,parliament_firstpref,parliament_scores,parliament_ranking):
        '''
         calculates agent's dissatisfaction with the parliament results for all three voting systems using L2 norm of
         the difference between agent's ideology vector and parliament's vector
        '''
        
        Differences_Scores = abs(ideol - parliament_scores)
        Differences_First_Pref = abs(ideol - parliament_firstpref)
        Differences_Ranking = abs(ideol - parliament_ranking)

        Happiness_Scores =   np.sum((Differences_Scores)**2, axis = 1)**(0.5)
        Happiness_First_Pref = np.sum((Differences_First_Pref)**2, axis = 1)**(0.5)
        Happiness_Ranking = np.sum((Differences_Ranking)**2, axis = 1)**(0.5)

        self.happiness_fp = Happiness_First_Pref
        self.happiness_scores = Happiness_Scores
        self.happiness_ranking=Happiness_Ranking
        
    def Moderation_calc(self, parliament_firstpref, parliament_scores, parliament_ranking):
        '''
        Function to calculate how moderate the parliament is.
        moderation of the parliament is sum of the absolute difference between 
        each party's view and complete moderation times the number of seats they own in the parliament
        '''
            
        self.moderation_FP = np.sum(parliament_firstpref * abs(self.parties-0.5))*2
        self.moderation_Scores = np.sum(parliament_scores * abs(self.parties-0.5))*2
        self.moderation_Ranking = np.sum(parliament_ranking * abs(self.parties-0.5))*2
        
    def step(self):
        '''
        Method that calls the step method for each of the voters.
        '''
        self.schedule.step()

    def vote(self):

        '''
        This function collects the ideology vectors of all self.schedule.agents and turns them into votes and
        returns the final parlaimant distriution for all 3 voting systems
        '''
        # Collect ideologies of all agents
        Ideologies_Collection = [a.ideology for a in self.schedule.agents]
        Ideologies_Collection2 = np.stack( Ideologies_Collection, axis=0 ) # Stack into one array

        '''First past the post: assume each agent votes for their favorite party(the one with biggest value in ideology vector)'''
        First_Preference_Votes = np.argmax(Ideologies_Collection2, axis=1) # fins the index(party) of each agent's first preference
        Parlaimant_Distribution_First_Pref = []
        for candidate in range(self.number_candidates):
            #count the votes for each candidate and normalize it
            Parlaimant_Distribution_First_Pref.append(list(First_Preference_Votes).count(candidate)) 
        Parlaimant_Distribution_First_Pref = np.array(Parlaimant_Distribution_First_Pref)/self.number_voters
        a = Parlaimant_Distribution_First_Pref
        quota = 1/self.number_seats # calculate quota for election
        seats=np.zeros(self.number_candidates)
        excess=np.zeros(self.number_candidates)
        for i in range (len(a)):
            if a[i] > quota:
                '''If a party exceeds the quota, allocate the seats to them and calculate the excess votes'''
                temp= int(a[i]/quota)
                seats[i]+= temp
            excess[i]= a[i] % quota
        while (sum(seats)<self.number_seats):
            '''If there are empty seats in the parlaimant allocate them to the party with most excess votes'''
            ind=np.argmax(excess)
            seats[ind]+=1
            excess[ind]=0
        Parlaimant_Distribution_First_Pref = np.array(seats)/self.number_seats #normalize the final distribution of parliament to 1

        '''Scored voting: Each agent assigns a score to each candidate''' 
        '''calculate each party's aggregated scores '''
        Parlaimant_Distribution_Scores = np.sum(Ideologies_Collection2, axis = 0)/self.number_voters 
        a = Parlaimant_Distribution_Scores
        quota = 1/self.number_seats  # calculate quota for election
        seats=np.zeros(self.number_candidates)
        excess=np.zeros(self.number_candidates)
        for i in range (len(a)):
            if a[i] > quota:
                '''If a party exceeds the quota, allocate the seats to them and calculate the excess votes'''
                temp= int(a[i]/quota)
                seats[i]+= temp
            excess[i]= a[i] % quota
        while (sum(seats)<self.number_seats):
           '''If there are empty seats in the parlaimant allocate them to the party with most excess votes'''
           ind=np.argmax(excess)
           seats[ind]+=1
           excess[ind]=0
        Parlaimant_Distribution_Scores = np.array(seats)/self.number_seats

        Parlaimant_Distribution_Ranked=Ranked_vote(self.number_voters,self.number_candidates, self.number_seats, Ideologies_Collection2,quota)
        return(Ideologies_Collection2, Parlaimant_Distribution_First_Pref,Parlaimant_Distribution_Scores,Parlaimant_Distribution_Ranked)
  
        
    def run_model(self, step_count=20):
        
        '''
        Method that runs the model for a specific amount of steps. 
        At each step, the model calls the model step() method (movement).
        We vote every 10 timesteps (can be changed).
        '''
        
        for i in (range(step_count)):
            self.move_count = 0
            self.avg_move_prob = 0
            
            self.step()
            if step_count%10==0:
                '''
                after a pre-defined number of steps agents vote.
                the dissastisfaction with resultsand the moderation of the resulting parliament 
                is calclated in all three voting systems at the same time
                '''
                ideologies,parliament_firstpref,parliament_scores, parliament_ranking = self.vote() 
                self.parliament_fp = parliament_firstpref  
                self.parliament_scores = parliament_scores
                self.parliament_ranking = parliament_ranking

                self.happiness_calc(ideologies,parliament_firstpref,parliament_scores,parliament_ranking)
                self.Moderation_calc(parliament_firstpref,parliament_scores,parliament_ranking)
            self.avg_move_prob = self.avg_move_prob/self.number_voters #average probability of moving is updated to monitor convergence
            
            self.datacollector.collect(self) # collects data from the model
Example #55
0
    def __init__(
        self,
        height=40,
        width=40,
        citizen_density=0.7,
        cop_density=0.074,
        citizen_vision=7,
        cop_vision=7,
        legitimacy=0.8,
        max_jail_term=1000,
        active_threshold=0.1,
        arrest_prob_constant=2.3,
        movement=True,
        initial_unemployment_rate=0.1,
        corruption_level=0.1,
        susceptible_level=0.3,
        honest_level=0.6,
        max_iters=1000,
    ):

        super().__init__()
        self.height = height
        self.width = width
        self.citizen_density = citizen_density
        self.cop_density = cop_density
        self.citizen_vision = citizen_vision
        self.cop_vision = cop_vision
        self.legitimacy = legitimacy
        self.max_jail_term = max_jail_term
        self.active_threshold = active_threshold
        self.arrest_prob_constant = arrest_prob_constant
        self.movement = movement
        self.initial_unemployment_rate = initial_unemployment_rate
        self.corruption_level = corruption_level
        self.susceptible_level = susceptible_level
        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),
            "Employed":
            lambda m: self.count_employed(m),
            "Corrupted":
            lambda m: self.count_moral_type_citizens(m, "Corrupted"),
            "Honest":
            lambda m: self.count_moral_type_citizens(m, "Honest"),
            "Susceptible":
            lambda m: self.count_moral_type_citizens(m, "Susceptible")
        }
        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),
            "is_employed": lambda a: getattr(a, "is_employed", None),
            "moral_condition": lambda a: getattr(a, "moral_condition", None),
        }
        self.datacollector = DataCollector(model_reporters=model_reporters,
                                           agent_reporters=agent_reporters)
        unique_id = 0
        if self.cop_density + self.citizen_density > 1:
            raise ValueError(
                "Cop density + citizen density must be less than 1")

        if self.initial_unemployment_rate > 1:
            raise ValueError(
                "initial_unemployment_rate must be between [0,1] ")

        if self.corruption_level + self.susceptible_level > 1:
            raise ValueError("moral level must be less than 1 ")

        for (contents, x, y) in self.grid.coord_iter():
            if self.random.random() < self.cop_density:
                cop = Cop(unique_id, self, (x, y), vision=self.cop_vision)
                unique_id += 1
                self.grid[y][x] = cop
                self.schedule.add(cop)
            elif self.random.random() < (self.cop_density +
                                         self.citizen_density):
                moral_state = "Honest"
                is_employed = 1
                if self.random.random() < self.initial_unemployment_rate:
                    is_employed = 0
                p = self.random.random()
                if p < self.corruption_level:
                    moral_state = "Corrupted"
                elif p < self.corruption_level + self.susceptible_level:
                    moral_state = "Susceptible"

                citizen = Citizen(
                    unique_id,
                    self,
                    (x, y),
                    #updated hardship formula: if agent is employed hardship is alleviated
                    hardship=self.random.random() -
                    (is_employed * self.random.uniform(0.05, 0.15)),
                    legitimacy=self.legitimacy,
                    #updated regime legitimacy, so inital corruption rate is taken into consideration
                    regime_legitimacy=self.legitimacy - self.corruption_level,
                    risk_aversion=self.random.random(),
                    active_threshold=self.active_threshold,
                    #updated threshold: if agent is employed threshold for rebelling is raised
                    threshold=self.active_threshold +
                    (is_employed * self.random.uniform(0.05, 0.15)),
                    vision=self.citizen_vision,
                    is_employed=is_employed,
                    moral_state=moral_state,
                )
                unique_id += 1
                self.grid[y][x] = citizen
                self.schedule.add(citizen)

        self.running = True
        self.datacollector.collect(self)
Example #56
0
    def __init__(self, init_seed, height, width, density, minority_pc, homophily, virtuous_homophily, nudge_amount, num_to_argue, num_to_convert, convert_prob, convinced_threshold \
            , random_move_prob, traditionless_life_decrease, vir_a, vir_b, vir_c, emo_a, emo_b \
            , emo_c , emo_bias_a, emo_bias_b, emo_bias_c , strongest_belief_weight, count_extra_pow, count_extra_det \
            , count_extra_det_pow, extra_pow, extra_det , belief_of_extra_pow, belief_of_extra_det, belief_of_extra_det_pow):

        # uncomment to make runs reproducible
        super().__init__(seed=init_seed)

        self.height = height
        self.width = width
        self.density = density
        self.minority_pc = minority_pc
        # segregation logic taken from the Schelling segregation model example
        self.homophily = homophily
        self.virtuous_homophily = virtuous_homophily
        self.convert_prob = convert_prob
        self.num_to_convert = num_to_convert
        self.traditionless_life_decrease = traditionless_life_decrease
        self.steps_since = 0

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

        self.happy = 0
        self.convinced = 0
        self.virtuous_count = 0
        self.emotivist_count = 0
        self.virtuous_death_count = 0
        self.datacollector = DataCollector( # Model-level variables for graphs
            {"happy": "happy", "convinced": "convinced", "emotivist_count": "emotivist_count" \
                , "virtuous_count": "virtuous_count", "virtuous_death_count": "virtuous_death_count"},
            {"x": lambda a: a.pos[0], "y": lambda a: a.pos[1], "happy": lambda a: a.happy, # Agent-level variables
            "convinced": lambda a: a.convinced, "strongest_belief": lambda a: a.strongest_belief()
            , "beliefs": lambda a: a.beliefs_string(), "type": lambda a: 0 if isinstance(a, EmotivistAgent) else 1})

        self.nudge_amount = nudge_amount
        self.num_to_argue = num_to_argue
        self.convinced_threshold = convinced_threshold
        self.random_move_prob = random_move_prob

        population = [
            "A", "B", "C"
        ]  # defined here because of dependencies on the visualization side (emo_bias in server.py)
        self.population = population
        probs_emotivist = np.array([emo_a, emo_b, emo_c])
        probs_emotivist = probs_emotivist / np.sum(
            probs_emotivist)  # normalize probs to 1.0
        probs_virtuous = np.array([vir_a, vir_b, vir_c])
        probs_virtuous = probs_virtuous / np.sum(probs_virtuous)
        initial_bias_emotivist = {
            "A": emo_bias_a,
            "B": emo_bias_b,
            "C": emo_bias_c
        }
        self.strongest_belief_weight = strongest_belief_weight

        # Set up agents
        # We get a list of cells in order from the grid iterator
        # and randomize the list
        cell_list = list(self.grid.coord_iter())
        random.shuffle(cell_list)
        total_num_agents = self.density * self.width * self.height

        det_emotivists_added = 0
        pow_emotivists_added = 0
        det_pow_emotivists_added = 0

        # pregenerate a list of strongest_beliefs in random order according to distribution
        # currently only works with a population of 3 beliefs
        list_emotivist_choices = []
        emo_length = ceil((1.0 - self.minority_pc) * total_num_agents)
        for i in range(0, emo_length):
            if (float(i) / emo_length < probs_emotivist[0]):
                list_emotivist_choices.append(population[0])
            elif (float(i) / emo_length <
                  probs_emotivist[0] + probs_emotivist[1]):
                list_emotivist_choices.append(population[1])
            else:
                list_emotivist_choices.append(population[2])

        random.shuffle(list_emotivist_choices)

        list_virtuous_choices = []
        vir_length = ceil(self.minority_pc * total_num_agents)
        for i in range(0, vir_length):
            if (float(i) / vir_length < probs_virtuous[0]):
                list_virtuous_choices.append(population[0])
            elif (float(i) / vir_length <
                  probs_virtuous[0] + probs_virtuous[1]):
                list_virtuous_choices.append(population[1])
            else:
                list_virtuous_choices.append(population[2])

        random.shuffle(list_virtuous_choices)

        # create agents and add to grid
        i = 0
        for cell in cell_list:
            x = cell[1]
            y = cell[2]
            if i < total_num_agents:
                if i < self.minority_pc * total_num_agents:
                    #initial_strongestbelief_virtuous = random.choices(population, weights=probs_virtuous, k=1)[0]
                    initial_strongestbelief_virtuous = list_virtuous_choices.pop(
                    )
                    initial_beliefs_virtuous = {}
                    for belief in population:
                        if (belief == initial_strongestbelief_virtuous):
                            initial_beliefs_virtuous[
                                belief] = strongest_belief_weight
                        else:
                            initial_beliefs_virtuous[belief] = (
                                1 - strongest_belief_weight) / (
                                    len(population) - 1)
                    agent = VirtuousAgent(i, (x, y), self,
                                          initial_beliefs_virtuous)
                    self.virtuous_count += 1
                else:
                    #agent_type = 0
                    #initial_strongestbelief_emotivist = random.choices(population, weights=probs_emotivist, k=1)[0]
                    initial_strongestbelief_emotivist = list_emotivist_choices.pop(
                    )
                    initial_beliefs_emotivist = {}
                    det = 0.0
                    pow = 1.0
                    if (initial_strongestbelief_emotivist
                            == belief_of_extra_det
                            and det_emotivists_added < count_extra_det):
                        det = extra_det
                        det_emotivists_added += 1
                    elif (initial_strongestbelief_emotivist
                          == belief_of_extra_pow
                          and pow_emotivists_added < count_extra_pow):
                        pow = extra_pow
                        pow_emotivists_added += 1
                    elif (initial_strongestbelief_emotivist
                          == belief_of_extra_det_pow
                          and det_pow_emotivists_added < count_extra_det_pow):
                        pow = extra_pow
                        det_pow_emotivists_added += 1

                    for belief in population:
                        if (belief == initial_strongestbelief_emotivist):
                            initial_beliefs_emotivist[
                                belief] = strongest_belief_weight
                        else:
                            initial_beliefs_emotivist[belief] = (
                                1 - strongest_belief_weight) / (
                                    len(population) - 1)

                    agent = EmotivistAgent(i, (x, y), self,
                                           initial_beliefs_emotivist,
                                           initial_bias_emotivist, pow, det)
                    self.emotivist_count += 1

                i += 1
                self.grid.position_agent(agent, (x, y))
                self.schedule.add(agent)

        self.last_agent_id = i
        # update message with starting probs
        self.message = "Emotivist probs: " + str(list(map(lambda x: "{:.2f}".format(x), probs_emotivist.tolist()))) \
                + ", Virtuous probs: " + str(list(map(lambda x: "{:.2f}".format(x), probs_virtuous.tolist())))
        self.running = True
        self.datacollector.collect(self)
Example #57
0
    def __init__(self,
                 width=0,
                 height=0,
                 torus=False,
                 time=0,
                 step_in_year=0,
                 number_of_families=0,
                 number_of_monkeys=0,
                 monkey_birth_count=0,
                 monkey_death_count=0,
                 monkey_id_count=0,
                 number_of_humans=0,
                 grid_type=0,
                 run_type=0,
                 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
        if self.number_of_families == 0:
            self.number_of_families = int(setting_list[0])
        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
        if self.grid_type == 0:
            self.grid_type = str(
                setting_list[1])  # string ''With Humans' or 'Without Humans'
        self.run_type = run_type
        if self.run_type == 0:
            self.run_type = str(
                setting_list[2])  # 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

        try:
            household_file = file_list[0]
            farm_file = file_list[1]
            forest_file = file_list[2]
        except IndexError:  # if you run server.py instead of gui.py
            household_file = 'hh_ascii400.txt'
            farm_file = 'farm_ascii300.txt'
            forest_file = 'forest_ascii200.txt'
        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 (red 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 fertility_scenario[0] == '2.5':
                        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 fertility_scenario[0] == '1.5':
                        if birth_plan_chance < 0.09:
                            birth_plan = 0
                        elif 0.09 <= birth_plan_chance < 0.59:
                            birth_plan = 1
                        elif 0.59 <= birth_plan_chance < 0.89:
                            birth_plan = 2
                        elif 0.89 <= birth_plan_chance < 0.95:
                            birth_plan = 3
                        elif 0.95 <= birth_plan_chance < 0.98:
                            birth_plan = 4
                        else:
                            birth_plan = 5
                    elif fertility_scenario[0] == '3.5':
                        if birth_plan_chance < 0.02:
                            birth_plan = 0
                        elif 0.02 <= birth_plan_chance < 0.04:
                            birth_plan = 1
                        elif 0.04 <= birth_plan_chance < 0.08:
                            birth_plan = 2
                        elif 0.08 <= birth_plan_chance < 0.46:
                            birth_plan = 3
                        elif 0.46 <= birth_plan_chance < 0.9:
                            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 fertility_scenario[0] == '2.5':
                        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 fertility_scenario[0] == '1.5':
                        if birth_plan_chance < 0.09:
                            birth_plan = 0
                        elif 0.09 <= birth_plan_chance < 0.59:
                            birth_plan = 1
                        elif 0.59 <= birth_plan_chance < 0.89:
                            birth_plan = 2
                        elif 0.89 <= birth_plan_chance < 0.95:
                            birth_plan = 3
                        elif 0.95 <= birth_plan_chance < 0.98:
                            birth_plan = 4
                        else:
                            birth_plan = 5
                    elif fertility_scenario[0] == '3.5':
                        if birth_plan_chance < 0.02:
                            birth_plan = 0
                        elif 0.02 <= birth_plan_chance < 0.04:
                            birth_plan = 1
                        elif 0.04 <= birth_plan_chance < 0.08:
                            birth_plan = 2
                        elif 0.08 <= birth_plan_chance < 0.46:
                            birth_plan = 3
                        elif 0.46 <= birth_plan_chance < 0.9:
                            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)
Example #58
0
class VirusModel(Model):
    def __init__(self, num_nodes, avg_node_degree, initial_outbreak_size, alpha, beta, gamma, delta, k, n):

        self.num_nodes = num_nodes
        self.avg_node_degree = avg_node_degree
        self.G = nx.barabasi_albert_graph(n=self.num_nodes,m=avg_node_degree)
        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.alpha = alpha
        self.beta = beta
        self.gamma = gamma
        self.delta = delta

        self.k=k
        self.n=n

        # Create agents
        for i, node in enumerate(self.G.nodes()):
            a = VirusAgent(i, self, State.SUSCEPTIBLE, self.alpha, self.beta, self.gamma, self.delta, self.k, self.n)
            self.schedule.add(a)
            # Add the agent to the node
            self.grid.place_agent(a, node)

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

        self.datacollector = DataCollector(
            model_reporters={
                             "Infected": number_active,
                             "Susceptible": number_susceptible,
                             "Carrier": number_inactive,
                             "Removed": number_removed,
                             "Active Clustering": infective_clustering,
                             "Exposed Clustering": exposed_clustering,
                             "Infective Diffusion": infective_diffusion,
                             "Exposed Diffusion": exposed_diffusion
                             }
        )

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

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

    def tyrant_remove(self):
        if number_active(self) > 0:
            if random.random() < 0.002:
                actives = [a for a in self.grid.get_all_cell_contents() if a.state is State.ACTIVE]
                node_for_removal = random.sample(actives, 1)
                for a in node_for_removal:
                    a.state = State.REMOVED
        # for a in self.grid.get_cell_list_contents(active_nodes):
        #     a.state = State.ACTIVE

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

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

    def __init__(self,b =35.98, a = 0.6933, beta = 0.95, delta = 0.08, theta = 0.8,N=100): #N- number of agents
        self.N = N
        self.b = 35.98
        self.a = 0.6933
        self.agents = []
        self.t = 0
        self.beta = 0.95
        self.delta = 0.08
        self.theta = 0.8
        self.time = 1 #for sensitivity analysis
        self.G = nx.barabasi_albert_graph(n=N, m = 1)
        nx.set_edge_attributes(self.G, 1, 'weight') #setting all initial edges with a weight of 1
        self.nodes = np.linspace(0,N-1,N, dtype = 'int') #to keep track of the N nodes   
        self.schedule = RandomActivation(self)
        self.datacollector = DataCollector(model_reporters =
        {'b': 'b', 'a': 'a','delta':'delta','theta':'theta', 
         'beta': 'beta', 'TotalTrap': 'Count','TotalSwitch':'total',
         'Threshold':'t'}, agent_reporters={"k":'k','lamda':'lamda','abilitity':'alpha', 'technology':'tec'})
                                                                   
        
        for i, node in enumerate(self.G.nodes()):
            agent = MoneyAgent(i, self)
            self.schedule.add(agent)
           
        self.running = True
        self.datacollector.collect(self)
        
    def Global_Attachment(self):
        #print("Global Attachment no: {}".format(self.count))
        node1 = random.choice(self.nodes)
        node2 = random.choice(self.nodes)
        while(self.G.has_edge(node1,node2)==True):
            node2 = random.choice(self.nodes)
            node1 = random.choice(self.nodes)
        #adding the edge node1-node2
        for agent in self.agents:
            if(agent.unique_id == node1):
                node1_a = agent
            if(agent.unique_id == node2):
                node2_a = agent
        self.G.add_edge(node1,node2,weight = Edge_Weight(node1_a,node2_a, self.b, self.a)) 
        

    def step(self):
        #print(self.time)
        self.schedule.step()
        # collect data
        self.Global_Attachment() #for sensitivity analysis
        self.datacollector.collect(self)
        agent_df = self.datacollector.get_agent_vars_dataframe()
        agent_df.reset_index(level=['Step','AgentID'], inplace = True)
        k = agent_df.k.to_numpy()
        self.t = np.percentile(k,q=10)
        #print("Threshold = ", self.t)
        count = 0
        #trap = []
        agents = []
        for agent in self.nodes: 
            df = agent_df.loc[(agent_df["AgentID"] == agent)& (agent_df['k']<self.t)].reset_index(drop=True)
            if(not df.empty):
                agents.append(agent)
                j = int(df.loc[0].Step)
                count = 0
                while(j < len(df)-1):
                    if(int(df.loc[j+1].Step) - int(df.loc[j].Step) == 1):
                        count+=1
                    j+=1
                    #print("i = ", i)
                #trap.append(count)
                self.Count = count
        #self.fit_alpha, self.fit_loc, self.fit_beta=stats.gamma.fit(trap)
        self.time +=1#
        #counting number of switches
        switch = {'Agent': [], 'Total': []}
        for agent in self.nodes:
            df = agent_df.loc[agent_df.AgentID == agent].reset_index(drop = True)
            tech = df.technology.to_numpy()
            count = 0
            for i in range(len(tech)-1):
                if((tech[i] == 'L' and tech[i+1] == 'H') or (tech[i] == 'H' and tech[i+1] == 'L')):
                    count +=1
            if(count):
                switch['Agent'].append(agent)
                switch['Total'].append(count)
        switch = pd.DataFrame(switch)
        no_switch = switch.Total.unique()
        no_switch.sort()
        total = {no_switch[i]:[] for i in range(len(no_switch))}
        #print(total)
        for i in no_switch:
            total[i] = len(switch.loc[switch.Total == i])
        #print(total) 
        self.total = total

         
    def run_model(self, n):
        for i in tqdm(range(n)):
            self.time = i+1
            self.step()
Example #60
0
class Network(Model):
    def __init__(self, N, no_of_neighbors, network_type, beta_component,
                 similarity_treshold, social_influence, swingers, malicious_N,
                 echo_threshold):
        self.num_agents = N
        self.G = select_network_type(
            network_type, N, no_of_neighbors, beta_component
        )  #nx.watts_strogatz_graph(N, no_of_neighbors, rand_neighbors, seed=None)
        self.grid = NetworkGrid(self.G)
        self.schedule = RandomActivation(self)
        # self.node_positions = nx.spring_layout(self.G)
        self.node_list = self.random.sample(self.G.nodes(), self.num_agents)
        self.layout = nx.spring_layout(self.G, dim=2)
        self.step_no = 0
        self.similarity_treshold = similarity_treshold
        self.social_influence = social_influence
        self.swingers = swingers
        self.malicious_N = malicious_N
        self.echo_threshold = echo_threshold
        # Initialy set to 1 agreement and 1 agreement to avoid 100%/0% probability scenrarios
        nx.set_edge_attributes(self.G, 2, 'total_encounters')
        nx.set_edge_attributes(self.G, 1, 'times_agreed')
        nx.set_edge_attributes(self.G, .5, 'trust')

        self.place_agents()

        self.set_malicious()

        self.datacollector = DataCollector(
            model_reporters={
                "preferences": compute_preferences,
                "opinion": compute_opinions,
                "preference_A": compute_preference_A,
                "preference_B": compute_preference_B,
                "radical_opinions": compute_radical_opinions,
                "community_no": community_no,
                "community_all": community_all,
                "silent_spiral": compute_silent_spiral,
                "echo_no": echo_no
                # "graph": return_network
            },
            agent_reporters={
                "preference": "preference",
            })

        self.running = True
        # return_network(self)

    # place agents on network
    def place_agents(self):
        for i in range(self.num_agents):
            a = agent(i, self)
            self.grid.place_agent(a, self.node_list[i])
            self.schedule.add(a)

    # Update trust between nodes
    def update_edge(self, node1, node2):
        # Get opinion of agents
        opinionA = self.G.nodes()[node1]['agent'][0].opinion
        opinionB = self.G.nodes()[node2]['agent'][0].opinion

        self.G.edges[node1, node2]['total_encounters'] += 1
        # If agents share opinion, edge strength increases
        if (opinionA == opinionB):
            self.G.edges[node1, node2]['times_agreed'] += 1

        self.G.edges[node1, node2]['trust'] = self.G.edges[node1, node2][
            'times_agreed'] / self.G.edges[node1, node2]['total_encounters']

    def step(self):
        # nx.draw(self.G, pos=nx.spring_layout(self.G))
        # plt.show()
        self.datacollector.collect(self)
        self.perturb_network()
        self.schedule.step()
        self.step_no += 1
        # print(nx.get_edge_attributes(self.G, 'trust'))

    def perturb_network(self):
        agent_nodes = np.random.randint(self.num_agents,
                                        size=(1, self.swingers))
        for node in agent_nodes:
            agent = self.G.nodes()[np.random.randint(
                self.num_agents)]['agent'][0]
            agent.opinion = np.random.randint(2)
            agent.preference = set_rand_unifrom_preference()

    def set_malicious(self):
        centrality_dict = nx.degree_centrality(self.G)
        most_central = nlargest(self.malicious_N,
                                centrality_dict,
                                key=centrality_dict.get)
        test = 0
        for a in most_central:
            self.G.nodes()[a]["agent"][0].opinion = 0
            self.G.nodes()[a]["agent"][0].preference = 1