コード例 #1
1
ファイル: ForestFire.py プロジェクト: CHEN-JIANGHANG/mesa
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
コード例 #2
0
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)
コード例 #3
0
ファイル: model.py プロジェクト: 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()
コード例 #4
0
ファイル: model.py プロジェクト: bangtree/mesa
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()
コード例 #5
0
ファイル: MoneyModel.py プロジェクト: Eleonore9/mesa
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()
コード例 #6
0
ファイル: Schelling.py プロジェクト: DanielWeitzenfeld/mesa
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
コード例 #7
0
ファイル: model.py プロジェクト: hypeserver/ajan
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()
コード例 #8
0
ファイル: model.py プロジェクト: projectmesa/mesa
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()
コード例 #9
0
ファイル: model.py プロジェクト: dadaromeo/bayes-dap
class Foraging(Model):
    
    number_of_bean = 0
    number_of_corn = 0
    number_of_soy = 0
    
    def __init__(self, width=50, height=50, torus=True, num_bug=50, seed=42, strategy=None):
        super().__init__(seed=seed)
        self.number_of_bug = num_bug
        if not(strategy in ["stick", "switch"]):
            raise TypeError("'strategy' must be one of {stick, switch}")
        self.strategy = strategy
        
        self.grid = SingleGrid(width, height, torus)
        self.schedule = RandomActivation(self)
        data = {"Bean": lambda m: m.number_of_bean,
                "Corn": lambda m: m.number_of_corn,
                "Soy": lambda m: m.number_of_soy,
                "Bug": lambda m: m.number_of_bug,
                }
        self.datacollector = DataCollector(data)
        
        # create foods
        self._populate(Bean)
        self._populate(Corn)
        self._populate(Soy)
        
        # create bugs
        for i in range(self.number_of_bug):
            pos = self.grid.find_empty()
            bug = Bug(i, self)
            bug.strategy = self.strategy
            self.grid.place_agent(bug, pos)
            self.schedule.add(bug)
    
    def step(self):
        self.schedule.step()
        self.datacollector.collect(self)
        
        if not(self.grid.exists_empty_cells()):
            self.running = False
    
    def _populate(self, food_type):
        prefix = "number_of_{}"
        
        counter = 0
        while counter < food_type.density * (self.grid.width * self.grid.height):
            pos = self.grid.find_empty()
            food = food_type(counter, self)
            self.grid.place_agent(food, pos)
            self.schedule.add(food)
            food_name = food_type.__name__.lower()
            attr_name = prefix.format(food_name)
            val = getattr(self, attr_name)
            val += 1
            setattr(self, attr_name, val)
            counter += 1
コード例 #10
0
ファイル: model.py プロジェクト: bangtree/mesa
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
コード例 #11
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
コード例 #12
0
ファイル: pd_grid.py プロジェクト: csmaxwell/mesa
class PD_Model(Model):
    '''
    Model class for iterated, spatial prisoner's dilemma model.
    '''

    schedule_types = {"Sequential": BaseScheduler,
                      "Random": RandomActivation,
                      "Simultaneous": SimultaneousActivation}

    # This dictionary holds the payoff for this agent,
    # keyed on: (my_move, other_move)

    payoff = {("C", "C"): 1,
              ("C", "D"): 0,
              ("D", "C"): 1.6,
              ("D", "D"): 0}

    def __init__(self, height, width, schedule_type, payoffs=None):
        '''
        Create a new Spatial Prisoners' Dilemma Model.

        Args:
            height, width: Grid size. There will be one agent per grid cell.
            schedule_type: Can be "Sequential", "Random", or "Simultaneous".
                           Determines the agent activation regime.
            payoffs: (optional) Dictionary of (move, neighbor_move) payoffs.
        '''
        self.running = True
        self.grid = SingleGrid(height, width, torus=True)
        self.schedule_type = schedule_type
        self.schedule = self.schedule_types[self.schedule_type](self)

        # Create agents
        for x in range(width):
            for y in range(height):
                agent = PD_Agent((x, y), self)
                self.grid.place_agent(agent, (x, y))
                self.schedule.add(agent)

        self.datacollector = DataCollector({
            "Cooperating_Agents":
            lambda m: len([a for a in m.schedule.agents if a.move == "C"])
        })

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

    def run(self, n):
        '''
        Run the model for a certain number of steps.
        '''
        for _ in range(n):
            self.step()
コード例 #13
0
class InspectionModel(Model):
    '''
    Simple Restaurant Inspection model.
    '''
    def __init__(self, height, width, density):
        '''
        Create a new restaurant inspection model.

        Args:
            height, width: The size of the grid to model
            density: What fraction of grid cells have a restaurant in them.
        '''
        # Initialize model parameters
        self.height = height
        self.width = width
        self.density = density

        # Set up model objects
        self.schedule = RandomActivation(self)
        self.grid = Grid(height, width, torus=False)

        self.datacollector = DataCollector(
            {"Good": lambda m: self.count_type(m, "Good"),
             "Bad": lambda m: self.count_type(m, "Bad")})

        # Place a restaurant in each cell with Prob = density
        for (contents, x, y) in self.grid.coord_iter():
            if random.random() < self.density:
                # Create a restaurant
                new_restaurant = RestaurantCell((x, y))
                self.grid._place_agent((x, y), new_restaurant)
                self.schedule.add(new_restaurant)
        self.running = True

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

    @staticmethod
    def count_type(model, restaurant_hygiene):
        '''
        Helper method to count restaurants in a given condition in a given model.
        '''
        count = 0
        for restaurant in model.schedule.agents:
            if restaurant.hygiene == restaurant_hygiene and restaurant.rating != 'Closed':
                count += 1
        return count
コード例 #14
0
ファイル: model.py プロジェクト: bangtree/mesa
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()
コード例 #15
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
コード例 #16
0
ファイル: sir_model.py プロジェクト: i-Zaak/linum
class SIR_Network_Model(Model):
    def __init__(self, g=None, outbreak_size=3, si_trans=0.025, ir_trans=0.05):
        self.schedule = SimultaneousActivation(self)
        
        if g is None:
            g = nx.random_graphs.watts_strogatz_graph(100, 4, 0.05) 

        self.si_trans = si_trans
        self.ir_trans = ir_trans

        nodes = g.nodes()
        agent_nodes = list(map(lambda x: SIR_Agent(x), nodes))
        n_map = dict(zip(nodes, agent_nodes))
        agent_edges = list(map(lambda e: (n_map[e[0]], n_map[e[1]])  , g.edges()))

        for agent in agent_nodes:
            self.schedule.add(agent)
        # set the initial outbreak
        for node in sample(list(agent_nodes), outbreak_size):
            node.state = State.infected

        self.network = NetworkSpace(agent_nodes, agent_edges)
        self.dc = DataCollector({"susceptible": lambda m: self.count_state(m, State.susceptible),
                                "infected": lambda m: self.count_state(m, State.infected),
                                "resistant": lambda m: self.count_state(m, State.resistant)},
                                {"state": lambda a: a.state.value}
                                )
        self.dc.collect(self) #initial state

        self.running = True

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

        # disease dead?
        if self.count_state(self, State.infected) == 0:
            self.running = False

    @staticmethod
    def count_state(model,state):
        count = 0
        for agent in model.schedule.agents:
            if agent.state == state:
                count +=1
        return count
コード例 #17
0
class MockModel(Model):
    '''
    Minimalistic model for testing purposes.
    '''

    schedule = BaseScheduler(None)

    def __init__(self):
        self.schedule = BaseScheduler(self)
        for i in range(10):
            a = MockAgent(i, i)
            self.schedule.add(a)
        self.datacollector = DataCollector(
            {"total_agents": lambda m: m.schedule.get_agent_count()},
            {"value": lambda a: a.val},
            {"Final_Values": ["agent_id", "final_value"]})

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

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

    def step(self):
        self.schedule.step()
        self.dc.collect(self)
コード例 #19
0
ファイル: test_lifespan.py プロジェクト: csmaxwell/mesa
class LifeTimeModel(Model):
    '''Simple model for running models with a finite life'''
    def __init__(self, agent_lifetime = 1, n_agents = 10):
        super().__init__()
        
        self.agent_lifetime = agent_lifetime
        self.n_agents = n_agents

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

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

    def run_model(self, step_count = 100):
        for _ in range(step_count):
            self.step()
コード例 #20
0
ファイル: model.py プロジェクト: GeoESW/mesa
class Sugarscape2ConstantGrowback(Model):
    '''
    Sugarscape 2 Constant Growback
    '''

    verbose = True  # Print-monitoring

    def __init__(self, height=50, width=50,
                 initial_population=100):
        '''
        Create a new Constant Growback model with the given parameters.

        Args:
            initial_population: Number of population to start with
        '''

        # Set parameters
        self.height = height
        self.width = width
        self.initial_population = initial_population

        self.schedule = RandomActivationByBreed(self)
        self.grid = MultiGrid(self.height, self.width, torus=False)
        self.datacollector = DataCollector({"SsAgent": lambda m: m.schedule.get_breed_count(SsAgent), })

        # Create sugar
        import numpy as np
        sugar_distribution = np.genfromtxt("sugarscape/sugar-map.txt")
        for _, x, y in self.grid.coord_iter():
            max_sugar = sugar_distribution[x, y]
            sugar = Sugar((x, y), self, max_sugar)
            self.grid.place_agent(sugar, (x, y))
            self.schedule.add(sugar)

        # Create agent:
        for i in range(self.initial_population):
            x = random.randrange(self.width)
            y = random.randrange(self.height)
            sugar = random.randrange(6, 25)
            metabolism = random.randrange(2, 4)
            vision = random.randrange(1, 6)
            ssa = SsAgent((x, y), self, False, sugar, metabolism, vision)
            self.grid.place_agent(ssa, (x, y))
            self.schedule.add(ssa)

        self.running = True

    def step(self):
        self.schedule.step()
        self.datacollector.collect(self)
        if self.verbose:
            print([self.schedule.time,
                   self.schedule.get_breed_count(SsAgent)])

    def run_model(self, step_count=200):

        if self.verbose:
            print('Initial number Sugarscape Agent: ',
                  self.schedule.get_breed_count(SsAgent))

        for i in range(step_count):
            self.step()

        if self.verbose:
            print('')
            print('Final number Sugarscape Agent: ',
                  self.schedule.get_breed_count(SsAgent))
コード例 #21
0
ファイル: model.py プロジェクト: bangtree/mesa
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()
コード例 #22
0
ファイル: model.py プロジェクト: nickmalleson/surf
class DDAModel(Model):
    """A simple DDA model"""

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

        # Call all agents' 'step' method.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    @classmethod
    def _make_agent_distribution(cls, N):
        """Create a distribution that tells us the number of agents to be created at each hour"""
        a = np.arange(0, 24, 1)  # Create an array with one item for each hour
        rv1 = norm(loc=12., scale=6.0)  # A continuous, normal random variable with a peak at 12
        dist = rv1.pdf(a)  # Draw from the random variable pdf, taking values from a
        return [round(item * N, ndigits=0) for item in dist]  # Return a rounded list (the number of agents at each hour)
コード例 #23
0
ファイル: main.py プロジェクト: ysaikai/LFABM
class Trade(Model):
  verbose = False # Print-monitoring

  os.chdir(os.path.dirname(__file__))
  fpath = os.getcwd() + '/parameters.csv'
  reader = csv.reader(open(fpath, 'r'))
  d = dict()
  for key, value in reader:
    d[key] = float(value)

  height = int(d['height'])
  width = int(d['width'])
  ini_buyers = int(d['ini_buyers'])
  ini_sellers = int(d['ini_sellers'])

  def __init__(self, height=height, width=width, ini_buyers=ini_buyers, ini_sellers=ini_sellers):

    '''Parameters'''
    reader = csv.reader(open(self.fpath, 'r'))
    d = dict()
    for key, value in reader:
      d[key] = float(value)

    self.height = int(d['height'])
    self.width = int(d['width'])
    self.ini_buyers = int(d['ini_buyers'])
    self.ini_sellers = int(d['ini_sellers'])
    self.ini_cash = d['ini_cash']
    self.num_w = int(d['num_w'])
    self.trust_w = d['trust_w']
    self.costs = d['costs'] * ini_buyers
    self.mktresearch = d['mktresearch']
    self.priceRange = d['priceRange']
    self.csa = d['csa']
    self.csa_length = int(d['csa_length'])
    self.network = d['network']

    self.lb = d['lb'] # Lower bound
    self.ub = d['ub'] # Upper bound (in effect, unbounded)
    self.up = d['up'] # Up rate
    self.down = d['down'] # Down rate

    '''
    Entry mode
      0: No entry
      1: Full market research
      2: Whenever Avg cash balance > entryThreshhold with a random position
      3: Whenever Max cash balance > entryThreshhold enter nearby that position
    '''
    self.entry = int(d['entry'])
    self.entryFrequency = int(d['entryFrequency'])
    self.entryThreshhold = d['entryThreshhold'] * self.ini_cash
    self.entryRadius = int(d['entryRadius'])  # Area within high earner that a new seller will plop down

    '''Debugging'''
    self.sellerDebug = d['sellerDebug']
    self.buyerDebug = d['buyerDebug']
    self.networkDebug = d['networkDebug']
    self.utilweightDebug = d['utilweightDebug']
    self.entryDebug = d['entryDebug']

    self.schedule = RandomActivationByType(self)
    self.grid = MultiGrid(self.height, self.width, torus=True)
    self.datacollector = DataCollector(
      {"Sellers": lambda m: m.schedule.get_type_count(Seller),
      "Buyers": lambda m: m.schedule.get_type_count(Buyer)})

    '''Initialization'''
    self.cnt = 0 # Period counter
    self.buyers = {} # Dictionary of buyer instances
    self.sellers = {} # Dictionary of seller instances
    self.sid_alive = []
    self.pi = [0] * (height * width) # Profitability

    prices = {}
    for i in range(ini_sellers):
      prices[i] = self.priceRange * np.random.rand() + 1
    min_price = min(prices.values())
    for i in range(self.num_w):
      prices[i] = min_price * 0.9
    self.prices = prices

    e = {} # Embeddedness
    for i in range(ini_sellers):
      e[i] = 0.8*np.random.rand() + 0.2 # 0.2 - 1.0
    for i in range(self.num_w):
      e[i] = 0
    self.e = e

    '''Create buyers'''
    for i in range(self.ini_buyers):
      # It seems coincidence in the same cell is allowed
      x = np.random.randint(self.width)
      y = np.random.randint(self.height)

      α = d['alpha']
      trust = {}
      β = d['beta']*np.random.rand()
      for j in range(ini_sellers):
        trust[j] = np.random.rand()
      for j in range(self.num_w):
        trust[j] = self.trust_w
      γ = d['gamma']

      '''
      Network ties
        ties[j]=0 means 'no connection with bid=j buyer'
        ties[own bid] = 0 or 1 means nothing.
      '''
      ties = dict(zip(range(ini_buyers),[0]*ini_buyers))

      buyer = Buyer(i, self.grid, (x, y), True, α, trust, β, γ, ties)
      self.buyers[i] = buyer # Dictionary key is an integer
      self.grid.place_agent(buyer, (x, y))
      self.schedule.add(buyer)

    '''Create sellers'''
    for i in range(self.ini_sellers):
      x = np.random.randint(self.width)
      y = np.random.randint(self.height)

      cash = self.ini_cash
      costs = self.costs
      price = self.prices[i]
      w = False
      if i < self.num_w:
        w = True
      e = self.e[i]

      seller = Seller(i, self.grid, (x, y), True, cash, costs, price, w, e)
      self.sellers[i] = seller
      self.grid.place_agent(seller, (x, y))
      self.schedule.add(seller)

    self.running = True

  def step(self):
    '''Initialization'''
    self.cnt += 1
    self.sid_alive = [] # Excluding Wal-Mart

    for sid, seller in self.sellers.items():
      if seller.csa == False:
        '''Adjacent sales'''
        seller.sales = 0
        '''Customer list'''
        seller.customers[self.cnt] = []
      else:
        seller.customers[self.cnt] = seller.customers[self.cnt - 1]

      '''A list of living sellers (excluding Wal-Mart)'''
      if (seller.alive and seller.w == False):
        self.sid_alive.append(sid)
    # For entry
    if self.entry == 1:
      # Initialize the profitability vector
      self.pi = [0] * (self.height * self.width)
    elif self.entry == 2:
      # Calculate the average cash balance (scalar)
      total_cash = 0
      cnt_seller = 0
      total_cash = sum([self.sellers[sid].cash for sid in self.sid_alive])
      self.avg_cash = total_cash / len(self.sid_alive)
    elif self.entry == 3:
      # Calculate the max cash balance (scalar)
      temp_sids = self.sid_alive
      cash_bals = [self.sellers[sid].cash for sid in temp_sids]
      new_sellers = True

      # Loops over maximal sellers until it finds one with no new firms nearby
      while(new_sellers):
        max_cash = max(cash_bals)
        if(max_cash < self.entryThreshhold): break
        max_cash_ind = cash_bals.index(max_cash)
        max_sid = temp_sids[max_cash_ind]
        max_x = self.sellers[max_sid].pos[0]
        max_y = self.sellers[max_sid].pos[1]
        if(self.entryDebug):
          print("Max Cash, sid:", max_sid, ", Cell:(" + str(max_x) + ", " + str(max_y) + ")")
          print("-Neighbor Ages:", end=" ")

        new_sellers = False
        # Check the age of all firms nearby the max cash balance firm
        # (wants to avoid new firms)

        for neighbor in self.grid.get_neighbors((max_x, max_y),True,True,self.entryRadius):
          if(isinstance(neighbor, Seller) and self.entryDebug): print(str(neighbor.age), end=" ")
          if(isinstance(neighbor, Seller) and neighbor.age < 52): new_sellers = True
        if(new_sellers):
          if(self.entryDebug):
            print("\n-New Firm Exists Near sid: ", max_sid, ", Cell:(" + str(max_x) + ", " + str(max_y) + ")")
          del temp_sids[max_cash_ind]
          del cash_bals[max_cash_ind]

    '''
    Entry
      Entry=1
        Determine the most profitable position and whether to enter
        Threshold: the fixed costs
      Entry=2
        Enter whenever Avg cash balance > entryThreshhold
      Entry=3
        Checks that no new firms are near the max balance seller
        Enters within entryRadius units of the seller with max cash balance
    '''
    entry_on = False

    if (self.entry == 1 and self.mktresearch):
      opt = max(self.pi)
      opt_pos = self.pi.index(opt)

      if opt >= self.costs:
        x = opt_pos // self.width
        y = opt_pos % self.width
        entry_on = True

    elif (self.entry == 2 and self.avg_cash > self.entryThreshhold):
      x = np.random.randint(self.width)
      y = np.random.randint(self.height)
      entry_on = True

    elif (self.entry == 3 and max_cash > self.entryThreshhold and not new_sellers):
      x = max_x + np.random.randint(-self.entryRadius,self.entryRadius)
      y = max_y + np.random.randint(-self.entryRadius,self.entryRadius)
      x = x % self.width
      y = y % self.height
      entry_on = True

    if entry_on:
      cash = self.ini_cash
      costs = self.costs
      w = False
      price = np.mean([self.sellers[sid].price for sid in self.sid_alive])
      # e = np.random.choice([self.sellers[sid].e for sid in self.sid_alive])
      e = np.random.rand()
      sid = max([seller.sid for seller in self.sellers.values()]) + 1
      self.sid_alive.append(sid)
      seller = Seller(sid, self.grid, (x, y), True, cash, costs, price, w, e)
      self.sellers[sid] = seller
      self.sellers[sid].customers[self.cnt] = []
      for buyer in self.buyers.values():
        buyer.trust[sid] = self.lb
      self.grid.place_agent(seller, (x, y))
      self.schedule.add(seller)
      self.prices[sid] = price

      if (self.entry >= 1 and self.entryDebug):
        entry_NewFirm(sid, x, y)

      self.mktresearch = False

    '''Move'''
    self.schedule.step()
    self.datacollector.collect(self)
    if self.verbose:
      print([self.schedule.time,
        self.schedule.get_type_count(Seller),
        self.schedule.get_type_count(Buyer)])

    '''Network'''
    if self.network:
      network.formation(self.cnt, self.buyers, self.sellers)


  def run_model(self, step_count):
    for _ in range(step_count):
      self.step()
      '''
      Debugging
      '''
      '''Display trust levels'''
      if self.buyerDebug:
        debug.buyers(self.buyers)
      '''Network'''
      if self.networkDebug:
        debug.network(self.buyers)
      '''Display seller information'''
      if self.sellerDebug:
        debug.sellers(self.cnt, self.num_w, self.sellers, self.buyers)

    '''End of the run'''
    print("\n************\nPut a summary here.\n************")
コード例 #24
0
ファイル: model_TotC.py プロジェクト: RicardoKnauer/TotC
class TotC(Model):
    """
    Main model for the tragedy of the commons
    """
    def __init__(self,
                 initial_herdsmen=5,
                 initial_sheep_per_herdsmen=0,
                 initial_edges=5,
                 l_coop=0,
                 l_fairself=0,
                 l_fairother=0,
                 l_negrecip=0,
                 l_posrecip=0,
                 l_conf=0):
        super().__init__()
        self.width = GRID_SIZE
        self.height = GRID_SIZE

        self.grass = []
        self.herdsmen = []
        self.initial_herdsmen = initial_herdsmen
        self.initial_sheep_per_herdsmen = initial_sheep_per_herdsmen
        self.sheep_survival_rate = []

        self.l_coop = l_coop
        self.l_fairself = l_fairself
        self.l_fairother = l_fairother
        self.l_negrecip = l_negrecip
        self.l_posrecip = l_posrecip
        self.l_conf = l_conf

        self.G = nx.gnm_random_graph(initial_herdsmen, initial_edges)

        Sheep.sheepdeaths = 0
        Herdsman.i = 0
        Herdsman.x = np.zeros(initial_herdsmen, dtype=np.int8)

        self.schedule_Grass = RandomActivation(self)
        self.schedule_Herdsman = StagedActivation(
            self, stage_list=["advance", "step"], shuffle=True)
        self.schedule_Sheep = RandomActivation(self)
        self.schedule = RandomActivation(self)

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

        # "Grass" is the number of sheep that the grass can sustain
        self.datacollector = DataCollector({
            "Grass":
            lambda m: self.get_expected_grass_growth() / .5,
            "Sheep":
            lambda m: self.get_sheep_count(),
            "Sheep deaths":
            lambda m: Sheep.sheepdeaths
        })

        self.init_population()

        # required for the datacollector to work
        self.running = True
        self.datacollector.collect(self)

    def add_herdsman(self):
        """
        At a herdsman at a random position on the grid.
        """
        x = random.randrange(self.width)
        y = random.randrange(self.height)
        herdsman = self.new_agent(Herdsman, (x, y))
        self.herdsmen.append(herdsman)

    def init_grass(self):
        """
        Initialise a patch of grass at every square on the grid.
        """
        for agent, x, y in self.grid.coord_iter():
            self.grass.append(self.new_agent(Grass, (x, y)))

    def init_herdsman(self):
        """
        Spawn `initial_herdsmen' herdsmen on the field.
        """
        for i in range(getattr(self, "initial_herdsmen")):
            self.add_herdsman()

    def init_node_attr(self):
        """
        Assign the unique herdsman ID as attribute to graph nodes for the social
        network.
        """
        N = self.get_herdsman_count()
        for i in range(getattr(self, "initial_herdsmen")):
            for j in range(getattr(self, "initial_herdsmen")):
                if i is not j:
                    if nx.has_path(self.G, source=i, target=j) == True:
                        if nx.shortest_path_length(self.G, source=i,
                                                   target=j) == 1:
                            if sum(nx.common_neighbors(self.G, i, j)) > 5:
                                self.herdsmen[i].friendship_weights.append(1)
                            else:
                                self.herdsmen[i].friendship_weights.append(
                                    .75 + .05 *
                                    sum(nx.common_neighbors(self.G, i, j)))
                        elif nx.shortest_path_length(self.G,
                                                     source=i,
                                                     target=j) == 1:
                            if sum(nx.common_neighbors(self.G, i, j)) > 10:
                                self.herdsmen[i].friendship_weights.append(1)
                            else:
                                self.herdsmen[i].friendship_weights.append(
                                    .5 + .05 *
                                    sum(nx.common_neighbors(self.G, i, j)))
                        else:
                            self.herdsmen[i].friendship_weights.append(
                                1 / nx.shortest_path_length(
                                    self.G, source=i, target=j))
                    else:
                        self.herdsmen[i].friendship_weights.append(1 / N)

    def init_population(self):
        """
        Initialise grass, herdsmen, sheep, and the social network
        """
        self.init_grass()
        self.init_herdsman()
        self.init_node_attr()

    def get_expected_grass_growth(self):
        """
        Get an estimate of the expected grass growth for the next timestep. 
        If grass is fully grown it will return 0.0123 (the average grass growth
        over its lifetime.
        """
        return sum([
            grass.next_density() if grass.density < 0.99 else 0.0123
            for grass in self.grass
        ])

    def get_grass_count(self):
        """
        Get a sum of all grass densities.
        """
        return sum([grass.density for grass in self.grass])

    def get_herdsman_count(self):
        return self.schedule_Herdsman.get_agent_count()

    def get_sheep_count(self):
        return self.schedule_Sheep.get_agent_count()

    def new_agent(self, agent_type, pos):
        """
        Create new agent, and add it to the scheduler.
        """
        agent = agent_type(self.next_id(), self, pos)
        self.grid.place_agent(agent, pos)
        getattr(self, f"schedule_{agent_type.__name__}").add(agent)

        return agent

    def remove_agent(self, agent):
        """
        Remove agent from the grid and the scheduler.
        """
        self.grid.remove_agent(agent)
        getattr(self, f"schedule_{type(agent).__name__}").remove(agent)

    def run_model(self, step_count=200):
        """
        Runs the model for a specific amount of steps.
        """
        for i in range(step_count):
            self.step()

    def step(self):
        """
        Calls the step method for grass and sheep.
        """
        self.schedule_Grass.step()
        a = self.get_sheep_count()
        self.schedule_Sheep.step()
        b = self.get_sheep_count()
        c = b / a if a > 0 else 0
        self.sheep_survival_rate.append(c)
        self.schedule_Herdsman.step()
        self.schedule.step()

        # save statistics
        self.datacollector.collect(self)
コード例 #25
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.G =nx.empty_graph(0)
        lis = []
        for x in range(5):
            lis.append(range(random.randint(2,15)))
        correlative_num = 0
        central = 0
        for i,x in enumerate(lis):
            for y in lis[i]:
                if y > 0:
                    self.G.add_node(correlative_num)
                    self.G.add_edge(correlative_num, central)
                    correlative_num+=1
                else:
                    self.G.add_node(correlative_num)
                    correlative_num+=1
                    central = correlative_num 
        print("Impresion del grapho")
        print(self.G.nodes)
        print(self.G.edges)

        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()
コード例 #26
0
class DumbEcoModel(Model):
    #inicialização
    verbose = True
    economy = None
    initial_assets = None
    initial_liabilities = None
    initial_cash = None
    initial_inventory = None
    labor_market = None
    goods_market = None

    def __init__(self):

        self.num_firms = 3
        #    self.num_firms2 = n2
        self.num_households = 30
        self.running = True
        self.grid = MultiGrid(1, 5, True)
        self.result = 0
        #posso criar meu scheduler se for o caso
        self.schedule = RandomActivation(self)
        self.datacollector = DataCollector(
            model_reporters={
                "GoodsQt": goods_qt,
                "GoodsVl": goods_vl,
                "LaborQt": labor_qt,
                "LaborVl": labor_vl
            })

        #        )

        #        self.datacollector = DataCollector(
        #           model_reporters={"Labor": computeN1,"Goods": getResult}

        #       )
        self.initial_assets = dict()
        self.initial_liabilities = dict()
        self.initial_cash = 100.0
        self.initial_inventory = dict()

        self.economy = Economy("DumbEconomy", self)
        self.schedule.add(self.economy)
        self.grid.place_agent(self.economy, (0, 0))

        self.labor_market = Market("LaborMarket", self)
        self.schedule.add(self.labor_market)
        self.grid.place_agent(self.labor_market, (0, 1))

        self.goods_market = Market("GoodsMarket", self)
        self.schedule.add(self.goods_market)
        self.grid.place_agent(self.goods_market, (0, 2))

        #### Define goods and services of the economy

        self.initial_assets = dict()
        self.initial_liabilities = dict()

        self.initial_inventory = dict()

        # initialize households
        for i in range(self.num_households):
            self.initial_cash = 10.0
            # Intialize Household assets
            quantity_of_labor = 1000.0
            price_of_labor = .5
            value_of_labor = quantity_of_labor * price_of_labor
            quantity_of_food = 0.0
            price_of_food = .1
            value_of_food = quantity_of_food * price_of_food
            available_labor = GoodOrService("labor", 1, quantity_of_labor,
                                            price_of_labor, value_of_labor)
            food = GoodOrService("corn", 1, quantity_of_food, price_of_food,
                                 value_of_food)
            self.initial_assets = {
                available_labor.name_of_gs: available_labor,
                food.name_of_gs: food
            }

            # Intialize Household liabilities
            quantity_of_food_demmand = random() * 130.0
            price_of_food_demmand = 0.1
            value_of_food_demmand = quantity_of_food_demmand * price_of_food_demmand
            food_demmand = GoodOrService("food_demmand", 1,
                                         quantity_of_food_demmand,
                                         price_of_food_demmand,
                                         value_of_food_demmand)
            self.initial_liabilities = {food_demmand.name_of_gs: food_demmand}

            # Initialize Household inventory
            self.initial_inventory_hh = {
                food.name_of_gs: food,
                available_labor.name_of_gs: available_labor
            }

            fm = DumbHousehold(i, self, self.economy, self.initial_assets,
                               self.initial_liabilities, self.initial_cash,
                               self.initial_inventory_hh)
            self.schedule.add(fm)
            self.grid.place_agent(fm, (0, 3))
            fm.enter_labor_market(self.labor_market)
            fm.enter_goods_market(self.goods_market)

        # initialize firms
        for i in range(self.num_firms):
            # initialize firm assets
            self.initial_cash = 1000.0
            quantity_of_food = 10.0
            price_of_food = .1
            value_of_food = quantity_of_food * price_of_food
            produced_food = GoodOrService("corn", 1, quantity_of_food,
                                          price_of_food, value_of_food)
            self.initial_assets = {produced_food.name_of_gs: produced_food}
            # initialize firm liabilities
            quantity_of_labor = 0.0
            price_of_labor = 0.5
            value_of_labor = quantity_of_labor * price_of_labor
            demmanded_labor = GoodOrService("labor", 1, quantity_of_labor,
                                            price_of_labor, value_of_labor)
            self.initial_liabilities = {
                demmanded_labor.name_of_gs: demmanded_labor
            }
            # initialize firm inventory
            self.initial_inventory_firm = {
                produced_food.name_of_gs: produced_food
            }

            f1 = DumbFirm(i, self, self.economy, self.initial_assets,
                          self.initial_liabilities, self.initial_cash,
                          self.initial_inventory_firm)
            self.schedule.add(f1)
            self.grid.place_agent(f1, (0, 4))
            f1.enter_labor_market(self.labor_market)
            f1.enter_goods_market(self.goods_market)

    def step(self):
        print([self.schedule.time, " my_step"])
        self.schedule.step()
        # restart market variables
        self.datacollector.collect(self)
        print([
            "Labor Market:", self.labor_market.unique_id, "Quantity: ",
            self.labor_market.total_sells_qt, "  Value: ",
            self.labor_market.total_sells_vl
        ])
        print([
            "Goods Market:", self.goods_market.unique_id, "Quantity: ",
            self.goods_market.total_sells_qt, "  Value: ",
            self.goods_market.total_sells_vl
        ])

        self.goods_market.total_sells_qt = 0.0
        self.labor_market.total_sells_qt = 0.0
        self.goods_market.total_sells_vl = 0.0
        self.labor_market.total_sells_vl = 0.0

        print([self.schedule.time, "passei"])

    def run_model(self, n):
        for i in range(n):
            self.step()
コード例 #27
0
class Population(Model):
    """Population
    Adapted from https://www.medrxiv.org/content/10.1101/2020.03.18.20037994v1.full.pdf

    Model Parameters:
    spread_chance: probability of infection based on contact
    gamma: mean incubation period
    alpha: probability of become asymptomatic vs symptomatic
    gamma_AR: infectious period for asymptomatic people
    gamma_YR: infectious period for symptomatic people
    delta: death rate due to disease

    The social distancing func takes time passed -> new interaction multiplier
    """
    def __init__(self,
                 graph,
                 model_parameters,
                 social_distancing_func=lambda x: 1):

        # Model initialization
        self.population_size = model_parameters['population size']
        self.initial_outbreak_size = model_parameters['initial outbreak size']
        self.graph = graph
        self.grid = NetworkGrid(self.graph)
        self.schedule = SimultaneousActivation(self)
        self.social_distancing_func = social_distancing_func

        self.datacollector = DataCollector({  # "Exposed": count_exposed,
            "Susceptible": count_susceptible,
            "Recovered": count_recovered,
            # "Asymptomatic": count_asymptomatic,
            # "Symptomatic": count_symptomatic,
            "Diseased": count_diseased,
            "Removed": count_removed
        })
        self.model_parameters = model_parameters

        for i, node in enumerate(self.graph.nodes()):
            a = Person(i, self, State.SUSCEPTIBLE, model_parameters,
                       social_distancing_func)
            self.schedule.add(a)
            self.grid.place_agent(a, i)
            if i % 100 == 0:
                logger.info("Finished with agent " + str(i))

        infected_nodes = self.random.sample(self.graph.nodes(),
                                            self.initial_outbreak_size)
        for a in self.grid.get_cell_list_contents(infected_nodes):
            a.status = State.EXPOSED

        self.datacollector.collect(self)
        print("Model initialized...\n")

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

    def run(self, n):
        for i in range(n):
            logger.info("Steps Completed: " + str(i))
            self.step()

    def run_until_stable(self):
        max_steps = 1e3
        steps = 0
        window_size = 50
        while steps < max_steps:
            self.step()
            logger.info("Steps Completed:" + str(steps))
            if steps > window_size:
                data = self.get_data()
                last_value = int(data.tail(1)['Diseased'])
                if last_value == 0:
                    break
                window_average = np.mean(
                    data.tail(window_size)
                    ['Diseased'])  # Window for determining stopping rule
                if abs(last_value - window_average) / window_average < 0.005:
                    break
            steps += 1

    def cross_influence(self, influence_coefficients, ratios):
        for inf_coeff, ratio in zip(influence_coefficients, ratios):
            susceptibles = list(
                filter(lambda x: x.status == State.SUSCEPTIBLE,
                       self.grid.get_all_cell_contents()))
            to_flip = self.random.sample(
                susceptibles, int(inf_coeff * ratio * len(susceptibles)))
            for agent in to_flip:
                agent.status = State.EXPOSED

    def clear_social_distancing_func(self):
        """
        Clears the social distancing function of the model and all its agents for pickling
        :return: None
        """
        self.social_distancing_func = None
        for agent in self.grid.get_all_cell_contents():
            agent.social_distancing_func = None

    def reinstate_social_distancing_func(self,
                                         social_distancing_func=lambda x: 1):
        """
        Re-adds the social distancing func to the model and all its agents
        :param social_distancing_func: social distancing func to be re-added
        :return: None
        """
        self.social_distancing_func = social_distancing_func
        for agent in self.grid.get_all_cell_contents():
            agent.social_distancing_func = social_distancing_func

    def save_model(self, filename):
        """
        Save the model to a pickle and dill file
        :param filename: filename (without extension) to save to
        :return: None
        """
        with open(filename + ".dil", 'wb') as f:
            dill.dump(self.social_distancing_func, f)
        self.clear_social_distancing_func()
        with open(filename + ".pkl", 'wb') as f:
            pickle.dump(self, f)

    def get_data(self):
        return self.datacollector.get_model_vars_dataframe()

    '''
コード例 #28
0
class SIRModel(Model):
    '''Description of the model'''
    
    def __init__(self, width, height, infectivity=2.0, infection_duration = 10, immunity_duration = 15, mutation_probability=0, mutation_strength=10, visualise_each_x_timesteps=-1):
        # Set the model parameters
        self.infectivity = infectivity       # Infection strength per infected individual
        self.infection_duration = infection_duration # Duration of infection
        self.immunity_duration = immunity_duration  # Duration of infection
        
        #mutations
        self.mutation_probability = mutation_probability 
        self.mutation_strength = mutation_strength
        #self.mean_inf_duration_list = []

        percentage_starting_infected = 0.01
        percentage_starting_recovered = 0.01
       
        self.visualise_each_x_timesteps = visualise_each_x_timesteps
        self.grid = SingleGrid(width, height, torus=False)
        self.schedule = SimultaneousActivation(self)
        for (contents, x, y) in self.grid.coord_iter():
            # Place randomly generated individuals
            rand = random.random()
            cell = Cell((x,y), self)

            # place random infected cells with a chance
            if rand < percentage_starting_infected:
                cell.initialise_as_infected()

            # place random infected cells with a chance
            elif rand < percentage_starting_infected + percentage_starting_recovered:
                cell.initialise_as_recovered()

            self.grid.place_agent(cell, (x,y))
            self.schedule.add(cell)

        # Add data collector, to plot the number of individuals of different types
        self.datacollector_cells = DataCollector(model_reporters={
            "Infected": fracI,
            "Susceptible": fracS,
            "Recovered": fracR,
        })

        # Add data collector, to plot the mean infection duration
        self.datacollector_meaninfectionduration = DataCollector(model_reporters={"Mean_inf_duration": compute_mean_infduration})

        # collects grids per amount of time steps
        self.grids_saved = []
        
        self.running = True

    def get_grid_cells(self):
        return np.array([cell.state for cell in self.schedule.agents])

    def step(self):
        # collect grids for running without browser
        if self.visualise_each_x_timesteps != -1:
            if self.schedule.time % self.visualise_each_x_timesteps == 0:
                print(f'timestep: {self.schedule.time}, saved grid.')
                self.grids_saved.append(self.get_grid_cells())

        self.datacollector_cells.collect(self)
        self.datacollector_meaninfectionduration.collect(self)

        self.schedule.step()
コード例 #29
0
class ShoalModel(Model):
    """
    Shoal model class. Handles agent creation, placement and scheduling.
    Parameters are interactive, using the user-settable parameters defined
    above.

    Parameters:
        n_fish: Initial number of "Fish" agents.
        width, height: Size of the space.
        speed: how fast the boids should 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.
    """
    def __init__(self,
                 n_fish=100,
                 width=50,
                 height=50,
                 speed=10,
                 vision=10,
                 separation=2,
                 cohere=0.25,
                 separate=0.025,
                 match=0.3):
        assert speed < width and speed < height, "speed can't be greater than model area dimensions"
        self.n_fish = n_fish
        self.vision = vision
        self.speed = speed
        self.separation = separation
        self.schedule = RandomActivation(self)
        self.space = ContinuousSpace(width, height, torus=True)
        self.factors = dict(cohere=cohere, separate=separate, match=match)
        # self.make_obstructions()  # Todo: un-comment this line to include obstructions
        self.make_fish()
        self.running = True

    def make_fish(self):
        """
        Create N "Fish" agents. A random position and starting velocity is
        assigned for each fish.

        Call data collectors for position and heading of each fish at each data step.
        """
        for i in range(self.n_fish):
            x = random.randrange(2, (self.space.x_max - 2))
            y = random.randrange(2, (self.space.y_max - 2))
            pos = np.array((x, y))
            velocity = np.random.random(
                2) * 2 - 1  # [-1.0 .. 1.0, -1.0 .. 1.0]
            fish = Fish(i, self, pos, self.speed, velocity, self.vision,
                        self.separation, **self.factors)
            self.space.place_agent(fish, pos)
            self.schedule.add(fish)

        self.datacollector = DataCollector(
            # model_reporters={"test": test})
            model_reporters={
                "positions": positions,
                "heading": heading
            })

    def make_obstructions(self):
        """
        Create N "Obstruct" agents, with set positions & no movement. Borders
        are defined as coordinate points between the maximum and minimum extent
        of the width/height of the obstruction. These ranges are drawn from the
        model space limits, with a slight buffer.

        In this case, the obstructions form a line to represent an environmental
        variable such as a thermo- or halocline.
        """
        max_lim = self.space.x_max - 1
        min_lim = self.space.x_min + 1
        line = range(min_lim, max_lim)
        borders = np.asarray([(n, 25) for n in line])
        x_points = np.ndarray.tolist(borders[:, 0])
        y_points = np.ndarray.tolist(borders[:, 1])
        points = list(zip(x_points, y_points))

        for i in points:  # create obstruction agent for all points along the borders
            pos = np.array(i)
            obstruct = Obstruct(i, self, pos)
            self.space.place_agent(obstruct, pos)
            self.schedule.add(obstruct)

    def step(self):
        self.datacollector.collect(self)
        self.schedule.step()
コード例 #30
0
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 = b
        self.a = a
        self.agents = []
        self.fit_alpha = 0
        self.fit_loc = 0
        self.fit_beta = 0
        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={
            'beta': 'b',
            'a': 'a',
            '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()
コード例 #31
0
class LocustModel(Model):
    """A model with some number of agents."""
    def __init__(self, N, width, height, delta_t, R_plus, v, Lambda, alpha,
                 eta, gamma, beta, theta, delta):
        self.num_agents = N
        self.width = width
        self.height = height
        self.grid = MultiGrid(width, height, True)
        self.schedule = SimultaneousActivation(self)
        self.delta_t = 1
        self.R_plus = 200.0
        self.resources = [self.R_plus] * width
        self.v = .04
        self.Lambda = .00001
        self.a = alpha
        self.b = eta
        self.r_fm = gamma
        self.c = beta
        self.d = theta
        self.r_mf = delta
        self.delta_x = v * delta_t

        # print("Resources" + str(self.resources))
        # Create agents
        for i in range(self.num_agents):
            a = LocustAgent(i, self)
            self.schedule.add(a)
            #print ("Hi, Iss am agent " + str(a.unique_id) +" at grid : (" + str(0) + "," + str(a.unique_id) +')')
            # Add the agent to a random grid cell
            self.grid.place_agent(a, (0, (a.unique_id % self.height)))

        self.datacollector = DataCollector(
            model_reporters={"Resources": compute_gini})

    def get_locust_At(self, index):
        size = 0
        for i in range(self.height):
            for agent in self.grid.get_cell_list_contents([(index, i)]):
                if (agent.isFeeding == 0):
                    size += 1
        #print("think this is the size:" + str(size))
        return size

    def get_width(self):
        return self.width

    def get_height(self):
        return self.height

    #Probability function of going from isFeeding -> ~isFeeding
    def Kmf(self, r):
        y = self.b - (self.b - self.a) * np.exp(-self.r_fm * r)
        return y

    #Probability function of going from ~isFeeding -> isFeeding
    def Kfm(self, r):
        y = (self.d - (self.d - self.c) * np.exp(-self.r_mf * r))
        return y

    # Exp function of S to reduce R by. R(t+1) = R*R_exp(S)
    def updateResources(self, S):
        y = np.exp(-self.Lambda * S * self.delta_t / self.delta_x)
        return y

    def step(self):
        self.datacollector.collect(self)
        '''Advance the model by one step.'''
        self.schedule.step()
        ##Update Resource
        for i in range(self.width):
            locustcount = 0
            locustcount = int(self.get_locust_At(i))

            self.resources[i] *= self.updateResources(locustcount)
        resource_history.append(self.resources)
        # print("Resources" + str(self.resources))

    def get_resource(self, index):
        return self.resources[index]
コード例 #32
0
class SugarscapeModel(Model):
    def __init__(self, height=50, width=50, init_agents=500, max_metabolism=3, max_vision=10, max_init_sugar=5, min_age=30, max_age=60, init_poll=3, ex_ratio=2, ex_mod=1, poll_growth_rule=True, inheritance_rule=True):
        self.height = height
        self.width = width
        self.init_agents = init_agents
        self.init_poll = init_poll
        self.max_metabolism = max_metabolism
        self.max_vision = max_vision
        self.max_init_sugar = max_init_sugar
        self.min_age = min_age
        self.max_age = max_age
        self.ex_ratio = ex_ratio
        self.ex_mod = ex_mod

        self.replacement_rule = True
        self.pollution_rule = False
        self.diffusion_rule = False
        self.push_rule = False
        self.poll_growth_rule = poll_growth_rule
        self.expend_rule = True
        self.inheritance_rule = inheritance_rule

        self.map = self.import_map()
        self.grid = MultiGrid(height, width, torus=True)
        self.schedule = RandomActivationByType(self)
        self.datacollector = DataCollector({'Pollution': (lambda m: m.total_pollution),
                                            'Wealth': (lambda m: m.total_wealth/m.init_agents),
                                            'Agents': (lambda m: len(m.schedule.agents_by_type[ScapeAgent]))},
                                           {'Wealth': self.collect_wealth,
                                            'Metabolism': self.collect_metabolism,
                                            'Vision': self.collect_vision})

        self.total_wealth = 0
        self.total_pollution = 0

        self.populate_sugar()
        self.populate_agents()


    def step(self):
        ''' Step method run by the visualization module'''
        self.schedule.step([ScapeAgent, SugarPatch])
        self.datacollector.collect(self)

        # if self.schedule.time == 20:
        #     self.pollution_rule = True
        if self.schedule.time == 30:
            self.push_rule = True

        self.total_wealth = 0
        self.total_pollution = 0
        for agent in self.schedule.agents_by_type[ScapeAgent]:
            self.total_wealth += agent.wealth
        for patch in self.schedule.agents_by_type[SugarPatch]:
            self.total_pollution += patch.pollution

    def import_map(self):
        ''' Imports a text file into an array to be used when generating and
            placing the sugar Agents into the grid
        '''

        f = open('Maps/sugar_map.txt', 'r')
        map_list = []
        for line in f:
            num_list = line.split(' ')
            for num in num_list:
                map_list.append(int(num[0]))

        return map_list

    def new_agent(self, uid, inheritance):
        ''' Place a new agent on the sugarscape in order to replace a death'''
        free = False
        while not free:
            location = random.choice([cell for cell in self.grid.coord_iter()])
            if len(location[0]) == 1:
                free = True

        pos = (location[1], location[2])
        patch = self.grid.get_cell_list_contents([pos])[0]

        if self.inheritance_rule:
            if inheritance == 'rand':
                wealth = random.randint(1, self.max_init_sugar)
            else:
                wealth = inheritance
        else:
            wealth = random.randint(1, self.max_init_sugar)

        agent = ScapeAgent(uid, pos, wealth, random.randint(1,self.max_metabolism), random.randint(1,self.max_vision), random.randint(self.min_age, self.max_age), patch, self.ex_ratio, self.ex_mod)

        self.grid.place_agent(agent, agent.pos)
        self.schedule.add(agent)

    def populate_agents(self):
        ''' Place ScapeAgent's in random unoccupied locations on the grid with randomomized
            sets of parameters
        '''

        cells = [(cell[1], cell[2]) for cell in self.grid.coord_iter()]
        for i in range(self.init_agents):
            uid = 'a' + str(i)
            location = random.choice(cells)
            cells.remove(location)
            patch = self.grid.get_cell_list_contents([location])[0]
            agent = ScapeAgent(uid, location, random.randint(1,self.max_init_sugar), random.randint(1,self.max_metabolism), random.randint(1,self.max_vision), random.randint(self.min_age, self.max_age), patch, self.ex_ratio, self.ex_mod)
            self.grid.place_agent(agent, location)
            self.schedule.add(agent)

    def populate_sugar(self):
        ''' Place SugarPatch's on every cell with maximum sugar content
            according to the imported 'sugar_map.txt' file
        '''

        map_i = 0
        for cell in self.grid.coord_iter():
            x = cell[1]
            y = cell[2]
            uid = 's'+str(y)+str(x)
            # patch = SugarPatch(uid, (x,y), 3)
            patch = SugarPatch(uid, (x,y), self.map[map_i], self.init_poll)
            self.grid.place_agent(patch, (x,y))
            self.schedule.add(patch)
            map_i += 1

    def collect_wealth(self, agent):
        '''Method for datacollector'''
        if isinstance(agent, ScapeAgent):
            return agent.wealth

    def collect_metabolism(self, agent):
        '''Method for datacollector'''
        if isinstance(agent, ScapeAgent):
            return agent.metabolism

    def collect_vision(self, agent):
        '''Method for datacollector'''
        if isinstance(agent, ScapeAgent):
            return agent.vision

    def calc_gini(self, wealths):
        '''Returns gini coefficient'''
        sort_wealths = sorted(wealths)
        num_agents = len(sort_wealths)
        gini,count = 0,0
        for wealth in sort_wealths:
            gini += wealth * (num_agents - count)
            count += 1
        gini /=  (num_agents*sum(sort_wealths))
        return num_agents**(-1) - 2*gini + 1
コード例 #33
0
ファイル: model.py プロジェクト: ntexplorer/CMT400
class CovidModel(Model):
    """
    initialize the model with N agents, of which M agents are infected initially
    Parameter J and K for numbers of agents who wears face masks;
    add all the agents in the agent_list for function position_agent
    """
    def __init__(self, N: int, M: int, J: int, K: int, L: int, width, height,
                 hospital_activated: bool, auto_self_isolation: bool,
                 manual_self_isolation_lvl: int):
        super().__init__()
        self.agent_number = N
        self.initial_infected = M
        self.healthy_with_mask = J
        self.carrier_with_mask = K
        self.hospital_capacity = L
        self.hospital_occupation = 0
        self.hospital_activated = hospital_activated
        self.auto_self_isolation = auto_self_isolation
        self.manual_self_isolation_lvl = manual_self_isolation_lvl
        self.grid = SingleGrid(width, height, True)
        self.schedule = RandomActivation(self)
        self.schedule_end_steps = 0
        self.schedule_end_flag = False
        self.highest_morbidity_rate = 0
        self.running = True
        self.agent_list = []
        self.symptomatic_list = []
        self.symptomatic_rate = 0
        self.quarantine_toggle = 0
        self.quarantine_list = []
        self.quarantined_agent_length_1 = 0
        self.quarantined_agent_length_2 = 0

        for i in range(self.carrier_with_mask):
            infected_with_mask = CovidAgent(i, self, True, True)
            self.schedule.add(infected_with_mask)
            self.agent_list.append(infected_with_mask)

        for i in range(self.carrier_with_mask, self.initial_infected):
            infected_without_mask = CovidAgent(i, self, True, False)
            self.schedule.add(infected_without_mask)
            self.agent_list.append(infected_without_mask)

        for i in range(self.initial_infected,
                       (self.agent_number - self.healthy_with_mask)):
            healthy_without_mask = CovidAgent(i, self, False, False)
            self.schedule.add(healthy_without_mask)
            self.agent_list.append(healthy_without_mask)

        for i in range((self.agent_number - self.healthy_with_mask),
                       self.agent_number):
            healthy_with_mask = CovidAgent(i, self, False, True)
            self.schedule.add(healthy_with_mask)
            self.agent_list.append(healthy_with_mask)

        for agent in self.agent_list:
            # for SingleGrid use position_agent to place them the first time
            self.grid.position_agent(agent)

        self.data_collector = DataCollector(
            model_reporters={
                "Fatalities": compute_fatalities,
                "Immune": compute_immune,
                "Healthy": compute_healthy_agent,
                "Infected": compute_infection,
                "Hospital Occupation": compute_hospital_treated,
                "Fatality Rate": compute_fatality_rate,
                "Morbidity Rate": compute_morbidity_rate
            })

    def step(self):
        self.data_collector.collect(self)
        self.schedule.step()
        self.get_end_time()
        self.get_highest_morbidity_rate()

    # A function to check if all agents are not infected
    def check_all_agents(self):
        for agent in self.agent_list:
            if agent.is_infected:
                return False
        return True

    def get_end_time(self):
        # if all the agents get rid of infection and the model has not register the steps
        if self.check_all_agents() and not self.schedule_end_flag:
            self.schedule_end_steps = self.schedule.steps
            # set the flag to true to only record the steps once
            self.schedule_end_flag = True

    def auto_quarantine_get_symptomatic_rate(self):
        # if the agent has symptom, append it to the list
        self.symptomatic_list = []
        for agent in self.agent_list:
            if agent.has_symptom:
                self.symptomatic_list.append(agent)
        # then calculate the symptomatic_rate
        self.symptomatic_rate = len(self.symptomatic_list) / len(
            self.agent_list)

    def auto_quarantine_update_quarantine_list(self):
        # get number of agents who need to be self-isolated for both quarantine level
        self.quarantined_agent_length_1 = round(
            len(self.agent_list) * float(quarantine_rate["1"]))
        self.quarantined_agent_length_2 = round(
            len(self.agent_list) * float(quarantine_rate["2"]))
        # level 1
        if float(quarantine_threshold['level_1_threshold']
                 ) <= self.symptomatic_rate < float(
                     quarantine_threshold['level_2_threshold']
                 ) and self.quarantine_toggle != 1:
            self.auto_quarantine_reset_quarantine_list()
            # pick random agents (number set by lvl 1) to stay still
            self.quarantine_list = self.random.sample(
                self.agent_list, self.quarantined_agent_length_1)
            # set the toggle to 1
            self.quarantine_toggle = 1
        # level 2
        elif float(quarantine_threshold['level_2_threshold']
                   ) <= self.symptomatic_rate and self.quarantine_toggle != 2:
            self.auto_quarantine_reset_quarantine_list()
            # pick random agents (number set by lvl 2) to stay still
            self.quarantine_list = self.random.sample(
                self.agent_list, self.quarantined_agent_length_2)
            # set the toggle to 2
            self.quarantine_toggle = 2
        elif float(quarantine_threshold['level_1_threshold']
                   ) > self.symptomatic_rate and self.quarantine_toggle != 0:
            self.auto_quarantine_reset_quarantine_list()
            # at lvl 0 no one needs to self-isolate
            self.quarantine_list = []
            self.quarantine_toggle = 0
        # all the agents in the list to stay still
        for agent in self.quarantine_list:
            agent.self_isolation_toggle = True

    def auto_quarantine_reset_quarantine_list(self):
        for agent in self.agent_list:
            agent.self_isolation_toggle = False

    def manual_quarantine(self):
        if not self.quarantine_toggle:
            self.quarantine_toggle = 1
            quarantined_agent_length = round(
                len(self.agent_list) *
                float(quarantine_rate[str(self.manual_self_isolation_lvl)]))
            self.quarantine_list = self.random.sample(
                self.agent_list, quarantined_agent_length)
            for agent in self.quarantine_list:
                agent.self_isolation_toggle = True

    def get_highest_morbidity_rate(self):
        morbidity_list = []
        for agent in self.agent_list:
            if agent.is_infected:
                morbidity_list.append(agent)
        H = len(morbidity_list)
        morbidity_rate = H / self.agent_number
        if morbidity_rate > self.highest_morbidity_rate:
            self.highest_morbidity_rate = morbidity_rate
コード例 #34
0
ファイル: model.py プロジェクト: johnx25bd/ucl-dissertation
class CentralizedArchitecture(Model):
    """
    Simulating traditional cloud server web architectures including
    client-server relationship
    """

    def __init__(self, num_clouds, gateways_per_cloud,
                sensors_per_gateway, height=100, width=100):
        """
        Create a new model with centralized database architectures.

        """
        super().__init__()

        self.height = height
        self.width = width

        self.schedule = RandomActivationByBreed(self)
        self.grid = Grid(height, width, torus=False)

        self.datacollector = DataCollector(
            {"Temperature": lambda m: self.retrieve_state_updates(m)
            })

        # self.agents_by_breed = defaultdict(dict)

        for cloud in range(0, num_clouds):

            current_cloud_id = self.next_id()
            new_cloud = Cloud(current_cloud_id, self)
            # self.grid._place_agent() # where do the cloud symbols go?
            self.schedule.add(new_cloud)

            for gateway in range(0, gateways_per_cloud):

                current_gateway_id = self.next_id()
                new_gateway = Gateway(current_gateway_id, None, 0, current_cloud_id, self)

                # self.grid._place_agent((0, gateway ), new_gateway)
                self.schedule.add(new_gateway)

                for sensor in range(0, sensors_per_gateway):

                    current_sensor_id = self.next_id()
                    pos = (random.randint(0,width -1), random.randint(0,height -1))

                    new_sensor = Sensor( current_sensor_id, pos, 10, current_gateway_id, self)

                    # self.grid._place_agent(pos, new_sensor)
                    self.schedule.add(new_sensor)




    def step(self):
        print("STEP:", self.schedule.steps)
        self.schedule.step()
        self.datacollector.collect(self)

        # if self.duration <

    @staticmethod
    def retrieve_state_updates(model):
        state_updates = {}
        # # print(model.schedule.agents)
        # for breed in model.schedule.agents_by_breed:
        #     print(breed)
        #     state_updates[breed] = {}
        #     for agent in model.schedule.agents_by_breed[breed]:
        #         state_updates[breed][agent] = model.schedule.agents_by_breed[breed][agent].state_updates
        #     # recordings[sensor.pos] = sensor.recordings

        return state_updates
コード例 #35
0
class InfectionModel(Model):
    """A model for infection spread."""
    def __init__(self,
                 human_count,
                 random_spawn,
                 save_plots,
                 floor_plan_file="floorplan_1.txt",
                 N=10,
                 width=10,
                 height=10,
                 ptrans=0.5,
                 progression_period=3,
                 progression_sd=2,
                 death_rate=0.0193,
                 recovery_days=21,
                 recovery_sd=7):
        # Load floorplan
        # floorplan = np.genfromtxt(path.join("infection_spread/floorplans/",
        #                                     floor_plan_file))
        with open(
                os.path.join("infection_spread/floorplans/", floor_plan_file),
                "rt",
        ) as f:
            floorplan = np.matrix(
                [line.strip().split() for line in f.readlines()])

        # Rotate the floorplan so it's interpreted as seen in the text file
        floorplan = np.rot90(floorplan, 3)

        # Check what dimension our floorplan is
        width, height = np.shape(floorplan)

        # Init params
        self.num_agents = N
        self.initial_outbreak_size = 1
        self.recovery_days = recovery_days
        self.recovery_sd = recovery_sd
        self.ptrans = ptrans
        self.death_rate = death_rate
        self.running = True
        self.dead_agents = []
        self.width = width
        self.height = height
        self.human_count = human_count

        # Set up model objects
        self.schedule = RandomActivation(self)
        self.grid = MultiGrid(height, width, torus=False)

        # Used to easily see if a location is an Exit or Door,
        #   since this needs to be done a lot
        self.exit_list = []
        self.door_list = []
        # If random spawn is false, spawn_list will contain the list of
        #   possible spawn points according to the floorplan
        self.random_spawn = random_spawn
        self.spawn_list = []

        # Load floorplan objects
        for (x, y), value in np.ndenumerate(floorplan):
            value = str(value)
            floor_object = None

            if value == "W":
                floor_object = Wall((x, y), self)

            elif value == "E":
                floor_object = Exit((x, y), self)
                self.exit_list.append((x, y))
                self.door_list.append((x, y))  # Add exits to doors as well

            elif value == "D":
                floor_object = Door((x, y), self)
                self.door_list.append((x, y))

            elif value == "S":
                self.spawn_list.append((x, y))

            if floor_object:
                self.grid.place_agent(floor_object, (x, y))
                self.schedule.add(floor_object)

        # Create a graph of traversable routes, used by agents for pathing
        self.graph = nx.Graph()
        for agents, x, y in self.grid.coord_iter():
            pos = (x, y)

            # If the location is empty, or a door
            if not agents or any(isinstance(agent, Door) for agent in agents):
                neighbors = self.grid.get_neighborhood(pos,
                                                       moore=True,
                                                       include_center=True,
                                                       radius=1)

                for neighbor in neighbors:
                    # If there is contents at this location and they are
                    #   not Doors or FireExits, skip them
                    if not self.grid.is_cell_empty(neighbor) \
                            and neighbor not in self.door_list:
                        continue

                    self.graph.add_edge(pos, neighbor)
        """
         # Start placing human agents
               # for i in range(0, self.human_count):
                #    if self.random_spawn:  # Place human agents randomly
                 #       pos = self.grid.find_empty()
                  #  else:  # Place human agents at specified spawn locations
                   #     pos = random.choice(self.spawn_list)

                    #if pos:
                        # Create a random human
                     #   health = random.randint(self.MIN_HEALTH * 100,
                                                 self.MAX_HEALTH * 100
                                                 ) / 100
                      #  speed = random.randint(self.MIN_SPEED, self.MAX_SPEED)
        """

        for i in range(self.num_agents):
            a = Human(unique_id=i, model=self)
            self.schedule.add(a)
            # Add the agent to a random grid cell
            x = self.random.randrange(self.grid.width)
            y = self.random.randrange(self.grid.height)
            self.grid.place_agent(a, (x, y))
            # make some agents infected at start
            infected = np.random.choice([0, 1], p=[0.98, 0.02])
            if infected == 1:
                a.state = State.INFECTED
                a.recovery_time = self.get_recovery_time()

        self.datacollector = DataCollector(
            # model_reporters={"Gini": compute_gini},
            agent_reporters={"State": "state"})

    def get_recovery_time(self):
        return int(
            self.random.normalvariate(self.recovery_days, self.recovery_sd))

    def step(self):
        """
        Advance the model by one step.
        """
        self.schedule.step()
        self.datacollector.collect(self)
コード例 #36
0
ファイル: model.py プロジェクト: BROSE-Uninc/SSF2021
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()
コード例 #37
0
ファイル: model.py プロジェクト: edwisdom/regime_model
class RegimeModel(Model):
    # A model of a regime

    def __init__(self, num_nodes, productivity, demand, shape, network_param,
                 resource_inequality, capacity_inequality, uncertainty, shock):

        # Initialize graph
        self.num_nodes = num_nodes
        self.G = create_graph(shape, num_nodes, network_param)
        self.G = max(nx.connected_component_subgraphs(self.G),
                     key=lambda g: len(g.nodes()))

        # Initialize other attributes
        self.grid = NetworkGrid(self.G)
        self.schedule = StagedActivation(self,
                                         stage_list=[
                                             'add_link', 'cut_link',
                                             'settle_env_transfer',
                                             'settle_link_transfer'
                                         ],
                                         shuffle=True,
                                         shuffle_between_stages=True)
        self.productivity = productivity
        self.demand = demand
        self.resource_inequality = resource_inequality
        self.capacity_inequality = capacity_inequality
        self.uncertainty = uncertainty
        self.datacollector = DataCollector({
            "Gini Coeff. of Capacity": gini_capacity,
            "Gini Coeff. of Resources": gini_resources,
            "Satisfied": num_satisfied,
            "Dissatisfied": num_dissatisfied
        })
        self.shock = shock

        # Initialize agents on graph (cap capacity at 25 to avoid overflow errors)
        for i, node in enumerate(self.G.nodes()):
            a = RegimeAgent(i, self, self.demand,
                            math.exp(paretovariate(1 / resource_inequality)),
                            min(25, paretovariate(1 / capacity_inequality)),
                            True)
            self.schedule.add(a)
            self.grid.place_agent(a, node)

        for e in self.G.edges():
            capacity_transfer = expovariate(1 / self.uncertainty)
            agents = ([
                self.G.nodes[e[0]]['agent'][0], self.G.nodes[e[1]]['agent'][0]
            ])
            resource_transfer = calculate_transfer(
                self.productivity, agents[0].capacity + capacity_transfer,
                agents[1].capacity + capacity_transfer, capacity_transfer)

            # Give the agent with the higher capacity 2*transfer capacity to
            # simulate a prior interaction where the transfer was made, when
            # both the nodes had their current capacity + transfer.
            max_capacity_agent = max(agents, key=attrgetter('capacity'))
            min_capacity_agent = min(agents, key=attrgetter('capacity'))
            max_capacity_agent.capacity += 2 * capacity_transfer
            min_capacity_agent.exp_resources += resource_transfer

            # Initialize edge attributes for transfer rates, memory of
            # resource transfers, and which agent is the patron.
            self.G.edges[e]['capacity_t'] = capacity_transfer
            self.G.edges[e]['resource_t'] = resource_transfer
            self.G.edges[e]['exp_resources'] = [
                resource_transfer, resource_transfer
            ]
            self.G.edges[e]['patron'] = max_capacity_agent

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

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

    def run_model(self, n):
        for i in range(n):
            if i == n // 2:
                # Halfway through simulation, add shock.
                self.productivity *= self.shock
            self.step()
コード例 #38
0
class MASArchitecture(Model):
    def __init__(self,
                 width,
                 height,
                 distributed,
                 model_reporters_dict=None,
                 agent_reporters_dict=None,
                 newOrderProbability=10,
                 quantity=1,
                 splitSize=1,
                 verbose=True,
                 searchSize=1,
                 ordersPerWeek=1,
                 batchRun=False):
        sys.stdout = sys.__stdout__
        print('New Order Probability {} - Quantity {} - Orders Per week {}'.
              format(newOrderProbability, quantity, ordersPerWeek))
        self.verbose = verbose
        if (verbose):
            sys.stdout = sys.__stdout__
        else:
            sys.stdout = open(os.devnull, 'w')

        self.grid = MultiGrid(width, height, True)
        self.schedule = RandomActivation(self)
        self.running = True
        self.minutes = 0
        self.hours = 0
        self.days = 0
        self.weeks = 0

        self.batchRun = batchRun

        # This is the number of external orders the marketplace recieved per week
        self.ordersPerWeek = ordersPerWeek
        # This is the probability at any given step that a factory will produce a new order
        self.newOrderProbability = newOrderProbability
        self.splitSize = splitSize

        federationCentre = SOEF(1, self, (49, 49), searchSize)

        self.schedule.add(federationCentre)
        self.grid.place_agent(federationCentre, federationCentre.coordinates)

        numberOfCheap = round(quantity * 0.5)
        numberOfASAP = round(quantity * 0.5)

        # This fella is only used to produce orders, has no capabilities of it's own
        self.dummyFactoryId = self.schedule.get_agent_count() + 1
        self.dummyFactoryAgent = FactoryAgent(self.dummyFactoryId,
                                              self, (2, 2),
                                              distributed,
                                              newOrderProbability,
                                              splitSize=splitSize)
        self.schedule.add(self.dummyFactoryAgent)
        self.grid.place_agent(self.dummyFactoryAgent,
                              self.dummyFactoryAgent.coordinates)

        while numberOfCheap != 0:
            numberOfCheap -= 1
            for factory in factoriesAndCapabilities:
                factoryNumber = self.schedule.get_agent_count() + 1

                newFactoryAgent = FactoryAgent(factoryNumber,
                                               self,
                                               factory[0],
                                               distributed,
                                               newOrderProbability,
                                               splitSize=splitSize)

                self.schedule.add(newFactoryAgent)
                self.grid.place_agent(newFactoryAgent,
                                      newFactoryAgent.coordinates)

                incrementedYCoordinate = 2
                for capability in factory[1]:
                    coordinates = (factory[0][0] + 3,
                                   factory[0][1] - incrementedYCoordinate)
                    newMachine = MachineAgent(self.schedule.get_agent_count() +
                                              1,
                                              self,
                                              capability,
                                              coordinates,
                                              factoryNumber,
                                              asapOrCheap='cheap')
                    self.schedule.add(newMachine)
                    self.grid.place_agent(newMachine, newMachine.coordinates)
                    incrementedYCoordinate += 2

        while numberOfASAP != 0:
            numberOfASAP -= 1
            for factory in factoriesAndCapabilities:

                coordinates = (factory[0][0] + 15, factory[0][1] + 15)
                factoryNumber = self.schedule.get_agent_count() + 1

                newFactoryAgent = FactoryAgent(factoryNumber,
                                               self,
                                               coordinates,
                                               distributed,
                                               newOrderProbability,
                                               splitSize=splitSize)

                self.schedule.add(newFactoryAgent)
                self.grid.place_agent(newFactoryAgent,
                                      newFactoryAgent.coordinates)

                incrementedYCoordinate = 2
                for capability in factory[1]:
                    newCoordinates = (coordinates[0] + 3,
                                      coordinates[1] - incrementedYCoordinate)

                    newMachine = MachineAgent(self.schedule.get_agent_count() +
                                              1,
                                              self,
                                              capability,
                                              newCoordinates,
                                              factoryNumber,
                                              asapOrCheap='asap')
                    self.schedule.add(newMachine)
                    self.grid.place_agent(newMachine, newMachine.coordinates)
                    incrementedYCoordinate += 2

        if (model_reporters_dict is None):
            self.datacollector = DataCollector()
        else:
            self.datacollector = DataCollector(
                model_reporters=model_reporters_dict,
                agent_reporters=agent_reporters_dict)

    def step(self):

        if (not self.batchRun):
            sys.stdout = sys.__stdout__
            print("Steps {} Weeks {} Days {} Hours {}".format(
                self.schedule.steps, self.weeks, self.days, self.hours))
            if (not self.verbose):
                sys.stdout = open(os.devnull, 'w')

        # Generate new orders
        if (self.ordersPerWeek <= 40):
            number = random.randrange(40 // self.ordersPerWeek)
            if (number == 0):
                capabilities = ['3D_SLS']
                orderAgent = OrderAgent(self.schedule.get_agent_count() + 1,
                                        self,
                                        capabilities,
                                        self.dummyFactoryId,
                                        splitSize=self.splitSize)
                self.schedule.add(orderAgent)
                self.grid.place_agent(
                    orderAgent, self.dummyFactoryAgent.newOrderCoordinates)
                newMessage = Message(self.dummyFactoryId, 'findResources')
                orderAgent.receivedMessages.append(newMessage)
        else:
            count = self.ordersPerWeek // 40
            while count != 0:
                count -= 1
                capabilities = ['3D_SLS']
                orderAgent = OrderAgent(self.schedule.get_agent_count() + 1,
                                        self,
                                        capabilities,
                                        self.dummyFactoryId,
                                        splitSize=self.splitSize)
                self.schedule.add(orderAgent)
                self.grid.place_agent(
                    orderAgent, self.dummyFactoryAgent.newOrderCoordinates)
                newMessage = Message(self.dummyFactoryId, 'findResources')
                orderAgent.receivedMessages.append(newMessage)
        '''Advance the model by one step.'''
        # Way easier to convert to hours...
        if (self.ordersPerWeek <= 40):

            number = random.randrange(40 // self.ordersPerWeek)
            if (number == 0):
                capabilities = ['3D_SLS']
                orderAgent = OrderAgent(self.schedule.get_agent_count() + 1,
                                        self,
                                        capabilities,
                                        self.dummyFactoryId,
                                        splitSize=self.splitSize)
                self.schedule.add(orderAgent)
                self.grid.place_agent(
                    orderAgent, self.dummyFactoryAgent.newOrderCoordinates)
                newMessage = Message(self.dummyFactoryId, 'findResources')
                orderAgent.receivedMessages.append(newMessage)
        else:
            count = self.ordersPerWeek // 40
            while count != 0:
                count -= 1
                capabilities = ['3D_SLS']
                orderAgent = OrderAgent(self.schedule.get_agent_count() + 1,
                                        self,
                                        capabilities,
                                        self.dummyFactoryId,
                                        splitSize=self.splitSize)
                self.schedule.add(orderAgent)
                self.grid.place_agent(
                    orderAgent, self.dummyFactoryAgent.newOrderCoordinates)
                newMessage = Message(self.dummyFactoryId, 'findResources')
                orderAgent.receivedMessages.append(newMessage)

        self.schedule.step()
        # Collect data
        self.datacollector.collect(self)
        self.hours += 1
        if (self.hours == 8):
            self.hours = 0
            self.days += 1

        if (self.days == 5):
            self.days = 0
            self.weeks += 1
コード例 #39
0
class NegotiationModel(object):
    '''
    '''

    step_stages = ["initialize", "send_threats", "resolve_threats", 
                    "resolve_attacks", "finalize", 
                    ("resolve_attacks", "Model")]


    def __init__(self, agents):
        '''
        Instantiate a new model.
        '''

        self.agents = agents
        self.schedule = StagedActivation(self, self.step_stages)
        for agent in self.agents:
            self.schedule.add(agent)

        self.agent_names = {agent.name: agent for agent in agents}

        self.running = True
        self.stage_delta = 1 / len(self.step_stages)
        
        self.log = EventLog()
        self.datacollector = DataCollector(
            {"Median": get_median, #lambda m: m.find_median(),
            "Mean": get_mean}, #lambda m: m.find_mean()},
            {"Position": get_position}) #lambda a: a.position})


    def step(self):
        '''
        One step of the model, through all step_stages.
        '''
        self.datacollector.collect(self)
        self.schedule.step()
        if all(a.position == self.agents[0].position for a in self.agents):
            self.running = False

    def run_model(self, steps):
        '''
        Run model for `steps` steps, or until it converges.
        '''
        while self.schedule.steps < steps and self.running:
            self.step()
        
    def resolve_attacks(self):
        done_attacks = []
        new_attacks = self.log.get_events(timestamp=self.schedule.steps,
            action="Attack")
        for attack in new_attacks:
            if (attack.target, attack.source) in done_attacks:
                continue
            source = self.agent_names[attack.source]
            target = self.agent_names[attack.target]
            if self.resolve_conflict(source, target):
                winner, loser = source, target
            else:
                winner, loser = target, source
            winner.win_conflict(loser)
            loser.lose_conflict(winner)
            done_attacks.append((attack.source, attack.target))

    def resolve_conflict(self, side_1, side_2):
        '''
        Resolve an active conflict between sides 1 and 2.

        Args:
            side_1, side_2: Agent objects
        Returns:
            True if side_1 wins, False if side_2 wins.
        '''
        if side_1.position == side_2.position:
            print(side_1)
            print(side_2)
            raise Exception("This attack shouldn't be happening.")
        side_1_power = 0
        side_2_power = 0
        for agent in self.agents:
            v = agent.allocate_support(side_1, side_2)
            if v < 0:
                side_2_power += abs(v)
            else:
                side_1_power += v
        try:
            p = side_1_power / (side_1_power + side_2_power)
        except Exception as e:
            print(side_1)
            print(side_2)
            raise e
        if random.random() < p:
            return True
        else:
            return False

    def add_event(self, source, target, action):
        '''
        Add an event to the event log.
        '''
        if type(source) is not str:
            source = source.name
        if type(target) is not str:
            target = target.name
        self.log.add_event(source, target, self.schedule.steps, action)

    def find_median(self):
        '''
        Returns the estimated median voter position.
        Uses the original BDM model calculation.
        '''
        pairwise_contests = {}
        for i, j in permutations(self.agents, 2):
            votes = 0
            for agent in self.agents:
                delta = (abs(agent.position - j.position) 
                    - abs(agent.position - i.position))
                votes += agent.capability * agent.salience * delta
            pairwise_contests[(i.position, j.position)] = votes
        return max(pairwise_contests, key=lambda x: pairwise_contests[x])[0]

    def find_mean(self):
        '''
        Returns the estimated mean position, weighted by capability*salience.
        '''
        weighted_sum = 0
        weights = 0
        for agent in self.agents:
            weight = agent.capability * agent.salience
            weighted_sum += weight * agent.position
            weights+= weight
        return weighted_sum / weights
コード例 #40
0
class SchellingModel(Model):
    '''Model class for Schelling segregation model'''

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

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

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


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

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


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

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

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


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

        self.happy = happy_count
        self.segregated = avg_seg/self.schedule.get_agent_count()
コード例 #41
0
ファイル: transport_model.py プロジェクト: i-Zaak/linum
class Travel_Model(Model):
    def __init__(self, networks=None, season_length=91, n_agents=100, max_steps=1000):
        self.n_steps = 0
        self.max_steps = max_steps
        self.season_length = season_length
        self.schedule = BaseScheduler(self)
        if networks is None:
            networks = self._demo_networks()
        self.n_seasons = len(networks)
        
        # space
        nodes = networks[0].nodes()
        edges = []
        for network in networks:
            edges.append(network.edges(data=True))

        self.network = MultilayerNetworkSpace(nodes,edges)

        # agents
        for n in range(n_agents):
            start, dest = sample(nodes,2)
            start_time = randrange(self.n_seasons * self.season_length )
            agent = Travel_Agent(start,dest,start_time,n)

            self.schedule.add(agent)
        
        # data collection
        self.dc = DataCollector(
                {
                    "enroute": lambda m: self.count_en_route(m)
                    },
                {
                    "position": lambda a: a.pos,
                    "travel_time": lambda a: a.travel_time
                    }
                )
        self.dc.collect(self)

        self.running = True

    def step(self):
        self.schedule.step()
        self.dc.collect(self)
        self.n_steps +=1

        if self.count_en_route(self) == 0 or self.n_steps >= self.max_steps:
            self.running = False

    def get_season(self, time):
        return (time // self.season_length) % self.n_seasons 


    def _demo_networks(self):
        networks = []
        for i in range(3):
            g = nx.random_graphs.watts_strogatz_graph(100, 2, 0.05)
            dists = np.random.randint(1,30, g.number_of_edges())
            dists = dict(zip(g.edges(),dists))
            nx.set_edge_attributes(g, 'distance', dists)
            networks.append(g)
        return networks

    @staticmethod
    def count_en_route(model):
        count = len(model.schedule.agents)
        for agent in model.schedule.agents:
            if agent.pos == agent.dest:
                count -=1
        return count
コード例 #42
0
class SugarscapeCg(Model):
    """
    Sugarscape 2 Constant Growback
    """

    LIVING_ANTS = "Living Ants"
    DEAD_ANTS = "Dead Ants"
    PERCENT_DEAD_LOW_VISION = "% Dead Low Vision"
    PERCENT_DEAD_HIGH_VISION = "% Dead High Vision"

    verbose = False  # Print-monitoring

    def __init__(self, height=50, width=50, initial_population=100, recreate=0, share_knowledge=False, solidarity=False):
        """
        Create a new Constant Growback model with the given parameters.

        Args:
            initial_population: Number of population to start with
        """

        # Set parameters
        self.height = height
        self.width = width
        self.initial_population = initial_population
        self.recreate = recreate

        self.schedule = RandomActivationByBreed(self)
        self.shared_knowledge = SharedKnowledge(width=width, height=height) if share_knowledge else None
        self.solidarity = self.shared_knowledge and solidarity
        self.grid = MultiGrid(self.height, self.width, torus=False)
        self.datacollector = DataCollector({
            "initial_population": lambda m: m.initial_population,
            "shared_knowledge": lambda m: m.shared_knowledge is not None,
            "recreate": lambda m: m.recreate,
            "solidarity": lambda m: m.solidarity,
            self.LIVING_ANTS: lambda m: m.schedule.get_breed_count(Ant),
            self.DEAD_ANTS: lambda m: m.schedule.num_dead,
            self.PERCENT_DEAD_LOW_VISION: lambda m: m.schedule.percent_dead(filter=self.PERCENT_DEAD_LOW_VISION),
            self.PERCENT_DEAD_HIGH_VISION: lambda m: m.schedule.percent_dead(filter=self.PERCENT_DEAD_HIGH_VISION),
            "min_sugar": lambda m: m.schedule.min_sugar(),
            "max_sugar": lambda m: m.schedule.max_sugar(),
            "avg_sugar": lambda m: m.schedule.avg_sugar(),
            "stdev_sugar": lambda m: m.schedule.stdev_sugar(),
        })

        # Create sugar
        sugar_distribution = np.genfromtxt("sim/sugar-map.txt")
        for _, x, y in self.grid.coord_iter():
            max_sugar = sugar_distribution[x, y]
            sugar = Sugar((x, y), self, max_sugar)
            self.grid.place_agent(sugar, (x, y))
            self.schedule.add(sugar)

        # Create ants:
        for i in range(self.initial_population):
            self._create_ant()

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

    def _create_ant(self):
        sugar = self.random.randrange(6, 25)
        metabolism = self.random.randrange(2, 4)
        vision = self.random.randrange(1, 5)
        while self.is_occupied(pos:=(
            self.random.randrange(self.width),
            self.random.randrange(self.height)
        )):
コード例 #43
0
class OpinionModel(Model):
    '''
    A model with some number of agents

    Keyword arguments:
    N -- Number of agents
    neighborhoods -- An NxX matrix.
    neighborhoods[a] is agent a\'s list of neighbors.
    The neighborhoods is not actually a matrix.
    Each inner list may be of different length.
    intial_opinions -- This is a list size N of opinions.
    Each inner list must have the same length, the opinions
    are then labeled Opinion0, Opinion1, ..., OpinionZ.
    potentials -- Potentials is a 1-D list of functions
    Each function describes how agents are influenced by innodes.
    coupling -- AxA matrix, where A = |opinions|. Describes how
    opinions affect each other.
    '''
    def __init__(self,
                 N,
                 neighborhoods,
                 weights,
                 initial_opinions,
                 potentials,
                 coupling,
                 schedule="simultaneous"):
        self.ALPHA = .001
        self.num_agents = N
        self.neighborhoods = neighborhoods
        self.initial_opinions = initial_opinions
        self.potentials = potentials
        self.coupling = coupling

        if weights is None:
            self.weights = [None for i in range(self.num_agents)]
        else:
            self.weights = weights

        #Set schedule
        if schedule == 'simultaneous':
            self.schedule = StagedActivation(
                self,
                stage_list=["simultaneousStep", "simultaneousAdvance"],
                shuffle=False)
        elif schedule == 'pairwise':
            self.schedule = StagedActivation(
                self,
                stage_list=["reset", "pairwiseStep", "noise"],
                shuffle=True)
            #stage_list is where you add "coupling" and "noise".

        #Create agents
        for i in range(self.num_agents):
            a_params = OpinionAgentParameters(i, self, self.neighborhoods[i],
                                              self.weights[i],
                                              self.potentials[i],
                                              initial_opinions[i])
            if schedule == 'simultaneous':
                a = OpinionAgent(a_params)
            elif schedule == 'pairwise':
                a = OpinionAgent(a_params)
            self.schedule.add(a)

        ag_reps = dict()
        for i in range(len(self.schedule.agents[0].opinions)):
            ag_reps["Opinion" + str(i)] = self.makeLam(i)

        self.datacollector = DataCollector(agent_reporters=ag_reps)

    def step(self):
        '''
        Advance the model one step
        '''
        self.datacollector.collect(self)
        self.schedule.step()

    def run(self, steps):
        for i in range(steps):
            self.step()

    def total_change(self):
        sum = 0
        for j in range(len(self.schedule.agents[0].opinions)):
            for i in range(self.num_agents):
                sum += abs(self.schedule.agents[i].opinions[0] -
                           self.schedule.agents[i].nextOpinion[0])
        return sum

    def makeLam(self, i):
        '''
        Don't use outside of the context of the OpinionModel's init method.
        This function is needed in order for the DataCollector to work properly,
        intializing the lambdas inside __init__ inside a for loop causes the last
        value of the iterator to be used for all of the functions, causing
        unwanted behavior. So that's why this function exists.
        '''
        return lambda a: a.opinions[i]
コード例 #44
0
class covid_Model(Model):
    """
    Class representing Model. The Model is responsible for the logical structure of the ABM.
    Here, the model is set up both visually to the grid and logical to the algorithm

    The most important attributes are listed below.
    The rest is commented in the class below.
    ---------
    N : int
        Number of agents in grid in current timestep
    height : int
        height of grid
    width : int
        width of grid
    setUpType : List
        List of classroom types/construction (2,3,4/H,R,G)
    grid : grid
        Visual grid
    schedule : module
        Logical grid
    datacollector : module
        collects data that we want to analyze
    time_step : int
        Indicates current time step
    minute_count : int
        Counting minutes
    hour_count : int
        Counting hours
    day_count : int
        Counting days
    TAs : List
        List of TAs at the current time_step
    classroom_2 : List
        List of seat-positions with corrosponding direction in the H set up
    classroom_3 : List
        List of seat-positions with corrosponding direction in the R set up
    classroom_4 : List
        List of seat-positions with corrosponding direction in the G set up

    """
    def __init__(self, N, height, width, setUpType):
        self.n_agents = N
        self.height = height

        self.grid = MultiGrid(width, height, torus=False)  #torus wraps edges
        self.schedule = SimultaneousActivation(self)
        self.setUpType = setUpType
        self.datacollector = DataCollector(
            model_reporters={
                "infected": lambda m: get_infected_count(self),
                "Agent_count": lambda m: all_agents_count(self),
                "recovered": lambda m: get_recovered_count(self),
                "Home": lambda m: get_home_sick_count(self),
                "Reproduction": lambda m: get_list_of_reproduction(self)
            })

        #Lists to hold agent-objects with with different states
        self.TAs = []
        self.agents_at_home = []
        self.recovered_agents = []
        self.infected_agents = []
        self.canteen_agents_at_work = []
        self.canteen_backups_to_go_home = []

        #Counting minutes and days
        self.minute_count = 1
        self.hour_count = 1
        self.day_count = 1
        #  self.door = ()

        self.entre = [(15, 0), (16, 0), (17, 0), (25, 34), (25, 33), (25, 32)]

        #Define time schedule + when breaks are
        self.class_times = [105, 120, 225, 300, 405, 420, 525]
        self.breaks_for_all = [i for i in range(105, 120)] + [
            i for i in range(225, 300)
        ] + [i for i in range(405, 420)]
        self.breaks_for_ft = [i for i in range(105, 300)]
        self.breaks_for_sf = [i for i in range(225, 420)]

        self.other_courses, self.range46, self.range13 = [], [], []

        create_courses(self)

        #Define classrooms +  directions
        self.classroom_2 = [((0, 0), dir['E']), ((1, 0), dir['N']),
                            ((2, 0), dir['N']), ((3, 0), dir['N']),
                            ((4, 0), dir['N']), ((5, 0), dir['N']),
                            ((6, 0), dir['N']), ((7, 0), dir['N']),
                            ((0, 1), dir['E']), ((0, 2), dir['E']),
                            ((0, 3), dir['E']), ((0, 4), dir['E']),
                            ((0, 5), dir['E']), ((0, 6), dir['E']),
                            ((0, 7), dir['E']), ((0, 8), dir['E']),
                            ((0, 9), dir['E']), ((1, 9), dir['S']),
                            ((2, 9), dir['S']), ((3, 9), dir['S']),
                            ((4, 9), dir['S']), ((5, 9), dir['S']),
                            ((6, 9), dir['S']), ((7, 9), dir['S'])]
        self.classroom_3 = [((1, 6), dir['E']), ((1, 7), dir['E']),
                            ((1, 8), dir['E']), ((1, 9), dir['E']),
                            ((2, 0), dir['E']), ((2, 1), dir['E']),
                            ((2, 2), dir['E']), ((2, 3), dir['E']),
                            ((3, 6), dir['E']), ((3, 7), dir['E']),
                            ((3, 8), dir['E']), ((3, 9), dir['E']),
                            ((4, 0), dir['E']), ((4, 1), dir['E']),
                            ((4, 2), dir['E']), ((4, 3), dir['E']),
                            ((5, 6), dir['E']), ((5, 7), dir['E']),
                            ((5, 8), dir['E']), ((5, 9), dir['E']),
                            ((6, 0), dir['E']), ((6, 1), dir['E']),
                            ((6, 2), dir['E']), ((6, 3), dir['E'])]
        self.classroom_4 = [((1, 1), dir['N']), ((1, 2), dir['S']),
                            ((2, 1), dir['N']), ((2, 2), dir['S']),
                            ((1, 4), dir['N']), ((1, 5), dir['S']),
                            ((2, 4), dir['N']), ((2, 5), dir['S']),
                            ((1, 7), dir['N']), ((1, 8), dir['S']),
                            ((2, 7), dir['N']), ((2, 8), dir['S']),
                            ((4, 1), dir['N']), ((4, 2), dir['S']),
                            ((5, 1), dir['N']), ((5, 2), dir['S']),
                            ((4, 4), dir['N']), ((4, 5), dir['S']),
                            ((5, 4), dir['N']), ((5, 5), dir['S']),
                            ((4, 7), dir['N']), ((4, 8), dir['S']),
                            ((5, 7), dir['N']), ((5, 8), dir['S'])]

        #Set up seats, canteen tables, queuing area
        self.seats, self.seat, self.toilet = [], (), ()
        self.canteen_table_1 = [((22, y), dir['E']) for y in range(25, 33)] + [
            ((18, y), dir['E']) for y in range(25, 33)
        ] + [((14, y), dir['E']) for y in range(25, 33)]
        self.canteen_table_2 = [((23, y), dir['W']) for y in range(25, 33)] + [
            ((19, y), dir['W']) for y in range(25, 33)
        ] + [((15, y), dir['W']) for y in range(25, 33)]
        self.canteen_tables = self.canteen_table_1 + self.canteen_table_2
        self.canteen_counter = 0
        self.enter_canteen_area12 = [(x, y) for y in range(0, 4)
                                     for x in range(17, 26)]
        self.enter_canteen_area10 = [(x, y) for y in range(0, 4)
                                     for x in range(21, 26)]
        self.canteen_queue_area = [(22, 3), (24, 3)] + [
            (23, y) for y in range(3, 21)
        ] + [(25, y) for y in range(5, 19)]
        self.classroom_area = [(x, y) for y in range(0, height + 1)
                               for x in range(0, 9)]
        self.toilet_queue_area = [(x, y) for x in range(8, 15)
                                  for y in [height - 1, height - 2]]

        set_up_initial_attributes(self)

        #Make seats (if family group restriction is on, dont shuffle)
        self.seat = make_classroom_seating(setUpType, self)
        for list in self.seat:
            if family_groups == False:  #Shuffle
                self.seats.append(random.sample(list, k=len(list)))
            elif family_groups == True:  #Dont shuffle
                self.seats.append(list)

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

        if 0 < percentages_of_vaccinated < 1:
            vaccinate_agents(self)

    def step(self):
        ''''
        Invoked every time step and is multi-purposed.
        Collect data in the data-collector and invokes all agents' step() function

        Tracks and manage time and time count, including weekends, day off and off school parameters at students.
        Initiate several different functions; chosing agents to go toilet, set students with questions in class,
        make classroom seating, set canteen employees,

        :param self: class-object
        :return: None
        '''
        #Only let people go to toilet, if toilet is open (closed when everyone go home in breaks)
        if go_home_in_breaks == False:
            choose_agents_to_go_to_toilet(self)

        #Go home if you dont have any more courses today
        set_off_school(self)

        #Day off
        if self.day_count % 7 == 2 or self.day_count % 7 == 3 or self.day_count % 7 == 4 or self.day_count % 7 == 5:
            set_day_off(self)

        #Update classroom seatings
        if go_home_in_breaks == False:
            if self.minute_count in [1, 119, 299, 419]:
                self.seats = make_classroom_seating(self.setUpType, self)

        #Handle employees
        set_canteen_employees(self)
        #Answer questions
        students_with_questions(self)

        #Tell the students that are attending class next, that they need to go to class. Timing this depends on
        #wether or not everyone go home in breaks or not
        set_students_go_to_class_next(self)

        #Step every agent and collect data
        self.schedule.step()
        self.datacollector.collect(self)

        #Time count, manage weekends and toilet cleaning
        self.minute_count += 1
        if self.minute_count % 60 == 0:
            self.hour_count += 1

        if self.minute_count % 526 == 0:
            self.day_count += 1
            if self.day_count in [6, 13, 20, 27, 34, 41, 48, 55, 62]:
                self.day_count += 2
                weekend(self)
            self.minute_count = 1
            self.hour_count = 1
            try:
                self.toilet.has_been_infected = False  #Clean toilet everyday
            except:
                return
コード例 #45
0
class World(Model):
    def __init__(self, N, coop, e_prob, width=100, height=100):
        self.num_agents = N
        self.grid = MultiGrid(width, height, False)
        self.schedule = RandomActivation(self)
        self.running = True
        self.population_center_x = np.random.randint(
            POP_MARGIN, self.grid.width - POP_MARGIN)
        self.population_center_y = np.random.randint(
            POP_MARGIN, self.grid.height - POP_MARGIN)
        self.num_energy_resources = RESERVE_SIZE
        self.num_explorers = 0
        self.num_exploiters = 0
        self.datacollector = DataCollector(model_reporters={
            "Num_Explorer": "num_explorers",
            "Num_Exploiter": "num_exploiters"
        })
        self.bases = self.init_base()
        self.ages = []
        self.memoryLens = [
        ]  # This will store average memory length at death for agent
        self.expected_ages = []
        self.member_tracker = []
        self.energy_tracker = []
        self.decay_rates = self.init_decay_rates()

        # add social agents to the world
        for i in range(1, self.num_agents + 1):
            if np.random.uniform() <= EXPLORER_RATIO:
                # create a new explorer
                a = Explorer("explorer_%d" % (i), self, coop)
                self.num_explorers += 1
            else:
                # create a new exploiter
                a = Exploiter("exploiter_%d" % (i), self, coop, e_prob)
                self.num_exploiters += 1

            # keep society members confined at beginning
            x = np.random.randint(self.population_center_x - POP_SPREAD,
                                  self.population_center_x + POP_SPREAD)
            y = np.random.randint(self.population_center_y - POP_SPREAD,
                                  self.population_center_y + POP_SPREAD)
            self.grid.place_agent(a, (x, y))

            # add agent to scheduler
            self.schedule.add(a)
            self.expected_ages.append(a.energy / a.living_cost)

        # add energy reserves to the world
        for i in range(self.num_energy_resources):
            a = EnergyResource("energy_reserve_%d" % (i), self,
                               self.decay_rates[i])

            # decide location of energy reserve
            x = np.random.randint(0, self.grid.width)
            y = np.random.randint(0, self.grid.height)
            self.grid.place_agent(a, (x, y))

            self.schedule.add(a)

    def init_base(self):
        pos = (self.population_center_x, self.population_center_y)
        return self.grid.get_neighborhood(pos, True, radius=POP_SPREAD)

    def init_decay_rates(self):
        decay_rates = list(
            np.random.uniform(-0.1, 0.02, self.num_energy_resources))
        np.random.shuffle(decay_rates)
        return decay_rates

    def step(self):
        self.datacollector.collect(self)
        self.schedule.step()
        self.member_tracker.append((self.num_explorers, self.num_exploiters))

        # keep track of total energy in world
        if self.schedule.time % 50 == 0:
            energies = [
                e.reserve for e in self.schedule.agents
                if isinstance(e, EnergyResource)
            ]
            if len(energies) > 0:
                mean_energy = np.mean(energies)
            else:
                mean_energy = 0
            self.energy_tracker.append(mean_energy)

        # change location of energy resources every 500 steps randomly
        # and change decay_rate to opposite every 100 steps
        if self.schedule.time % 50 == 0:
            for e in self.schedule.agents:
                if isinstance(e, EnergyResource) and np.random.uniform() < 0.1:
                    # change location
                    e.decay_rate *= -1
                    if self.schedule.time % 500 == 0:
                        self.grid.remove_agent(e)
                        x = np.random.randint(0, self.grid.width)
                        y = np.random.randint(0, self.grid.height)
                        self.grid.place_agent(e, (x, y))
コード例 #46
0
class WolfSheepPredation(Model):
    '''
    Wolf-Sheep Predation Model
    '''

    height = 20
    width = 20

    initial_sheep = 100
    initial_wolves = 50

    sheep_reproduce = 0.04
    wolf_reproduce = 0.05

    wolf_gain_from_food = 20

    grass = False
    grass_regrowth_time = 30
    sheep_gain_from_food = 4

    verbose = False  # Print-monitoring

    description = 'A model for simulating wolf and sheep (predator-prey) ecosystem modelling.'

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

        Args:
            initial_sheep: Number of sheep to start with
            initial_wolves: Number of wolves to start with
            sheep_reproduce: Probability of each sheep reproducing each step
            wolf_reproduce: Probability of each wolf reproducing each step
            wolf_gain_from_food: Energy a wolf gains from eating a sheep
            grass: Whether to have the sheep eat grass for energy
            grass_regrowth_time: How long it takes for a grass patch to regrow
                                 once it is eaten
            sheep_gain_from_food: Energy sheep gain from grass, if enabled.
        '''

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

        self.schedule = RandomActivationByBreed(self)
        self.grid = MultiGrid(self.height, self.width, torus=True)
        self.datacollector = DataCollector({
            "Wolves":
            lambda m: m.schedule.get_breed_count(Wolf),
            "Sheep":
            lambda m: m.schedule.get_breed_count(Sheep)
        })

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

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

        # Create grass patches
        if self.grass:
            for agent, x, y in self.grid.coord_iter():

                fully_grown = random.choice([True, False])

                if fully_grown:
                    countdown = self.grass_regrowth_time
                else:
                    countdown = random.randrange(self.grass_regrowth_time)

                patch = GrassPatch((x, y), self, fully_grown, countdown)
                self.grid.place_agent(patch, (x, y))
                self.schedule.add(patch)

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

    def step(self):
        self.schedule.step()
        # collect data
        self.datacollector.collect(self)
        if self.verbose:
            print([
                self.schedule.time,
                self.schedule.get_breed_count(Wolf),
                self.schedule.get_breed_count(Sheep)
            ])

    def run_model(self, step_count=200):

        if self.verbose:
            print('Initial number wolves: ',
                  self.schedule.get_breed_count(Wolf))
            print('Initial number sheep: ',
                  self.schedule.get_breed_count(Sheep))

        for i in range(step_count):
            self.step()

        if self.verbose:
            print('')
            print('Final number wolves: ', self.schedule.get_breed_count(Wolf))
            print('Final number sheep: ', self.schedule.get_breed_count(Sheep))
コード例 #47
0
class KSUModel(Model):
    """A model simulating KSU student"""
    def __init__(self, n_students, n_active: int, width: int, height: int):
        self.running = True
        self.schedule = SimultaneousActivation(self)
        self.grid = SingleGrid(width, height, torus=False)
        self.n_students: int = n_students
        self._semester_gen = self._gen_semester_code()
        self.semester = next(self._semester_gen)
        self.ALL_GENDERS = gen_gender(self.n_students)

        # Majors
        self.F1SEQ1_MAJORS = gen_f1seq1_majors(self.n_students)
        self.major_switcher = MajorSwitch()

        # Adding Student to KSU Environment
        for i in range(self.n_students):
            # Percentage of student agent that will be active and the rest inactive
            per_active = n_active / 100

            if np.random.binomial(1, per_active):
                student = Student(i, self, self.ALL_GENDERS[i])
                student.majors.append(self.F1SEQ1_MAJORS[i])
            else:
                student = Student(i, self, self.ALL_GENDERS[i], False)
                student.majors.append("N/A")

            self.schedule.add(student)
            self.grid.position_agent(student)

        self.datacollector = DataCollector(
            agent_reporters={
                "GPA": "gpa",
                "ATTEMPTED_HRS": "attempted_hrs",
                "EARNED_HRS": "earned_hrs",
                "Major": "curr_major"
            })

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

        try:
            self.update_semester()
            self.update_credit_hrs()
            self.update_gpa()
        except StopIteration:
            agent_gpa = self.datacollector.get_agent_vars_dataframe()
            agent_gpa.to_csv("gpa.csv", index=False)
            self.running = False

    def update_semester(self) -> None:
        self.semester = next(self._semester_gen)

    def update_credit_hrs(self):
        active_students: List[Student] = [
            student for student in self.schedule.agents if student.is_active
        ]
        n_active_students = len(active_students)

        earned_hrs = [
            round(earned_hr)
            for earned_hr in gen_credit_hrs(self.semester, n_active_students)
        ]
        attempted_hrs = [
            round(attempted_hr) for attempted_hr in gen_credit_hrs(
                self.semester, n_active_students, False)
        ]

        for i, student in enumerate(active_students):
            curr_major = tlz.last(student.majors)
            new_earned_hrs = student.earned_hrs
            new_attempted_hrs = student.attempted_hrs

            # Check if earned & attempted credit hours exists for current semester
            if earned_hrs:
                new_earned_hrs = 0 if curr_major == "E" else earned_hrs[i]
                new_attempted_hrs = 0 if curr_major == "E" else attempted_hrs[i]

            student.earnedhrs_history.append(new_earned_hrs)
            student.attemptedhrs_history.append(new_attempted_hrs)

    def update_gpa(self):
        active_students: List[Student] = [
            student for student in self.schedule.agents if student.is_active
        ]
        n_active_students = len(active_students)

        gpa_distr = [
            round(earned_hr)
            for earned_hr in gen_credit_hrs(self.semester, n_active_students)
        ]

        for i, student in enumerate(active_students):
            curr_major = tlz.last(student.majors)
            new_gpa = student.gpa

            # Check if gpa exists for current semester
            if gpa_distr:
                new_gpa = 0 if curr_major == "E" else gpa_distr[i]

            student.gpa_history.append(new_gpa)

    @staticmethod
    def _gen_semester_code():
        semester_pos = [x for x in range(1, 7)]
        semester_season = product(semester_pos, ("F", "F", "S", "S"))
        seq = cycle([1, 2])

        for semester in semester_season:
            pos, season = semester
            yield f"{season}{pos}SEQ{next(seq)}"
コード例 #48
0
ファイル: model.py プロジェクト: jiajia20/mesa-vis
class InfoSpread(Model):
    """A virus model with some number of agents"""
    def __init__(
        self,
        num_nodes=10,
        avg_node_degree=3,
        rewire_prob=.1,
        initial_outbreak_size=1,
        threshold=2,
        inf_prob_model=1,
    ):
        self.num_nodes = num_nodes
        self.G = nx.watts_strogatz_graph(
            n=self.num_nodes, k=avg_node_degree,
            p=rewire_prob)  #G generate graph structure
        self.grid = NetworkGrid(
            self.G
        )  #grid is the Masa native defintion of space: a coorindate with specified topology on which agents sits and interact
        self.schedule = SimultaneousActivation(self)
        self.initial_outbreak_size = (initial_outbreak_size
                                      if initial_outbreak_size <= num_nodes
                                      else num_nodes)

        self.inf_prob_model = inf_prob_model

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

        # Create agents
        for i, node in enumerate(self.G.nodes()):
            a = User(i, self, "susceptible", threshold, inf_prob_model)
            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 = "infected"
            neighbors_nodes = self.grid.get_neighbors(a.pos)
            for n in self.grid.get_cell_list_contents(neighbors_nodes):
                n.state = 'infected'

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

    def proportion_infected(self):
        try:
            return number_state(self, "infected") / self.num_nodes
        except ZeroDivisionError:
            return math.inf

    def step(self):
        self.schedule.step(
        )  #this model updates with symoutanous schedule, meaning,
        # collect data
        self.datacollector.collect(self)

    def run_model(self, n):
        ''' could experiment terminating model here too'''
        for i in range(n):
            self.step()
コード例 #49
0
ファイル: tax_model.py プロジェクト: nmontesg/value-alignment
class Society(Model):
    """
	A very simple of a society where taxes are collected and redistributed.
	"""
    def __init__(self, num_agents, num_evaders, collecting_rates,
                 redistribution_rates, invest_rate, catch, fine_rate):
        assert len(collecting_rates) == len(
            redistribution_rates
        ), "different number of collecting and redistributing segments."
        self.num_agents = num_agents  # number of agents
        self.common_fund = 0.  # collected taxes for each transition
        self.num_segments = len(collecting_rates)  # number of segments
        self.collecting_rates = collecting_rates  # collecting rates by group
        self.redistribution_rates = redistribution_rates  # redistribution rates by group
        self.invest_rate = invest_rate  # interest return to the investment of the common fund
        assert num_evaders <= self.num_agents, "more evaders than agents"
        self.num_evaders = num_evaders  # number of evader agents
        self.catch = catch  # probability of catching an evader
        self.fine_rate = fine_rate  # fine to be imposed if an evader in caught
        self.schedule = RandomActivation(self)
        self.running = True

        # create agents
        for i in range(self.num_agents):
            a = Individual(self, i)
            self.schedule.add(a)
        # assign some of the agents as evaders randomly
        for _ in range(self.num_evaders):
            random_agent = choice(self.schedule.agents)
            while random_agent.is_evader:
                random_agent = choice(self.schedule.agents)
            random_agent.is_evader = True

        # assign agents to their wealth group
        self.assign_agents_to_segments()

        # data collector on wealth of agents and Gini index of society
        self.data_collector = DataCollector(
            model_reporters={"Gini_wealth": compute_gini_wealth},
            agent_reporters=dict(Wealth="wealth",
                                 Segment="segment",
                                 Position="position",
                                 Evader="is_evader"))
        # collect initial data
        self.data_collector.collect(self)

    def assign_agents_to_segments(self):
        """
		Assign the agents in a model to their wealth segment and overall position.
		"""
        # assign agents to their wealth segment
        sorted_agents = sorted(self.schedule.agents, key=lambda a: a.wealth)
        # assign agents to their position in ranking
        for i in range(len(sorted_agents)):
            setattr(sorted_agents[i], 'position', self.num_agents - i - 1)
        # assign agents to their segment
        cut_index = int(self.num_agents / self.num_segments)
        for n in range(self.num_segments):
            for ag in sorted_agents[n * cut_index:(n + 1) * cut_index]:
                setattr(ag, 'segment', n)
            try:
                [
                    setattr(ag, 'segment', n)
                    for ag in sorted_agents[(n + 1) * cut_index:]
                ]
            except:
                pass

    def step(self):
        """
		Taxes and (if any) fines are collected into the common fund, and redistributed with interest.
		"""
        self.common_fund = 0.
        # collect taxes from all agents
        self.schedule.step()
        # redistribute common fund
        for ind in self.schedule.agents:
            ind.wealth += self.common_fund * (
                1 + self.invest_rate) * self.redistribution_rates[
                    ind.segment] * self.num_segments / self.num_agents
        # recompute segments
        self.assign_agents_to_segments()
        # collect data
        self.data_collector.collect(self)
コード例 #50
0
class DCGame(Model):
    def __init__(self, adjMat, visibles, adversaries):
        self.adjMat = adjMat  #matrix that keeps track of all players and their neighbors
        self.schedule = SimultaneousActivation(
            self
        )  # An activation in which players' states are effectively updated simultaneously as opposed to sequentially
        self.numAgents = len(adjMat)
        self.terminate = False  # if all non-adversarial players have reached consensus, terminal state is achieved
        self.time = 0
        # logging information
        self.log = Log()

        # total number of color changes in a game
        self.colorChanges = 0

        # convert adjMat to adjList
        def getAdjList(adjMat):
            adjList = {key: [] for key in range(self.numAgents)}
            for node in range(self.numAgents):
                #adjList[node] = [idx for idx, value in enumerate(adjMat[node]) if value == True]
                adjList[node] = [
                    idx for idx, value in enumerate(adjMat[node])
                    if value == 'True'
                ]
            return adjList

        self.adjList = getAdjList(self.adjMat)

        ############# designate visible, adversarial, and consensus nodes #############
        self.visibleColorNodes = visibles
        self.adversarialNodes = adversaries
        self.consensusNodes = [
            n for n in range(self.numAgents) if n not in self.adversarialNodes
        ]

        # adversarial nodes and regular nodes should not overlap
        assert set(self.adversarialNodes) & set(self.consensusNodes) == set()
        # visible nodes should belong to regular nodes
        assert set(self.visibleColorNodes) & set(self.consensusNodes) == set(
            self.visibleColorNodes)

        # logging simulation configuration
        self.log.add("#visible nodes: " + str(self.visibleColorNodes))
        self.log.add("#adversarial nodes: " + str(self.adversarialNodes))
        self.log.add("#consensus nodes: " + str(self.consensusNodes) + '\n')

        ############# initialize all agents #############
        for i in range(self.numAgents):
            # if i is a visible node
            isVisibleNode = i in self.visibleColorNodes
            # if i is an adversarial
            isAdversarial = i in self.adversarialNodes
            # make sure adversarial nodes are not intersected with visible nodes
            assert isVisibleNode & isAdversarial == False

            neighbors = self.adjList[i]

            # visible color nodes in i's neighbors
            vNode = list(set(neighbors) & set(self.visibleColorNodes))

            a = GameAgent(i, isVisibleNode, isAdversarial, neighbors, vNode,
                          self)
            self.schedule.add(a)

        # instantiate all nodes' neighbors and visibleColorNodes
        for agent in self.schedule.agents:
            agent.instantiateNeighbors(self)
            agent.instantiateVisibleColorNodes(self)

        self.datacollector = DataCollector(
            model_reporters={
                "red": getRed,
                "green": getGreen
            },
            agent_reporters={"agent_color": lambda a: a.color})

    # simulate the whole model for one step
    def step(self):
        # # # if either red or green reaches consensus, terminates!
        # # in terminal state we do not collect data
        if not self.terminate:
            self.datacollector.collect(self)
            self.schedule.step()
        return self.terminate

    def simulate(self, simulationTimes):
        for i in range(simulationTimes):
            self.updateTime(i)  # update model's time
            terminate = self.step()
            if terminate:
                break

        #added by Yifan
        hasWhitePlayers = False
        if not terminate:
            # if consensus was not reached in the simulation
            for agent in self.schedule.agents:
                if not agent.isAdversarial and not agent.isVisibleNode and agent.color == "white":
                    #at least one consensus player remained white
                    hasWhitePlayers = True

        # output log file to disk
        self.log.outputLog('result/simResult.txt')
        simulatedResult = self.datacollector.get_model_vars_dataframe()
        return (simulatedResult, hasWhitePlayers)

    # update model's clock
    def updateTime(self, t):
        self.time = t

    def setTerminal(self):
        assert self.terminate == False
        self.terminate = True

    def addRecord(self, msg):
        self.log.add(msg)

    # for degub purpose only
    def outputAdjMat(self, path):
        with open(path, 'w') as fid:
            for line in self.adjMat:
                # convert list of boolean values to string values
                tline = ["1" if item else "0" for item in line]
                fid.write(' '.join(tline) + '\n')
コード例 #51
0
class ContactModel(Model):
    def __init__(self, N, height, width, exponent, steps, seed):
        self.number_of_agents = N
        self.height = height
        self.width = width
        self.exponent = exponent
        self.range = 5
        self.neighborhood_deltas = self.initialize_neighborhood_deltas()

        self.x_locs = np.zeros((N, steps + 1))
        self.y_locs = np.zeros((N, steps + 1))

        self.current_step = 0  #NEW

        self.current_step_contacts = []
        self.adjacency_matrix = np.zeros((N, N))
        self.grid = Grid(self.width, self.height, torus=False)
        self.schedule = BaseScheduler(self)  #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, seed=i)
            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 initialize_neighborhood_deltas(self):
        neighborhood_deltas = []
        for x in range(-self.range, self.range + 1):
            for y in range(-self.range, self.range + 1):
                if x**2 + y**2 <= self.range**2:
                    neighborhood_deltas.append((x, y))
        return neighborhood_deltas

    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 get_neighbor_ids(self, position, id):
        x = position[0]
        y = position[1]
        neighbors = []
        for deltas in self.neighborhood_deltas:
            dx = deltas[0]
            dy = deltas[1]

            nx, ny = x + dx, y + dy
            if (not (0 <= nx < self.width) or not (0 <= ny < self.height)):
                continue

            content = self.grid[nx][ny]
            if isinstance(content, Pedestrian) and content.unique_id != id:
                #neighbors += [content.unique_id]
                neighbors += [content.unique_id]

        return neighbors

    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
        '''
        #print('ADJACENCY UPDATE')
        agents = self.schedule.agents
        for i, agent in enumerate(agents):
            neighbor_ids = self.get_neighbor_ids(agent.pos, agent.unique_id)

            for neighbor_id in neighbor_ids:
                if neighbor_id > agent.unique_id:
                    self.adjacency_matrix[agent.unique_id, neighbor_id] += 1

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

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

            self.step()

            self.current_step += 1  #NEW

            for agent in self.schedule.agents:
                self.x_locs[agent.unique_id][i + 1] = agent.pos[0]
                self.y_locs[agent.unique_id][i + 1] = agent.pos[1]

            if i % 100 == 0:
                print(i)
コード例 #52
0
class LanguageModel(Model):
    """ 
    A model that simulates Language Emergence through Self-Organization. For more 
    information check the original paper: https://digital.csic.es/bitstream/10261/127969/1/Spatial%20Vocabulary.pdf
    """

    def __init__(self, n, literate, r, alpha, beta, new_word_rate, antecipated_prob, success_window, width, height):
        self.num_agents = n
        self.literate = literate
        self.change_rate = r
        self.alpha = alpha
        self.beta = beta
        self.new_word_rate = new_word_rate
        self.success_window = success_window
        self.antecipated_prob = antecipated_prob
        # Last arg, if True makes grid toroidal
        self.grid = MultiGrid(width, height, False)
        # At each step, agents move in random order
        self.schedule = RandomActivation(self)
        self.running = True
        self.vocabulary = {}
        self.success_array = []
        self.total_dialogs = 0

        # Initialize a vocabulary. For each meaning it will collect the words used by the agents
        if literate > 0:
            for e in range(self.num_agents):
                self.vocabulary[e] = {STD_WORDS[e]: list(range(literate))}
        else:
            for e in range(self.num_agents):
                self.vocabulary[e] = {}

        # Create agents
        for i in range(self.num_agents):
            if i < self.literate:
                a = LanguageAgent(i, self, True)
            else:
                a = LanguageAgent(i, self, False)
            self.schedule.add(a)
            # Add the agent to a random grid cell
            x = self.random.randrange(self.grid.width)
            y = self.random.randrange(self.grid.height)
            self.grid.place_agent(a, (x, y))

        self.datacollector = DataCollector(
            model_reporters={
                "Average Success (of the last window of dialogs)": compute_graph},
            agent_reporters={"Meanings": "meanings"}
        )

    def step(self):
        # TODO: Refactor the conditional out of this step method.
        self.datacollector.collect(self)
        self.total_dialogs = sum(
            [a.number_of_dialogs for a in self.schedule.agents])
        # show global vocabulary every 50 iterations
        if self.schedule.time % 50 == 0:
            print("Dialog ", self.total_dialogs)
            self.showVocabulary()
        self.schedule.step()

    def showVocabulary(self):
        print("----------------")
        for e in self.vocabulary:
            text = str(e) + ": "
            for word in self.vocabulary[e]:
                text += str(word) + ":" + str(self.vocabulary[e][word]) + " "
            print(text)
        print("----------------")

    def addSuccess(self, success):
        if len(self.success_array) + 1 >= self.success_window:
            del self.success_array[0]

        self.success_array.append(success)
コード例 #53
0
ファイル: model.py プロジェクト: bangtree/mesa
class WolfSheep(Model):
    '''
    Wolf-Sheep Predation Model
    '''

    height = 20
    width = 20

    initial_sheep = 100
    initial_wolves = 50

    sheep_reproduce = 0.04
    wolf_reproduce = 0.05

    wolf_gain_from_food = 20

    grass = False
    grass_regrowth_time = 30
    sheep_gain_from_food = 4

    verbose = False  # Print-monitoring

    description = 'A model for simulating wolf and sheep (predator-prey) ecosystem modelling.'

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

        Args:
            initial_sheep: Number of sheep to start with
            initial_wolves: Number of wolves to start with
            sheep_reproduce: Probability of each sheep reproducing each step
            wolf_reproduce: Probability of each wolf reproducing each step
            wolf_gain_from_food: Energy a wolf gains from eating a sheep
            grass: Whether to have the sheep eat grass for energy
            grass_regrowth_time: How long it takes for a grass patch to regrow
                                 once it is eaten
            sheep_gain_from_food: Energy sheep gain from grass, if enabled.
        '''
        super().__init__()
        # Set parameters
        self.height = height
        self.width = width
        self.initial_sheep = initial_sheep
        self.initial_wolves = initial_wolves
        self.sheep_reproduce = sheep_reproduce
        self.wolf_reproduce = wolf_reproduce
        self.wolf_gain_from_food = wolf_gain_from_food
        self.grass = grass
        self.grass_regrowth_time = grass_regrowth_time
        self.sheep_gain_from_food = sheep_gain_from_food

        self.schedule = RandomActivationByBreed(self)
        self.grid = MultiGrid(self.height, self.width, torus=True)
        self.datacollector = DataCollector(
            {"Wolves": lambda m: m.schedule.get_breed_count(Wolf),
             "Sheep": lambda m: m.schedule.get_breed_count(Sheep)})

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

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

        # Create grass patches
        if self.grass:
            for agent, x, y in self.grid.coord_iter():

                fully_grown = self.random.choice([True, False])

                if fully_grown:
                    countdown = self.grass_regrowth_time
                else:
                    countdown = self.random.randrange(self.grass_regrowth_time)

                patch = GrassPatch(self.next_id(), (x, y), self,
                                   fully_grown, countdown)
                self.grid.place_agent(patch, (x, y))
                self.schedule.add(patch)

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

    def step(self):
        self.schedule.step()
        # collect data
        self.datacollector.collect(self)
        if self.verbose:
            print([self.schedule.time,
                   self.schedule.get_breed_count(Wolf),
                   self.schedule.get_breed_count(Sheep)])

    def run_model(self, step_count=200):

        if self.verbose:
            print('Initial number wolves: ',
                  self.schedule.get_breed_count(Wolf))
            print('Initial number sheep: ',
                  self.schedule.get_breed_count(Sheep))

        for i in range(step_count):
            self.step()

        if self.verbose:
            print('')
            print('Final number wolves: ',
                  self.schedule.get_breed_count(Wolf))
            print('Final number sheep: ',
                  self.schedule.get_breed_count(Sheep))
コード例 #54
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,
                 num_steps=1000,
                 server=True):
        '''
        '''
        self.server = server
        self.num_steps = num_steps
        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

    def run_model(self, n=None):
        if n:
            self.num_steps = n
        if self.server == False:
            for _ in range(self.num_steps):
                self.step()
            return self
        else:
            from .server import server

            server.launch()
コード例 #55
0
ファイル: model.py プロジェクト: Shermjj/schelling-model
class VariableSchelModel(Model):
    def __init__(self,
                 density,
                 width,
                 height,
                 satisfaction_ratio=[0.5, 0.5],
                 group_count=2,
                 group_pct=[0.5]):
        """
        Schelling's Model with a variable number of 'groups'

        :param density: density of the total number of agents, expressed as a percentage of size of model
        :param width: width of the model
        :param height: height of the model
        :param group_count: number of 'groups'
        :param satisfaction_ratio: satisfaction ratios for the different groups, takes an array of length equivalent
                                    to the number of 'groups'
        :param group_pct: group population size as a percentage of total number of agents, takes an array of length one less
                            than the number of groups. Last group percentage is calculated automatically
        """

        if isinstance(density, str):
            print('string')
        if group_count < 2:
            raise ValueError('Group Count cannot be less than 2!')
        if group_count - 1 != len(group_pct):
            raise ValueError(
                'Group Percentages and Group Count mismatch! '
                'Group percentages should be 1 less than the number of groups')
        if len(satisfaction_ratio) != group_count:
            raise ValueError(
                'Satisfaction ratio should be a list with length equivalent to the group count'
            )

        self.num_agents = int(density * (width * height))
        self.running = True
        self.grid = SingleGrid(width, height, True)
        self.schedule = RandomActivation(self)
        self.satisfaction_ratio = satisfaction_ratio
        self.reached_equilibrium = False
        self.agents = []
        self.ratio_sum = 0
        self.lowest_ratio = 1
        self.mean_ratio = 0

        id_offset = 0
        for group in range(group_count):
            if group == group_count - 1:
                # Final count (Percentage isn't explicit, have to calculate,i.e., group_pct length doesnt match ratio)
                pct = 1 - sum(group_pct)
                for i in range(id_offset,
                               id_offset + int(pct * self.num_agents)):
                    a = SchelAgent(i, self, group)
                    self.agents.append(a)
                    id_offset += 1
                    self.schedule.add(a)
                    self.grid.place_agent(a, self.grid.find_empty())
            else:
                for i in range(
                        id_offset,
                        id_offset + int(group_pct[group] * self.num_agents)):
                    a = SchelAgent(i, self, group)
                    self.agents.append(a)
                    id_offset += 1
                    self.schedule.add(a)
                    self.grid.place_agent(a, self.grid.find_empty())

        self.data_collector = DataCollector(model_reporters={
            "mean ratio value":
            lambda model: model.mean_ratio,
            "lowest ratio value":
            lambda model: model.lowest_ratio
        },
                                            agent_reporters={
                                                "coordinates":
                                                lambda agent: agent.pos,
                                                "group":
                                                lambda agent: agent.group,
                                                "satisfaction":
                                                lambda agent: agent.satisfied,
                                                "agent ratio value":
                                                lambda agent: agent.ratio
                                            })
        self.data_collector.collect(self)

    def step(self):
        self.ratio_sum = 0
        self.lowest_ratio = 1.0
        self.reached_equilibrium = True
        self.schedule.step()
        self.mean_ratio = self.ratio_sum / self.num_agents
        self.data_collector.collect(self)
        # Debugging for server charts
        # print(self.mean_ratio)
        # print(self.lowest_ratio)

        # Stops model if model reached equilibrium
        self.running = False if self.reached_equilibrium is True else True
コード例 #56
0
class Modelo(Model):
    #Algunas constantes
    SUCEPTIBLE = 0
    EXPUESTO = 1
    INFECTADO = 2
    RECUPERADO = 3
    salud_to_str = {
        0: 'Suceptible',
        1: 'Expuesto',
        2: 'Infectado',
        3: 'Recuperado'
    }

    def __init__(self, N, city_object, agent_object):
        super().__init__()
        self.num_ind = N
        self.city_object = city_object
        self.agent_object = agent_object
        self.schedule = RandomActivation(self)
        self.crearciudad()
        self.grid = self.ciudad.nodes['aurrera']['espacio']
        self.datacollector = DataCollector(
            model_reporters={
                'Suceptibles': self.conteo_func(self.SUCEPTIBLE),
                'Expuestos': self.conteo_func(self.EXPUESTO),
                'Infectados': self.conteo_func(self.INFECTADO),
                'Recuperados': self.conteo_func(self.RECUPERADO)
            })
        self.conteo_instantaneo = [N, 0, 0, 0]

    def crearciudad(self):
        self.ciudad = self.city_object(self, self.agent_object)
        for ind in self.ciudad.generarindividuos():
            self.schedule.add(ind)

        #Se planta un infectado en la simulación
        self.schedule.agents[0].salud = self.INFECTADO

        #Se crean las casas distribuyendo los individuos
        self.ciudad.crear_hogares()

        #Se agrega una tienda a la ciudad y se conecta con todas las casas
        self.ciudad.crear_nodo('aurrera', tipo='tienda', tamano=25)
        self.ciudad.conectar_a_casas('aurrera')

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

    def conteo(self):
        #Una función para contar los casos actuales en la ciudad
        self.conteo_instantaneo = [0, 0, 0, 0]
        for a in self.schedule.agents:
            self.conteo_instantaneo[a.salud] += 1
        return self.conteo_instantaneo

    def conteo_func(self, tipo):
        def contar(modelo):
            return modelo.conteo_instantaneo[tipo]

        return contar
コード例 #57
0
class CivilViolenceModel(Model):
    """
    Model 1 from "Modeling civil violence: An agent-based computational
    approach," by Joshua Epstein.
    http://www.pnas.org/content/99/suppl_3/7243.full
    Attributes:
        height: grid height
        width: grid width
        citizen_density: approximate % of cells occupied by citizens.
        cop_density: approximate % of calles occupied by cops.
        citizen_vision: number of cells in each direction (N, S, E and W) that
            citizen can inspect
        cop_vision: number of cells in each direction (N, S, E and W) that cop
            can inspect
        legitimacy:  (L) citizens' perception of regime legitimacy, equal
            across all citizens
        max_jail_term: (J_max)
        active_threshold: if (grievance - (risk_aversion * arrest_probability))
            > threshold, citizen rebels
        arrest_prob_constant: set to ensure agents make plausible arrest
            probability estimates
        movement: binary, whether agents try to move at step end
        max_iters: model may not have a natural stopping point, so we set a
            max.

    """

    def __init__(self, height, width, citizen_density, cop_density,
                 citizen_vision, cop_vision, legitimacy,
                 max_jail_term, active_threshold=.1, arrest_prob_constant=2.3,
                 movement=True, max_iters=1000):
        super(CivilViolenceModel, self).__init__()
        self.height = height
        self.width = width
        self.citizen_density = citizen_density
        self.cop_density = cop_density
        self.citizen_vision = citizen_vision
        self.cop_vision = cop_vision
        self.legitimacy = legitimacy
        self.max_jail_term = max_jail_term
        self.active_threshold = active_threshold
        self.arrest_prob_constant = arrest_prob_constant
        self.movement = movement
        self.running = True
        self.max_iters = max_iters
        self.iteration = 0
        self.schedule = RandomActivation(self)
        self.grid = Grid(height, width, torus=True)
        model_reporters = {
            "Quiescent": lambda m: self.count_type_citizens(m, "Quiescent"),
            "Active": lambda m: self.count_type_citizens(m, "Active"),
            "Jailed": lambda m: self.count_jailed(m)}
        agent_reporters = {
            "x": lambda a: a.pos[0],
            "y": lambda a: a.pos[1],
            'breed': lambda a: a.breed,
            "jail_sentence": lambda a: getattr(a, 'jail_sentence', None),
            "condition": lambda a: getattr(a, "condition", None),
            "arrest_probability": lambda a: getattr(a, "arrest_probability",
                                                    None)
        }
        self.dc = DataCollector(model_reporters=model_reporters,
                                agent_reporters=agent_reporters)
        unique_id = 0
        if self.cop_density + self.citizen_density > 1:
            raise ValueError(
                'Cop density + citizen density must be less than 1')
        for (contents, x, y) in self.grid.coord_iter():
            if random.random() < self.cop_density:
                cop = Cop(unique_id, (x, y), vision=self.cop_vision,
                          model=self)
                unique_id += 1
                self.grid[y][x] = cop
                self.schedule.add(cop)
            elif random.random() < (
                    self.cop_density + self.citizen_density):
                citizen = Citizen(unique_id, (x, y),
                                  hardship=random.random(),
                                  regime_legitimacy=self.legitimacy,
                                  risk_aversion=random.random(),
                                  threshold=self.active_threshold,
                                  vision=self.citizen_vision, model=self)
                unique_id += 1
                self.grid[y][x] = citizen
                self.schedule.add(citizen)

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

    @staticmethod
    def count_type_citizens(model, condition, exclude_jailed=True):
        """
        Helper method to count agents by Quiescent/Active.
        """
        count = 0
        for agent in model.schedule.agents:
            if agent.breed == 'cop':
                continue
            if exclude_jailed and agent.jail_sentence:
                continue
            if agent.condition == condition:
                count += 1
        return count

    @staticmethod
    def count_jailed(model):
        """
        Helper method to count jailed agents.
        """
        count = 0
        for agent in model.schedule.agents:
            if agent.breed == 'citizen' and agent.jail_sentence:
                count += 1
        return count
コード例 #58
0
ファイル: model.py プロジェクト: frazur/pabs
class PabsModel(Model):
    """Model your your pandemic"""

    def __init__(self, num_agents=10, width=10, height=10, initial_outbreak_size=0.1, virus_spread_chance=0.4,
                 virus_check_frequency=0.4, recovery_chance=0.3, gain_resistance_chance=0.5, min_infection_duration=5,
                 death_chance=0.5, resistance_duration=-1,
                 movers=0.1):
        self.agents = set()
        self.num_agents = num_agents
        self.width = width
        self.height = height
        self.grid = MultiGrid(height, width, True)
        self.schedule = RandomActivation(self)
        self.initial_outbreak_size = initial_outbreak_size if initial_outbreak_size <= 1.0 else 1.0
        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.resistance_duration = resistance_duration
        self.movers = movers
        self.death_chance = death_chance
        self.datacollector = DataCollector({"Infected": number_infected,
                                            "Susceptible": number_susceptible,
                                            "Resistant": number_resistant,
                                            "Dead": number_dead,
                                            "Total cases": number_total
                                            })

        # Create agents
        for i in range(self.num_agents):
            a = self.create_new_agent(i, min_infection_duration)
            mrn = self.random.random()
            if mrn < movers:
                a.movable = True

            self.schedule.add(a)
            self.agents.add(a)
            # Add the agent to the node
            x = self.random.randrange(self.grid.width)
            y = self.random.randrange(self.grid.height)
            self.grid.place_agent(a, (x, y))

        # # Infect some nodes
        # infected_nodes = self.random.sample(self., 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 create_new_agent(self, i, min_infection_duration):
        rn = self.random.random()
        if rn <= self.initial_outbreak_size:
            a = PabsAgent(i, self, State.INFECTED, self.virus_spread_chance, self.virus_check_frequency,
                          self.recovery_chance, self.gain_resistance_chance, min_infection_duration,
                          self.death_chance,
                          movable=False)
        else:
            a = PabsAgent(i, self, State.SUSCEPTIBLE, self.virus_spread_chance, self.virus_check_frequency,
                          self.recovery_chance, self.gain_resistance_chance, min_infection_duration,
                          self.death_chance,
                          movable=False)
        return a

    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()