예제 #1
0
class WalkerWorld(Model):
    '''
    Random walker world.
    '''
    height = 10
    width = 10

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

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

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

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

    def step(self):
        self.datacollector.collect(self)
        self.schedule.step()
    
    def run_model(self, n):
        for i in range(n):
            self.step()
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)
예제 #4
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()
예제 #5
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()
예제 #6
0
파일: test_grid.py 프로젝트: GeoESW/mesa
class TestMultiGrid(unittest.TestCase):
    '''
    Testing a toroidal MultiGrid
    '''

    torus = True

    def setUp(self):
        '''
        Create a test non-toroidal grid and populate it with Mock Agents
        '''
        width = 3
        height = 5
        self.grid = MultiGrid(width, height, self.torus)
        self.agents = []
        counter = 0
        for x in range(width):
            for y in range(height):
                for i in range(TEST_MULTIGRID[x][y]):
                    counter += 1
                    # Create and place the mock agent
                    a = MockAgent(counter, None)
                    self.agents.append(a)
                    self.grid.place_agent(a, (x, y))

    def test_agent_positions(self):
        '''
        Ensure that the agents are all placed properly on the MultiGrid.
        '''
        for agent in self.agents:
            x, y = agent.pos
            assert agent in self.grid[x][y]

    def test_neighbors(self):
        '''
        Test the toroidal MultiGrid neighborhood methods.
        '''

        neighborhood = self.grid.get_neighborhood((1, 1), moore=True)
        assert len(neighborhood) == 8

        neighborhood = self.grid.get_neighborhood((1, 4), moore=True)
        assert len(neighborhood) == 8

        neighborhood = self.grid.get_neighborhood((0, 0), moore=False)
        assert len(neighborhood) == 4

        neighbors = self.grid.get_neighbors((1, 4), moore=False)
        assert len(neighbors) == 0

        neighbors = self.grid.get_neighbors((1, 4), moore=True)
        assert len(neighbors) == 5

        neighbors = self.grid.get_neighbors((1, 1), moore=False,
                                            include_center=True)
        assert len(neighbors) == 7

        neighbors = self.grid.get_neighbors((1, 3), moore=False, radius=2)
        assert len(neighbors) == 11
 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
예제 #8
0
    def __init__(self, height=20, width=20,
                 initial_sheep=100, initial_wolves=50, sheep_reproduce=0.04,
                 wolf_reproduce=0.05, wolf_gain_from_food=20,
                 grass=False, sheep_gain_from_food=4):
        '''
        Create a new Wolf-Sheep model with the given parameters.

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

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

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

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

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

        self.running = True
예제 #9
0
 def setUp(self):
     '''
     Create a test non-toroidal grid and populate it with Mock Agents
     '''
     self.grid = MultiGrid(3, 5, self.torus)
     self.agents = []
     counter = 0
     for y in range(3):
         for x in range(5):
             for i in range(TEST_MULTIGRID[y][x]):
                 counter += 1
                 # Create and place the mock agent
                 a = MockAgent(counter, None)
                 self.agents.append(a)
                 self.grid.place_agent(a, (x, y))
예제 #10
0
파일: test_grid.py 프로젝트: GeoESW/mesa
 def setUp(self):
     '''
     Create a test non-toroidal grid and populate it with Mock Agents
     '''
     width = 3
     height = 5
     self.grid = MultiGrid(width, height, self.torus)
     self.agents = []
     counter = 0
     for x in range(width):
         for y in range(height):
             for i in range(TEST_MULTIGRID[x][y]):
                 counter += 1
                 # Create and place the mock agent
                 a = MockAgent(counter, None)
                 self.agents.append(a)
                 self.grid.place_agent(a, (x, y))
예제 #11
0
 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))
예제 #12
0
파일: batch_run.py 프로젝트: bangtree/mesa
    def __init__(self, height=grid_h, width=grid_w, init_people=2, rich_threshold=10,
                 reserve_percent=50,):
        self.uid = next(self.id_gen)
        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,
                                           "Model Params": track_params,
                                           "Run": track_run},
                                           agent_reporters={
                                           "Wealth": lambda x: x.wealth})

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

        # create people for the model according to number of people set by user
        for i in range(self.init_people):
            # set x coordinate as a random number within the width of the grid
            x = self.random.randrange(self.width)
            # set y coordinate as a random number within the height of the grid
            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
예제 #13
0
파일: model.py 프로젝트: bangtree/mesa
    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_cg/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 = self.random.randrange(self.width)
            y = self.random.randrange(self.height)
            sugar = self.random.randrange(6, 25)
            metabolism = self.random.randrange(2, 4)
            vision = self.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
        self.datacollector.collect(self)
예제 #14
0
    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()
예제 #15
0
class Epidemic(Model):
    height = 30
    width = 30

    initial_susceptible = 100
    initial_infected = 50
    initial_recovered = 0
    hospital = 1
    mortalityRate = 0.1

    social_isolation = False

    verbose = False

    description = 'A model for simulating spread of Corona Virus using SIR modelling.'

    def __init__(self,
                 height=30,
                 width=30,
                 initial_susceptible=100,
                 initial_infected=50,
                 hospital=1,
                 social_isolation=False,
                 mortalityRate=0.1):
        super().__init__()
        # Set parameters
        self.height = height
        self.width = width
        self.initial_susceptible = initial_susceptible
        self.initial_infected = initial_infected
        self.hospital = hospital
        self.social_isolation = social_isolation
        self.mortalityRate = mortalityRate
        self.schedule = RandomActivationByType(self)
        self.grid = MultiGrid(self.height, self.width, torus=True)
        #Collecting the data for Agents
        self.datacollector = DataCollector({
            "Infected":
            lambda m: m.schedule.get_type_count(Infected),
            "Susceptible":
            lambda m: m.schedule.get_type_count(Susceptible),
            "Recovered":
            lambda m: m.schedule.get_type_count(Recovered)
        })

        #Creating Susceptibles
        for i in range(self.initial_susceptible):
            x = self.random.randrange(self.width)
            y = self.random.randrange(self.height)
            newSusceptible = Susceptible(self.next_id(), (x, y), self,
                                         social_isolation)
            self.grid.place_agent(newSusceptible, (x, y))
            self.schedule.add(newSusceptible)

        #Creating Infected
        for i in range(self.initial_infected):
            x = self.random.randrange(self.width)
            y = self.random.randrange(self.height)
            newInfected = Infected(self.next_id(), (x, y), self,
                                   social_isolation, mortalityRate)
            self.grid.place_agent(newInfected, (x, y))
            self.schedule.add(newInfected)

        #Creating Hospitals
        for i in range(self.hospital):
            x = self.random.randrange(self.width)
            y = self.random.randrange(self.height)
            newHospital = Hospital(self.next_id(), (x, y), self,
                                   social_isolation)
            self.grid.place_agent(newHospital, (x, y))
            self.schedule.add(newHospital)

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

    def step(self):
        self.schedule.step()
        self.datacollector.collect(self)
        if self.verbose:
            print([
                self.schedule.time,
                self.schedule.get_type_count(Infected),
                self.schedule.get_type_count(Susceptible),
                self.schedule.get_type_count(Recovered)
            ])

    def run_model(self, step_count=200):
        if self.verbose:
            print('Initial number infected: ',
                  self.schedule.get_type_count(Infected))
            print('Initial number susceptible: ',
                  self.schedule.get_type_count(Susceptible))
            print('Initial number recovered: ',
                  self.schedule.get_type_count(Recovered))

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

        if self.verbose:
            print('')
            print('Final number infected: ',
                  self.schedule.get_type_count(Infected))
            print('Final number susceptible: ',
                  self.schedule.get_type_count(Susceptible))
            print('Final number recovered: ',
                  self.schedule.get_type_count(Recovered))
예제 #16
0
파일: model.py 프로젝트: nickmalleson/surf
    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
                             }
        )
예제 #17
0
파일: main.py 프로젝트: ysaikai/LFABM
  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
예제 #18
0
class SleepAnimals_sinDataColl(Model):
    '''
    Analysis of the evolution of sleep in animals
    '''

    # Default values
    width               = 40
    height              = 40
    
    number_food_patch   = 40
    number_sleep_patch  = 40

    interdistance_factor    = 0.7
    intradistance_factor    = 0.2

    fp_depletion_tick   = 60
        
    def __init__(self, model_id , genome,width = 40, height = 40, 
                 number_food_patch = 40, number_sleep_patch = 40,
                 interdistance_factor = 0.7, intradistance_factor = 0.2,
                 fp_depletion = 60, sleep_and_food_gainfactor = 1):
        super().__init__()
        
        # Setting Parameters
        self.model_id               = model_id
        self.width                  = width
        self.height                 = height
        self.number_food_patch      = number_food_patch
        self.number_sleep_patch     = number_sleep_patch
        self.interdistance_factor   = interdistance_factor
        self.intradistance_factor   = intradistance_factor
        self.sue_factor             = sleep_and_food_gainfactor
        self.genome = genome

        self.fp_center_x = 0
        self.fp_center_y = 0
        self.sp_center_x = 0
        self.sp_center_y = 0

        self.current_id_food_patch  = 0
        self.current_id_sleep_patch = 0

        self.fp_tick_to_depletion   = fp_depletion

        self.schedule = RandomActivation(self)
        self.grid = MultiGrid(self.width, self.height, torus = False)
        #self.datacollector = DataCollector(
        #   agent_reporters={"Food_fitness"  : lambda a: a.fitness_food,
        #                    "Sleep_fitness" : lambda a: a.fitness_sleep,
        #                    "Fitness"       : lambda a: a.fitness,
        #                    "Mode"          : lambda a: a.mode,
        #                    "Direction"     : lambda a: a.lookingto})
        
        # Picking Centers for Food and Sleep Patches
        self.interdistance = 0
        self.intradistance = 0
        self.findingcenters()

        # Populating Food Patches
        self.available_food_patches = self.grid.get_neighborhood( (self.fp_center_x, self.fp_center_y), False, True, self.intradistance )
        i = 0
        while i < self.number_food_patch:
            self.new_foodpatch()
            i += 1

        # Populating Sleep Patches
        self.available_sleep_patches = self.grid.get_neighborhood( (self.sp_center_x, self.sp_center_y), False, True, self.intradistance )
        i = 0
        while i < self.number_sleep_patch:
            current_spot = random.choice(self.available_sleep_patches)
            if not self.grid.is_cell_empty(current_spot):
                continue
            sleep_patch = SleepPatch( self.next_id_sleeppatch(), self, current_spot )
            self.grid.place_agent( sleep_patch, current_spot )
            i += 1
        
        # Adding Animal to the world
        current_spot = random.choice( self.grid.empties )
        animal = Animal( self.next_id(), self, current_spot, self.genome, self.sue_factor, self.sue_factor )
        self.grid.place_agent( animal, current_spot )
        self.schedule.add( animal )
        

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

    def findingcenters(self):
        max_manhattan_length = self.height + self.width
        self.interdistance = int(max_manhattan_length * self.interdistance_factor)
        self.intradistance = int(max_manhattan_length * self.intradistance_factor)

        fp_center_x = 0
        fp_center_y = 0
        sp_center_x = 0
        sp_center_y = 0
        
        centers_selected = False

        while not centers_selected:
            fp_center_x = random.randrange(self.width)
            fp_center_y = random.randrange(self.height)
            fp_center = (fp_center_x, fp_center_y)
            
            available_spots_food = self.grid.get_neighborhood(fp_center, False, False, self.intradistance)
            if len(available_spots_food) < 80:
                continue
            
            if self.interdistance > 0:
                list_centers_sp = list( set( self.grid.get_neighborhood(fp_center, False, False, self.interdistance + 1) ) - 
                                        set( self.grid.get_neighborhood(fp_center, False, False, self.interdistance - 1) ) )
                if len(list_centers_sp) < 5:
                    continue
            else:
                list_centers_sp = [(fp_center_x,fp_center_y)]

            sp_center = random.choice(list_centers_sp)
            (sp_center_x, sp_center_y) = sp_center

            available_spots_sleep = self.grid.get_neighborhood(sp_center, False, False, self.intradistance)
            if len(available_spots_sleep) < 80:
                continue

            centers_selected = True

        self.fp_center_x = fp_center_x
        self.fp_center_y = fp_center_y
        self.sp_center_x = sp_center_x
        self.sp_center_y = sp_center_y

    def next_id_foodpatch(self):
        """ Return the next unique ID for food patches, increment current_id"""
        self.current_id_food_patch += 1
        a = 'M' + str(self.model_id) + 'F' + str(self.current_id_food_patch)
        return a

    def next_id_sleeppatch(self):
        """ Return the next unique ID for sleep patches, increment current_id"""
        self.current_id_sleep_patch += 1
        a = 'M' + str(self.model_id) + 'S' + str(self.current_id_sleep_patch)
        return a

    def new_foodpatch(self):
        spot_found = False
        while not spot_found :
            current_spot = random.choice(self.available_food_patches)
            if not self.grid.is_cell_empty(current_spot):
                continue
            food_patch = FoodPatch(self.next_id_foodpatch(), self, current_spot, self.fp_tick_to_depletion)
            self.grid.place_agent(food_patch, current_spot)
            spot_found = True

    def arrayRGB_clusters(self):
        available_spots = np.full( (self.grid.width , self.grid.height , 3) , 255)
        for coordinates in self.available_sleep_patches:
            (x, y) = coordinates
            available_spots[x][y]= [100, 0, 150]
        for coordinates in self.available_food_patches:
            (x, y) = coordinates
            available_spots[x][y]= [10, 150, 0]
        return available_spots

    def arrayRGB_display(self):
        RGBdisplay = np.full((self.grid.width, self.grid.height,3), 255)
        for cell in self.grid.coord_iter():
            cell_content, x, y = cell
            a = list(cell_content)
            if len(a) == 0:
                RGBdisplay[x][y] = [255,255,255]
            elif len(a) == 1:
                if      isinstance(a[0], SleepPatch):
                    RGBdisplay[x][y] = [100,0,150]
                elif    isinstance(a[0], FoodPatch):
                    RGBdisplay[x][y] = [10,150,0]
                elif    isinstance(a[0], Animal):
                    RGBdisplay[x][y] = [0,0,0]
                else:
                    pass
            elif len(a) == 2:
                RGBdisplay[x][y] = [0,0,0]
            else:
                pass
        return RGBdisplay

    def array2D_display(self):
        display2D = np.zeros((self.grid.width, self.grid.height))
        for cell in self.grid.coord_iter():
            cell_content, x, y = cell
            a = list(cell_content)
            if len(a) == 0:
                display2D[x][y] = 0
            elif len(a) == 1:
                if isinstance(a[0], SleepPatch):
                    display2D[x][y] = 10
                elif isinstance(a[0], FoodPatch):
                    display2D[x][y] = 20
                elif isinstance(a[0], Animal):
                    display2D[x][y] = 30
                else:
                    pass
            else:
                pass
        return display2D
예제 #19
0
    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,
                 compGregSheep=1,
                 compGregWolf=0):
        '''
        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.compGregSheep = compGregSheep
        self.compGregWolf = compGregWolf

        self.energy_totale = 0

        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)
            self.energy_totale += energy
            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 = random.randrange(self.width)
            y = random.randrange(self.height)
            energy = random.randrange(2 * self.wolf_gain_from_food)
            self.energy_totale += energy
            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 = random.choice([True, False])

                if fully_grown:
                    countdown = self.grass_regrowth_time
                else:
                    countdown = 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)
예제 #20
0
파일: model.py 프로젝트: bangtree/mesa
    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)
예제 #21
0
class RoadNetworkModel(Model):
    description = (
        "A model for simulating Road Network Model"
    )

    def __init__(self, number_of_cars, width, height, is_odd_even_policy_enabled, is_odd_date, policy_range_time):
        # Tick increment
        self.tick = 0

        # Mean Travel Time
        self.mean_travel_time = 0.0

        # Odd-Even Policy Enabled
        self.is_odd_even_policy_enabled = is_odd_even_policy_enabled

        # Set the day of the week
        self.is_odd_date = is_odd_date

        # Set up Spatial dimension
        self.grid = MultiGrid(width, height, True)

        # Set up Temporal dimension
        self.schedule = SimultaneousActivation(self)
        self.running = True

        self.policy_range_time = policy_range_time

        # Set up peak hours
        self.start_peak_hour_1 = PEAK_HOURS["START_PEAK_HOUR_1"] #7
        self.end_peak_hour_1 = PEAK_HOURS["END_PEAK_HOUR_1"] #10
        self.start_peak_hour_2 = PEAK_HOURS["START_PEAK_HOUR_2"] #4
        self.end_peak_hour_2 = PEAK_HOURS["END_PEAK_HOUR_2"] #7

        # Car distribution
        num_highly_active_cars = math.ceil(ACTIVITY_PROPORTION["HIGHLY_ACTIVE"] * number_of_cars)
        num_business_hours_cars = math.ceil(ACTIVITY_PROPORTION["BUSINESS_HOURS"] * number_of_cars)
        num_peak_hours_cars = number_of_cars - (num_highly_active_cars + num_business_hours_cars)

        # generate road
        self.map = MapGenerator()
        roadPosition = self.map.get_road_position()
        for i in range(len(roadPosition)):
            road = Road(i, roadPosition[i], self)
            self.grid.place_agent(road, roadPosition[i])

        ## generate office
        officePosition = self.map.get_office_position()
        for i in range(len(officePosition)):
            office = Office(i, officePosition[i], self)
            self.grid.place_agent(office, officePosition[i])

        # generate residence
        residencePosition = self.map.get_residence_position()
        for i in range(len(residencePosition)):
            residence = Residence(i, residencePosition[i], self)
            self.grid.place_agent(residence, residencePosition[i])

        # generate entertainment
        entertainmentPosition = self.map.get_entertainment_position()
        for i in range(len(entertainmentPosition)):
            entertainment = Entertainment(i, entertainmentPosition[i], self)
            self.grid.place_agent(entertainment, entertainmentPosition[i])

        # generate traffic light
        trafficLightPosition = self.map.get_traffic_light_position()
        for i in range(len(trafficLightPosition)):
            trafficLight = TrafficLight(i, trafficLightPosition[i], self, COLOR["dark_grey"])
            self.grid.place_agent(trafficLight, trafficLightPosition[i])

        # Get source and destination lists
        residence_list = self.map.get_residence_position()
        office = self.map.get_office_position()
        entertainment = self.map.get_entertainment_position()

        # Create destination list based on weekday/weekend proportion
        proportion_of_office_workers = 0.65
        number_of_office_workers = math.ceil(proportion_of_office_workers * number_of_cars)
        number_of_shopper = number_of_cars - number_of_office_workers

        office_list = []
        while len(office_list) <= number_of_office_workers:
            office_list.append(office[self.random.randint(0, len(office) -1)])

        entertainment_list = []
        while len(entertainment_list) <= number_of_shopper:
            entertainment_list.append(entertainment[self.random.randint(0, len(entertainment) - 1)])

        office_entertainment_list = office_list + entertainment_list
        random.shuffle(residence_list)

        layout = self.map.get_layout()
        for i in range(number_of_cars):
            # determine departure and return time based on activity level
            if i <= num_highly_active_cars:
                activity_level = "HIGHLY_ACTIVE"
                departure_time = 0
                return_time = float("inf")
            elif i <= num_business_hours_cars:
                activity_level = "BUSINESS_HOURS"
                departure_time = self.start_peak_hour_1
                return_time = float("inf")
            else:
                activity_level = "PEAK_HOURS"
                departure_time = self.random.randint(self.start_peak_hour_1,self.end_peak_hour_1)
                return_time = self.random.randint(self.start_peak_hour_2,self.end_peak_hour_2)

            plate_number_oddity = self.random.randint(0, 1)

            source_x = residence_list[i][0]
            source_y = residence_list[i][1]
            destination_x = office_entertainment_list[i][0]
            destination_y = office_entertainment_list[i][1]

            state_fringes = self.map.get_fringes(source_x, source_y)
            shortest_distance = float("inf")
            car_direction = state_fringes[0][1]
            for state_fringe in state_fringes:
                current_direction =  state_fringe[1] # "^" "v" ">" "<"
                if current_direction in DIRECTION:
                    temp_x = state_fringe[0][0] + DIRECTION[current_direction][0]
                    temp_y = state_fringe[0][1] + DIRECTION[current_direction][1]

                    newDist = get_euclidean_distance((temp_x, temp_y), (destination_x, destination_y))
                    if newDist < shortest_distance:
                        shortest_distance = newDist
                        car_direction = current_direction

            # all cars are initialised as IDLE
            car_state = "IDLE"

            car = Car(i, plate_number_oddity,
                        (source_x,source_y),
                        (destination_x,destination_y),
                        car_direction,
                        car_state,
                        departure_time,
                        return_time,
                        activity_level,
                        self)

            self.grid.place_agent(car, (source_x,source_y))
            self.schedule.add(car)

        # Data Collection
        self.datacollector = DataCollector({
            "Idle": number_idle_cars,
            "Move": number_move_cars,
            "Finished": number_finished_cars,
            "SimulationMinutes": simulation_minutes,
            "ToOffice": number_office,
            "ToResidence": number_residence,
            "MeanTravelTime": mean_travel_time,
            "StdTravelTime": std_travel_time
        })
        self.datacollector.collect(self)

    def step(self):
        self.schedule.step()
        self.tick += 1
        self.mean_travel_time = np.mean([cell.travel_time for j in range(100) for i in range(100) for cell in self.grid.iter_cell_list_contents((i,j))
            if type(cell) is Car])
        self.datacollector.collect(self)

        # After a day (1440 minutes), stop the simulation
        if self.tick >= 1440:
            self.running = False

    def is_plate_number_oddity_allowed(self, plate_number_oddity=0, xy=(0, 0)):
        x, y = xy
        # implement odd even policy for avenue only.
        if(self.map.is_avenue(x, y)):
            if(self.is_odd_date == True): # date is odd
                if(plate_number_oddity % 2 == 1): # plate is odd
                    return True
                else:
                    return False
            else: # date is even
                if(plate_number_oddity % 2 == 0): # plate is even
                    return True
                else:
                    return False
        else:
            return True

    def is_odd_even_policy_time(self):
        #1 day == 1440 minutes
        day_tick = self.tick % 1440

        if self.policy_range_time == '7_10_and_16_19':
            if day_tick >= (7 * 60) and day_tick <= (10 * 60):
                return True
            elif day_tick >= (16 * 60) and day_tick <= (19 * 60):
                return True
            else:
                return False
        elif self.policy_range_time == '8_11_and_17_20':
            if day_tick >= (8 * 60) and day_tick <= (11 * 60):
                return True
            elif day_tick >= (17 * 60) and day_tick <= (20 * 60):
                return True
            else:
                return False
        elif self.policy_range_time == '6_9_and_15_18':
            if day_tick >= (6 * 60) and day_tick <= (9 * 60):
                return True
            elif day_tick >= (15 * 60) and day_tick <= (18 * 60):
                return True
            else:
                return False
        elif self.policy_range_time == '8_9_and_17_18':
            if day_tick >= (8 * 60) and day_tick <= (9 * 60):
                return True
            elif day_tick >= 17 * 60 and day_tick <= 18 * 60:
                return True
            else:
                return False
        elif self.policy_range_time == '6_11_and_15_20':
            if day_tick >= (6 * 60) and day_tick <= (11 * 60):
                return True
            elif day_tick >= (15 * 60) and day_tick <= (20 * 60):
                return True
            else:
                return False
        else:
            return False
예제 #22
0
    def __init__(self,
                 elevators=4,
                 floors=16,
                 a=0,
                 passager_flow='up',
                 controller='baseline',
                 alpha=1,
                 beta=1,
                 theta=1,
                 output_file=False):
        super().__init__()
        #self.running = True
        self.num_elevators = int(elevators)
        self.num_floors = int(floors)
        self.grid = MultiGrid(int(elevators) + 1, (int(floors)), False)
        self.schedule = BaseScheduler(self)
        self.a = a
        self.between_floors = 3
        self.verbose = False  # Print-monitoring
        self.floors = []
        self.elevators = []
        self.attended = []
        self.passager_flow = passager_flow
        self.simulation = self.get_simulation(passager_flow)
        self.alpha = alpha
        self.beta = beta
        self.theta = theta
        self.controller = controller
        self.gerado_saida = not output_file

        # Create elevators
        for i in range(self.num_elevators):
            # Add the agent to a random grid cell
            a = ElevatorAgent("e_" + str(i), (i + 1, 0), self, self.alpha,
                              self.beta, self.theta)
            #seta todos UP
            #
            #estado de todos é 5 (0 =fora d servico, 1 = parado com viagem para baixo, 2 = parado com viagem para cima, 3 = sem missao, 4 = descendo, 5 = subindo)
            self.schedule.add(a)
            self.elevators.append(a)
            self.grid.place_agent(a, (i + 1, 0))

        # Create floors
        for i in range(self.num_floors):
            a = FloorAgent("f_" + str(i), i, (0, i), self)
            self.schedule.add(a)
            self.grid.place_agent(a, (0, i))
            self.floors.append(a)

        #tempo medio de espera
        #tempo medio de atendimento
        #tempo medio global
        #numero de passageiros em cada andar
        #numero de passageiros em cada carro
        self.datacollector = DataCollector(
            model_reporters={
                "Attended": get_attended,
                "Floors": get_floors,
                "Cars": get_cars,
                "JourneyTime": get_journey_time,
                "WaitingTime": get_waiting_time,
                "TotalTime": get_total_time,
                "WaitingFloor": get_waiting_floor
            })
예제 #23
0
class Modelo(Model):
    """
    A model with some number of agents.
    """
    atendidos = 0
    num_elevators = 1
    num_floors = 15
    a = 1
    floors = []
    elevators = []
    attended = []
    gerado_saida = False

    def __init__(self,
                 elevators=4,
                 floors=16,
                 a=0,
                 passager_flow='up',
                 controller='baseline',
                 alpha=1,
                 beta=1,
                 theta=1,
                 output_file=False):
        super().__init__()
        #self.running = True
        self.num_elevators = int(elevators)
        self.num_floors = int(floors)
        self.grid = MultiGrid(int(elevators) + 1, (int(floors)), False)
        self.schedule = BaseScheduler(self)
        self.a = a
        self.between_floors = 3
        self.verbose = False  # Print-monitoring
        self.floors = []
        self.elevators = []
        self.attended = []
        self.passager_flow = passager_flow
        self.simulation = self.get_simulation(passager_flow)
        self.alpha = alpha
        self.beta = beta
        self.theta = theta
        self.controller = controller
        self.gerado_saida = not output_file

        # Create elevators
        for i in range(self.num_elevators):
            # Add the agent to a random grid cell
            a = ElevatorAgent("e_" + str(i), (i + 1, 0), self, self.alpha,
                              self.beta, self.theta)
            #seta todos UP
            #
            #estado de todos é 5 (0 =fora d servico, 1 = parado com viagem para baixo, 2 = parado com viagem para cima, 3 = sem missao, 4 = descendo, 5 = subindo)
            self.schedule.add(a)
            self.elevators.append(a)
            self.grid.place_agent(a, (i + 1, 0))

        # Create floors
        for i in range(self.num_floors):
            a = FloorAgent("f_" + str(i), i, (0, i), self)
            self.schedule.add(a)
            self.grid.place_agent(a, (0, i))
            self.floors.append(a)

        #tempo medio de espera
        #tempo medio de atendimento
        #tempo medio global
        #numero de passageiros em cada andar
        #numero de passageiros em cada carro
        self.datacollector = DataCollector(
            model_reporters={
                "Attended": get_attended,
                "Floors": get_floors,
                "Cars": get_cars,
                "JourneyTime": get_journey_time,
                "WaitingTime": get_waiting_time,
                "TotalTime": get_total_time,
                "WaitingFloor": get_waiting_floor
            })

    def step(self):
        #aqui vai a logica do fluxo de passageiros
        #chegada de passageiros

        #lista de botoes
        self.schedule.step()
        print(self.schedule.get_agent_count)
        self.datacollector.collect(self)

        #se nao tem mais passageiros pra chegar nem pra ser atendido
        #cria um csv com os dados
        #so uma vez
        if not self.gerado_saida and self.schedule.time > 1198:
            self.gerado_saida = True
            save_file_results(self)

    def run_model(self, step_count=1200):

        for i in range(step_count):
            self.step()
            print("step: ", i)

    def get_simulation(self, fluxo):
        #le o arquivo de fluxos
        # simulação:

        if fluxo == 'up':
            with open('resources/traff_up.txt', 'r') as f:
                traff_up = json.loads(f.read())
                return traff_up

        elif fluxo == 'dp':
            with open('resources/traff_dp.txt', 'r') as f:
                traff_dp = json.loads(f.read())
                return traff_dp

        elif fluxo == 'du':
            with open('resources/traff_du.txt', 'r') as f:
                traff_du = json.loads(f.read())
                return traff_du

        else:
            with open('resources/traff_poisson.txt', 'r') as f:
                traff_poisson = json.loads(f.read())
                return traff_poisson
예제 #24
0
class board(Model):

    def __init__(self,num_wolverines,num_spartans,num_buckeyes, height = 40, width = 40):
        '''Initializes the board and randomly puts spartans and wolverines in
        the board. This uses a multigrid and rolling boundary conditions'''
        self.num_wolverines = num_wolverines
        self.num_spartans = num_spartans
        self.num_buckeyes = num_buckeyes
        self.height = height
        self.width = width

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

        #Creates Wolverines
        for i in range(self.num_wolverines):
            x = random.randrange(self.width)
            y = random.randrange(self.height)
            wolverine = Wolverine((x, y), self)
            self.grid.place_agent(wolverine, (x, y))
            self.schedule.add(wolverine)

        # Create Spartans
        for i in range(self.num_spartans):
            x = random.randrange(self.width)
            y = random.randrange(self.height)
            spartan = Spartan((x, y), self)
            self.grid.place_agent(spartan, (x, y))
            self.schedule.add(spartan)

         # Create Buckeyes
        for i in range(self.num_spartans):
            x = random.randrange(self.width)
            y = random.randrange(self.height)
            buckeye = Buckeye((x, y), self)
            self.grid.place_agent(buckeye, (x, y))
            self.schedule.add(buckeye)

        self.running = True

    def step(self):
        '''Goes through the step functions found in the agents'''

        self.schedule.step()

    def run_model(self,num_iterations):
        '''Just iterates over the step for a given number of times and shows
        the colormap, this is mostly just for testing and the final result
        should include animation'''

        for i in range(num_iterations):
            self.step()
            self.print_model()

    def print_model(self):
        '''This function prints and does some operations in the function,
        specifically it goes through each square and if a wolverine and
        spartan are in the same square, it initiates combat along with putting
        the concentration of entities on a colormap, which is from my
        jupyter notebook'''
        agent_counts = np.zeros((self.grid.width, self.grid.height))
        self.total_count = 0
        for cell in self.grid.coord_iter():
            cell_content, x, y = cell
            self.total_count+=len(cell_content)
            cell_cont = list(cell_content)
            #This is statement goes through each cell and sees if there is a
            #spartan and wolverine in the same square, then initiates combat
            if cell_cont!=[]:
                #Have the class objects return their name and if it meets the
                #criteria, moves to combat
                if any(x.name() == "Spartan" for x in cell_cont) and \
                any(x.name() == "Wolverine" for x in cell_cont):
                    killed = False
                    for j in cell_content:
                        if j.name()=="Spartan":
                            killed = j.kill_wolverine()
                            break
                    if killed:
                        for i in cell_content:
                            if i.name() == "Wolverine":
                                j.add_food_from_kill(i.food_contents())
                                i.wolverine_killed()
                                print('A wolverine has just been killed')
                                break
                if any(x.name() == "Buckeye" for x in cell_cont) and \
                any(x.name() == "Wolverine" for x in cell_cont):
                    killed = False
                    for j in cell_content:
                        if j.name()=="Buckeye":
                            killed = j.kill_wolverine()
                            break
                    if killed:
                        for i in cell_content:
                            if i.name() == "Wolverine":
                                j.add_food_from_kill(i.food_contents())
                                i.wolverine_killed()
                                print('A wolverine has just been killed')
                                break
                if any(x.name() == "Spartan" for x in cell_cont) and \
                any(x.name() == "Buckeye" for x in cell_cont):
                    killed = False
                    for j in cell_content:
                        if j.name()=="Spartan":
                            killed = j.kill_wolverine()
                            break
                    if killed:
                        for i in cell_content:
                            if i.name() == "Buckeye":
                                j.add_food_from_kill(i.food_contents())
                                i.buckeye_killed()
                                print('A buckeye has just been killed')
                                break

            agent_count = len(cell_content)
            agent_counts[x][y] = agent_count
        print(self.total_count)
        plt.imshow(agent_counts, interpolation='nearest')
        plt.colorbar()

        plt.show()
예제 #25
0
    def __init__(self, shock_period, shock_duration, shock_rate, N_cities, N_a,
                 nc_rate, width, height):

        #canvas info
        self.width = width
        self.height = height

        #sim boilerplate
        self.grid = MultiGrid(width, height, True)
        self.schedule = RandomActivation(self)
        self.running = True

        self.num_nc = 0  #counts number of applicants
        self.num_azc = N_a  #number of AZC in sim
        self.nc_rate = nc_rate  #rate of inflow of newcomers
        self.num_cities = N_cities  #number of cities in sim
        self.num_buildings = 3

        self.num_activity_centers = 2
        self.num_activities_per_center = 2
        self.num_per_step = 10

        self.num_activity_centers = 2
        self.num_activities_per_center = 2

        #initialize shock values
        self.shock_period = shock_period  #how often does shock occur
        self.shock_duration = shock_duration  #how long does shock last
        self._shock_duration = shock_duration  #current position in shock
        self.shock_rate = shock_rate  #amt of increase during shock
        self.shock = False  #shock flag
        self.number_added = 1  #base rate of influx
        self.number_shocks = 4
        self.shock_growth = 2

        #dict of probabilities of first/second decision success rates by country
        self.specs = {}
        # list of multinomial probabilities for countries
        self.country_multinomial = []
        # list of shock distributions for countries related to adding newcomers
        self.country_shock_dist = []
        # list of countries
        self.country_list = []
        with open("country-input.csv") as csvfile:
            reader = csv.DictReader(csvfile)
            for row in reader:
                decisionList = []
                decisionList.append(float(row['DecisionA']))
                decisionList.append(float(row['DecisionB']))
                self.specs[row['Country']] = decisionList
                self.country_shock_dist.append(row['ShockDist'])
                self.country_list.append(row['Country'])
                self.country_multinomial.append(row['Multinomial'])

        self.country_count = np.zeros(
            len(self.country_list
                ))  #keeps track of how many applicants from each country
        self.country_success = np.zeros(len(self.country_list))
        self.current_country_index = -1

        #records capacitiy of each AZC type
        self.datacollector = DataCollector(model_reporters={
            'Cap - Extended-AS': calc_extended_as,
            'Cap - AS': calc_as
        })

        #records success rates of each country of origin using current_country_index
        #which is manipulated in sr_country
        sr_functions = {}
        for i in range(0, len(self.country_list)):
            self.current_country_index = i
            sr_functions[self.country_list[
                self.current_country_index]] = sr_country

        self.sr = DataCollector(model_reporters=sr_functions)

        self.capacity_dc = DataCollector(model_reporters={
            'Current Capacity': coa_occ,
            'Projected Capacity': coa_proj
        })

        #Ter apel
        ta_pos = (int(self.width / 2), int(self.height / 6 * 5))
        ta_id = self.num_cities + 1
        ter_apel = City(self.num_cities + 1, self, ta_pos)
        ta_coa = COA(ta_id, self, ter_apel)
        ta_coa.ta = True
        self.schedule.add(ta_coa)
        ta_ind = IND(ta_id, self, ter_apel)
        self.schedule.add(ta_ind)
        ta_azc = AZC(ta_id, self, 'edp', ta_pos, ta_coa)
        ta_azc.ta = True
        ta_coa.azcs.add(ta_azc)
        ta_coa.capacities[ta_azc] = ta_azc.occupancy
        self.schedule.add(ta_azc)
        self.grid.place_agent(ta_azc, ta_pos)
        self.ter_apel = ta_azc

        #add activities
        self.test_activity = Football(0, self, 5)
        self.schedule.add(self.test_activity)

        #generate cities

        for city in range(self.num_cities):
            space_per_city = int(self.width / self.num_cities)

            orientation_x = int(
                space_per_city / 2 + city * space_per_city +
                int(space_per_city / self.num_azc / 2))  #center point for city
            pos = (orientation_x, int(self.height / 2))  #placeholder position
            city_size = np.random.uniform(low=0, high=1)
            city_is_big = False
            if city_size > 0.70:
                city_is_big = True
            current_city = City(city, self, pos,
                                city_is_big)  #instantiates city
            #add COA
            current_coa = COA(city, self, current_city)
            current_city.coa = current_coa
            self.schedule.add(current_coa)
            self.grid.place_agent(current_coa,
                                  (pos[0], int(self.height / 3 * 2)))
            current_ind = IND(city, self, current_city)
            self.schedule.add(current_ind)
            current_coa.IND = current_ind
            current_ind.coa = current_coa
            #adds city to schedule n grid
            self.schedule.add(current_city)
            self.grid.place_agent(current_city, (current_city.pos))

            #azc location essentials
            space_per_azc = int(space_per_city / self.num_azc)
            azc_starting_point = orientation_x - (.5 * space_per_city)
            num_activity_centers_added = 0
            # Create AZCs
            for i in range(self.num_azc):
                '''
                if i == 0:
                    occupant_type = 'edp'   # ter apel
                '''
                if i < self.num_azc - 2:
                    occupant_type = 'as'  # standard AZC
                elif i == self.num_azc - 2:
                    occupant_type = 'as_ext'  # extended procedure AZC
                else:
                    occupant_type = 'tr'  # 'Housing' for those with

                #place evenly
                x = int(azc_starting_point + i * space_per_azc)
                y = int(self.height * .5)

                a = AZC(i, self, occupant_type, (x, y),
                        current_coa)  #instantiate
                self.schedule.add(a)  #add in time
                self.grid.place_agent(a, (x, y))  #add in spaace
                current_city.buildings.add(a)
                if a.occupant_type != 'tr':
                    current_coa.azcs.add(a)
                    current_coa.capacities[a] = a.occupancy

                if a.occupant_type == 'tr':
                    current_city.social_housing = a

                #add viz
                v = AZC_Viz(self, a)
                self.schedule.add(v)
                self.grid.place_agent(v, v.pos)

            #create civilian buildings

            y = int(self.height / 5)
            space_per_building = space_per_city / self.num_buildings
            row_size = 15

            if city == 0:
                x = int(azc_starting_point + .5 * space_per_building)
                current = Hotel(self.num_buildings + 1, self, (x, y), 1000)
                current_city.buildings.add(current)
                current.city = current_city
                self.grid.place_agent(current, (x, y))
                self.schedule.add(current)

                empty = Empty(self.num_buildings + 1, self,
                              (int(x + space_per_building), y), 100)
                current_city.buildings.add(empty)
                empty.city = current_city
                self.grid.place_agent(empty, (int(x + space_per_building), y))
                self.schedule.add(empty)

            for bdg in range(city * self.num_buildings):

                x = int(azc_starting_point + (bdg % 3) * space_per_building)

                if bdg == 0:

                    current = Hotel(bdg, self, (x, y), 1000)
                    current_city.buildings.add(current)
                    current.city = current_city
                    self.grid.place_agent(current, (x, y))
                    self.schedule.add(current)
                else:
                    empty = Empty(bdg, self, (x, y - row_size * int(bdg / 3)),
                                  100 * bdg)
                    current_city.buildings.add(empty)
                    empty.city = current_city
                    self.grid.place_agent(empty,
                                          (x, y - row_size * int(bdg / 3)))
                    self.schedule.add(empty)
예제 #26
0
class HumanitarianLogistics(Model):
    """A model with: number of azc
        rate of newcomer arrival
        dimensions width and height"""
    def __init__(self, shock_period, shock_duration, shock_rate, N_cities, N_a,
                 nc_rate, width, height):

        #canvas info
        self.width = width
        self.height = height

        #sim boilerplate
        self.grid = MultiGrid(width, height, True)
        self.schedule = RandomActivation(self)
        self.running = True

        self.num_nc = 0  #counts number of applicants
        self.num_azc = N_a  #number of AZC in sim
        self.nc_rate = nc_rate  #rate of inflow of newcomers
        self.num_cities = N_cities  #number of cities in sim
        self.num_buildings = 3

        self.num_activity_centers = 2
        self.num_activities_per_center = 2
        self.num_per_step = 10

        self.num_activity_centers = 2
        self.num_activities_per_center = 2

        #initialize shock values
        self.shock_period = shock_period  #how often does shock occur
        self.shock_duration = shock_duration  #how long does shock last
        self._shock_duration = shock_duration  #current position in shock
        self.shock_rate = shock_rate  #amt of increase during shock
        self.shock = False  #shock flag
        self.number_added = 1  #base rate of influx
        self.number_shocks = 4
        self.shock_growth = 2

        #dict of probabilities of first/second decision success rates by country
        self.specs = {}
        # list of multinomial probabilities for countries
        self.country_multinomial = []
        # list of shock distributions for countries related to adding newcomers
        self.country_shock_dist = []
        # list of countries
        self.country_list = []
        with open("country-input.csv") as csvfile:
            reader = csv.DictReader(csvfile)
            for row in reader:
                decisionList = []
                decisionList.append(float(row['DecisionA']))
                decisionList.append(float(row['DecisionB']))
                self.specs[row['Country']] = decisionList
                self.country_shock_dist.append(row['ShockDist'])
                self.country_list.append(row['Country'])
                self.country_multinomial.append(row['Multinomial'])

        self.country_count = np.zeros(
            len(self.country_list
                ))  #keeps track of how many applicants from each country
        self.country_success = np.zeros(len(self.country_list))
        self.current_country_index = -1

        #records capacitiy of each AZC type
        self.datacollector = DataCollector(model_reporters={
            'Cap - Extended-AS': calc_extended_as,
            'Cap - AS': calc_as
        })

        #records success rates of each country of origin using current_country_index
        #which is manipulated in sr_country
        sr_functions = {}
        for i in range(0, len(self.country_list)):
            self.current_country_index = i
            sr_functions[self.country_list[
                self.current_country_index]] = sr_country

        self.sr = DataCollector(model_reporters=sr_functions)

        self.capacity_dc = DataCollector(model_reporters={
            'Current Capacity': coa_occ,
            'Projected Capacity': coa_proj
        })

        #Ter apel
        ta_pos = (int(self.width / 2), int(self.height / 6 * 5))
        ta_id = self.num_cities + 1
        ter_apel = City(self.num_cities + 1, self, ta_pos)
        ta_coa = COA(ta_id, self, ter_apel)
        ta_coa.ta = True
        self.schedule.add(ta_coa)
        ta_ind = IND(ta_id, self, ter_apel)
        self.schedule.add(ta_ind)
        ta_azc = AZC(ta_id, self, 'edp', ta_pos, ta_coa)
        ta_azc.ta = True
        ta_coa.azcs.add(ta_azc)
        ta_coa.capacities[ta_azc] = ta_azc.occupancy
        self.schedule.add(ta_azc)
        self.grid.place_agent(ta_azc, ta_pos)
        self.ter_apel = ta_azc

        #add activities
        self.test_activity = Football(0, self, 5)
        self.schedule.add(self.test_activity)

        #generate cities

        for city in range(self.num_cities):
            space_per_city = int(self.width / self.num_cities)

            orientation_x = int(
                space_per_city / 2 + city * space_per_city +
                int(space_per_city / self.num_azc / 2))  #center point for city
            pos = (orientation_x, int(self.height / 2))  #placeholder position
            city_size = np.random.uniform(low=0, high=1)
            city_is_big = False
            if city_size > 0.70:
                city_is_big = True
            current_city = City(city, self, pos,
                                city_is_big)  #instantiates city
            #add COA
            current_coa = COA(city, self, current_city)
            current_city.coa = current_coa
            self.schedule.add(current_coa)
            self.grid.place_agent(current_coa,
                                  (pos[0], int(self.height / 3 * 2)))
            current_ind = IND(city, self, current_city)
            self.schedule.add(current_ind)
            current_coa.IND = current_ind
            current_ind.coa = current_coa
            #adds city to schedule n grid
            self.schedule.add(current_city)
            self.grid.place_agent(current_city, (current_city.pos))

            #azc location essentials
            space_per_azc = int(space_per_city / self.num_azc)
            azc_starting_point = orientation_x - (.5 * space_per_city)
            num_activity_centers_added = 0
            # Create AZCs
            for i in range(self.num_azc):
                '''
                if i == 0:
                    occupant_type = 'edp'   # ter apel
                '''
                if i < self.num_azc - 2:
                    occupant_type = 'as'  # standard AZC
                elif i == self.num_azc - 2:
                    occupant_type = 'as_ext'  # extended procedure AZC
                else:
                    occupant_type = 'tr'  # 'Housing' for those with

                #place evenly
                x = int(azc_starting_point + i * space_per_azc)
                y = int(self.height * .5)

                a = AZC(i, self, occupant_type, (x, y),
                        current_coa)  #instantiate
                self.schedule.add(a)  #add in time
                self.grid.place_agent(a, (x, y))  #add in spaace
                current_city.buildings.add(a)
                if a.occupant_type != 'tr':
                    current_coa.azcs.add(a)
                    current_coa.capacities[a] = a.occupancy

                if a.occupant_type == 'tr':
                    current_city.social_housing = a

                #add viz
                v = AZC_Viz(self, a)
                self.schedule.add(v)
                self.grid.place_agent(v, v.pos)

            #create civilian buildings

            y = int(self.height / 5)
            space_per_building = space_per_city / self.num_buildings
            row_size = 15

            if city == 0:
                x = int(azc_starting_point + .5 * space_per_building)
                current = Hotel(self.num_buildings + 1, self, (x, y), 1000)
                current_city.buildings.add(current)
                current.city = current_city
                self.grid.place_agent(current, (x, y))
                self.schedule.add(current)

                empty = Empty(self.num_buildings + 1, self,
                              (int(x + space_per_building), y), 100)
                current_city.buildings.add(empty)
                empty.city = current_city
                self.grid.place_agent(empty, (int(x + space_per_building), y))
                self.schedule.add(empty)

            for bdg in range(city * self.num_buildings):

                x = int(azc_starting_point + (bdg % 3) * space_per_building)

                if bdg == 0:

                    current = Hotel(bdg, self, (x, y), 1000)
                    current_city.buildings.add(current)
                    current.city = current_city
                    self.grid.place_agent(current, (x, y))
                    self.schedule.add(current)
                else:
                    empty = Empty(bdg, self, (x, y - row_size * int(bdg / 3)),
                                  100 * bdg)
                    current_city.buildings.add(empty)
                    empty.city = current_city
                    self.grid.place_agent(empty,
                                          (x, y - row_size * int(bdg / 3)))
                    self.schedule.add(empty)

    def house(self, newcomer):

        #find building for newcomers legal status
        eligible_buildings = [
            x for x in self.schedule.agents
            if type(x) is AZC and x.occupant_type == newcomer.ls
        ]

        #take first one, in future, evaluate buildings on some criteria
        destination = eligible_buildings[0]
        house_loc = destination.pos  #where is it

        if newcomer.ls is not 'edp':
            newcomer.loc.occupancy -= 1  #reduce occupance of prev building

        #add noise so agents don't overlap
        x = house_loc[0] + np.random.randint(-20, 20)
        y = house_loc[1] + np.random.randint(-20, 20)

        self.grid.move_agent(newcomer, (x, y))  #place

        destination.occupants.add(newcomer)  #add agent to building roster
        newcomer.loc = destination  #update agent location

        destination.occupancy += 1  #update occupancy

    def Remove(self, agent):

        agent.loc.occupancy -= 1  #reduce occupancy of building
        agent.loc.occupants.remove(agent)

        #remove from time n space
        self.schedule.remove(agent)
        self.grid.remove_agent(agent)

    def shock_distribution(self):
        #draws a random discrete number from multinomial distribution
        country = np.random.multinomial(1, self.country_shock_dist, size=1)

        # turns that distribution into a number
        country = np.where(country == 1)[1][0]

        # assigns that number to a country
        country_of_origin = self.country_list[country]
        return country_of_origin

    def country_distribution(self):
        #draws a random discrete number from multinomial distribution
        country = np.random.multinomial(1, self.country_multinomial, size=1)

        # turns that distribution into a number
        country = np.where(country == 1)[1][0]

        # updates country count
        self.country_count[country] += 1

        # assigns that number to a country
        country_of_origin = self.country_list[country]
        return country_of_origin

    def addNewcomer(self, shock, country_of_origin):

        #increase count
        self.num_nc += 1

        if not shock:

            country_of_origin = self.country_distribution()

        else:

            self.country_count[self.country_list.index(country_of_origin)] += 1

        x = np.random.randint(0, 10, dtype='int')
        y = np.random.randint(0, 10, dtype='int')
        #define newcomer
        r = Newcomer(self.num_nc, self, country_of_origin, (x, y))
        self.schedule.add(r)
        self.grid.place_agent(r, r.pos)

        #find coa
        coa = [x for x in self.schedule.agents if type(x) is COA][0]

        coa.intake(r)  #place n ter apel
        coa.newcomers.add(r)  #adds NC to coa's list of residents
        r.coa = coa  #likewise for the newcomer

    def step(self):
        self.schedule.step()
        self.datacollector.collect(self)  #collects occupancy data
        self.sr.collect(self)  #collects success rate data
        self.capacity_dc.collect(self)

        if self.schedule.steps % self.shock_period == 0:
            self.shock = True
            self.shock_counter = 0

        if self.shock:

            #if self._shock_duration > (self._shock_duration / 2):
            #    self.number_added += self.shock_rate
            #else:
            #    self.number_added -= self.shock_rate
            self.number_added += self.shock_rate
            for i in range(int(self.number_added)):

                shock_country = self.shock_distribution()

                self.addNewcomer(
                    True, shock_country
                )  # currently in data file all shocks come from Syria
                self.shock_counter += 1
            self._shock_duration -= 1

            if self._shock_duration == 0:

                self.shock = False
                self._shock_duration = self.shock_duration
                self.number_added = 1

                self.shock_counter = 0
                self.shock_rate = self.shock_rate * self.shock_growth
        else:

            #adds newcomers to simuluation at a given rate
            if uniform(0, 1) < self.nc_rate:
                for i in range(self.num_per_step):

                    self.addNewcomer(False, None)
예제 #27
0
    def __init__(self, num_agents, width, height, kmob, repscaling, rate_inbound, age_mortality, 
                 sex_mortality, age_distribution, sex_distribution, prop_initial_infected, 
                 proportion_asymptomatic, proportion_severe, avg_incubation_time, avg_recovery_time, prob_contagion,
                 proportion_isolated, day_start_isolation, days_isolation_lasts, after_isolation, prob_isolation_effective, social_distance,
                 day_distancing_start, days_distancing_lasts, proportion_detected, day_testing_start, days_testing_lasts, 
                 new_agent_proportion, new_agent_start, new_agent_lasts, new_agent_age_mean, new_agent_prop_infected,
                 day_tracing_start, days_tracing_lasts, stage_value_matrix, test_cost, alpha_private, alpha_public, proportion_beds_pop, dummy=0):
        self.running = True
        self.num_agents = num_agents
        self.grid = MultiGrid(width, height, True)
        self.schedule = RandomActivation(self)
        self.age_mortality = age_mortality
        self.sex_mortality = sex_mortality
        self.age_distribution = age_distribution
        self.sex_distribution = sex_distribution
        self.stage_value_dist = stage_value_matrix
        self.test_cost = test_cost
        self.stepno = 0
        self.alpha_private = alpha_private
        self.alpha_public = alpha_public

        # Number of 15 minute dwelling times per day
        self.dwell_15_day = 96

        # Average dwelling units
        self.avg_dwell = 4

        # The average incubation period is 5 days, which can be changed
        self.avg_incubation = int(round(avg_incubation_time * self.dwell_15_day))

        # Probability of contagion after exposure in the same cell
        # Presupposes a person centered on a 1.8 meter radius square.
        # We use a proxy value to account for social distancing.
        # Representativeness modifies the probability of contagion by the scaling factor
        if repscaling < 2:
            self.repscaling = 1
        else:
            self.repscaling = (np.log(repscaling)/np.log(1.96587))
        
        self.prob_contagion_base = prob_contagion / self.repscaling

        # Mobility constant for geographic rescaling
        self.kmob = kmob

        # Proportion of daily incoming infected people from other places
        self.rate_inbound = rate_inbound/self.dwell_15_day

        # Probability of contagion due to residual droplets: TODO
        self.prob_contagion_places = 0.001

        # Probability of being asymptomatic, contagious
        # and only detectable by testing
        self.prob_asymptomatic = proportion_asymptomatic

        # Average recovery time
        self.avg_recovery = avg_recovery_time * self.dwell_15_day

        # Proportion of detection. We use the rate as reference and
        # activate testing at the rate and specified dates
        self.testing_rate = proportion_detected/(days_testing_lasts  * self.dwell_15_day)
        self.testing_start = day_testing_start* self.dwell_15_day
        self.testing_end = self.testing_start + days_testing_lasts*self.dwell_15_day

        # We need an additional variable to activate and inactivate automatic contact tracing
        self.tracing_start = day_tracing_start* self.dwell_15_day
        self.tracing_end = self.tracing_start + days_tracing_lasts*self.dwell_15_day
        self.tracing_now = False

        # Same for isolation rate
        self.isolation_rate = proportion_isolated
        self.isolation_start = day_start_isolation*self.dwell_15_day
        self.isolation_end = self.isolation_start + days_isolation_lasts*self.dwell_15_day
        self.after_isolation = after_isolation
        self.prob_isolation_effective = prob_isolation_effective

        # Same for social distancing
        self.distancing = social_distance
        self.distancing_start = day_distancing_start*self.dwell_15_day
        self.distancing_end = self.distancing_start + days_distancing_lasts*self.dwell_15_day

        # Introduction of new agents after a specific time
        self.new_agent_num = int(new_agent_proportion * self.num_agents)
        self.new_agent_start = new_agent_start*self.dwell_15_day
        self.new_agent_end = self.new_agent_start + new_agent_lasts*self.dwell_15_day
        self.new_agent_age_mean = new_agent_age_mean
        self.new_agent_prop_infected = new_agent_prop_infected

        # Closing of various businesses
        # TODO: at the moment, we assume that closing businesses decreases the dwell time.
        # A more proper implementation would a) use a power law distribution for dwell times
        # and b) assign a background of dwell times first, modifying them upwards later
        # for all cells.
        # Alternatively, shutting restaurants corresponds to 15% of interactions in an active day, and bars to a 7%
        # of those interactions


        # Now, a neat python trick: generate the spacing of entries and then build a map
        times_list = list(np.linspace(self.new_agent_start, self.new_agent_end, self.new_agent_num, dtype=int))
        self.new_agent_time_map = {x:times_list.count(x) for x in times_list}

        # Probability of severity
        self.prob_severe = proportion_severe

        # Number of beds where saturation limit occurs
        self.max_beds_available = self.num_agents * proportion_beds_pop

        # Create agents
        self.i = 0

        for ag in self.age_distribution:
            for sg in self.sex_distribution:
                r = self.age_distribution[ag]*self.sex_distribution[sg]
                num_agents = int(round(self.num_agents*r))
                mort = self.age_mortality[ag]*self.sex_mortality[sg]
                for k in range(num_agents):
                    a = CovidAgent(self.i, ag, sg, mort, self)
                    self.schedule.add(a)
                    x = self.random.randrange(self.grid.width)
                    y = self.random.randrange(self.grid.height)
                    self.grid.place_agent(a, (x,y))
                    self.i = self.i + 1
        
        self.datacollector = DataCollector(
            model_reporters = {
                "Step": compute_stepno,
                "N": compute_num_agents,
                "Susceptible": compute_susceptible,
                "Exposed": compute_incubating,
                "Asymptomatic": compute_asymptomatic,
                "SymptQuarantined": compute_symptdetected,
                "AsymptQuarantined": compute_asymptdetected,
                "Severe": compute_severe,
                "Recovered": compute_recovered,
                "Deceased": compute_deceased,
                "Isolated": compute_isolated,
                "CumulPrivValue": compute_cumul_private_value,
                "CumulPublValue": compute_cumul_public_value,
                "CumulTestCost": compute_cumul_testing_cost,
                "Rt": compute_eff_reprod_number,
                "Employed": compute_employed,
                "Unemployed": compute_unemployed,
                "Tested": compute_tested,
                "Traced": compute_traced
            }
        )

        # Final step: infect an initial proportion of random agents
        num_init = int(self.num_agents * prop_initial_infected)
        
        for a in self.schedule.agents:
            if num_init < 0:
                break
            else:
                a.stage = Stage.EXPOSED
                num_init = num_init - 1
예제 #28
0
    def __init__(self, floor_plan_file, human_count, collaboration_percentage, fire_probability, visualise_vision, random_spawn, save_plots):
        # Load floorplan
        # floorplan = np.genfromtxt(path.join("fire_evacuation/floorplans/", floor_plan_file))
        with open(os.path.join("fire_evacuation/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.width = width
        self.height = height
        self.human_count = human_count
        self.collaboration_percentage = collaboration_percentage
        self.visualise_vision = visualise_vision
        self.fire_probability = fire_probability
        self.fire_started = False  # Turns to true when a fire has started
        self.save_plots = save_plots

        # Set up model objects
        self.schedule = RandomActivation(self)

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

        # Used to start a fire at a random furniture location
        self.furniture_list = []

        # Used to easily see if a location is a FireExit or Door, since this needs to be done a lot
        self.fire_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 is "W":
                floor_object = Wall((x, y), self)
            elif value is "E":
                floor_object = FireExit((x, y), self)
                self.fire_exit_list.append((x, y))
                self.door_list.append((x, y))  # Add fire exits to doors as well, since, well, they are
            elif value is "F":
                floor_object = Furniture((x, y), self)
                self.furniture_list.append((x, y))
            elif value is "D":
                floor_object = Door((x, y), self)
                self.door_list.append((x, y))
            elif value is "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)

        # Collects statistics from our model run
        self.datacollector = DataCollector(
            {
                "Alive": lambda m: self.count_human_status(m, Human.Status.ALIVE),
                "Dead": lambda m: self.count_human_status(m, Human.Status.DEAD),
                "Escaped": lambda m: self.count_human_status(m, Human.Status.ESCAPED),
                "Incapacitated": lambda m: self.count_human_mobility(m, Human.Mobility.INCAPACITATED),
                "Normal": lambda m: self.count_human_mobility(m, Human.Mobility.NORMAL),
                "Panic": lambda m: self.count_human_mobility(m, Human.Mobility.PANIC),
                "Verbal Collaboration": lambda m: self.count_human_collaboration(m, Human.Action.VERBAL_SUPPORT),
                "Physical Collaboration": lambda m: self.count_human_collaboration(m, Human.Action.PHYSICAL_SUPPORT),
                "Morale Collaboration": lambda m: self.count_human_collaboration(m, Human.Action.MORALE_SUPPORT)
            }
        )

        # Calculate how many agents will be collaborators
        number_collaborators = int(round(self.human_count * (self.collaboration_percentage / 100)))

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

                if number_collaborators > 0:
                    collaborates = True
                    number_collaborators -= 1
                else:
                    collaborates = False

                # Vision statistics obtained from http://www.who.int/blindness/GLOBALDATAFINALforweb.pdf
                vision_distribution = [0.0058, 0.0365, 0.0424, 0.9153]
                vision = int(np.random.choice(np.arange(self.MIN_VISION, self.width + 1, (self.width / len(vision_distribution))), p=vision_distribution))

                nervousness_distribution = [0.025, 0.025, 0.1, 0.1, 0.1, 0.3, 0.2, 0.1, 0.025, 0.025]  # Distribution with slight higher weighting for above median nerovusness
                nervousness = int(np.random.choice(range(self.MIN_NERVOUSNESS, self.MAX_NERVOUSNESS + 1), p=nervousness_distribution))  # Random choice starting at 1 and up to and including 10

                experience = random.randint(self.MIN_EXPERIENCE, self.MAX_EXPERIENCE)

                belief_distribution = [0.9, 0.1]  # [Believes, Doesn't Believe]
                believes_alarm = np.random.choice([True, False], p=belief_distribution)

                human = Human(pos, health=health, speed=speed, vision=vision, collaborates=collaborates, nervousness=nervousness, experience=experience, believes_alarm=believes_alarm, model=self)

                self.grid.place_agent(human, pos)
                self.schedule.add(human)
            else:
                print("No tile empty for human placement!")

        self.running = True
예제 #29
0
 def __init__(self, width, height, torus):
     MultiGrid.__init__(self, width, height, torus)
예제 #30
0
    def __init__(self, number_of_cars, width, height, is_odd_even_policy_enabled, is_odd_date, policy_range_time):
        # Tick increment
        self.tick = 0

        # Mean Travel Time
        self.mean_travel_time = 0.0

        # Odd-Even Policy Enabled
        self.is_odd_even_policy_enabled = is_odd_even_policy_enabled

        # Set the day of the week
        self.is_odd_date = is_odd_date

        # Set up Spatial dimension
        self.grid = MultiGrid(width, height, True)

        # Set up Temporal dimension
        self.schedule = SimultaneousActivation(self)
        self.running = True

        self.policy_range_time = policy_range_time

        # Set up peak hours
        self.start_peak_hour_1 = PEAK_HOURS["START_PEAK_HOUR_1"] #7
        self.end_peak_hour_1 = PEAK_HOURS["END_PEAK_HOUR_1"] #10
        self.start_peak_hour_2 = PEAK_HOURS["START_PEAK_HOUR_2"] #4
        self.end_peak_hour_2 = PEAK_HOURS["END_PEAK_HOUR_2"] #7

        # Car distribution
        num_highly_active_cars = math.ceil(ACTIVITY_PROPORTION["HIGHLY_ACTIVE"] * number_of_cars)
        num_business_hours_cars = math.ceil(ACTIVITY_PROPORTION["BUSINESS_HOURS"] * number_of_cars)
        num_peak_hours_cars = number_of_cars - (num_highly_active_cars + num_business_hours_cars)

        # generate road
        self.map = MapGenerator()
        roadPosition = self.map.get_road_position()
        for i in range(len(roadPosition)):
            road = Road(i, roadPosition[i], self)
            self.grid.place_agent(road, roadPosition[i])

        ## generate office
        officePosition = self.map.get_office_position()
        for i in range(len(officePosition)):
            office = Office(i, officePosition[i], self)
            self.grid.place_agent(office, officePosition[i])

        # generate residence
        residencePosition = self.map.get_residence_position()
        for i in range(len(residencePosition)):
            residence = Residence(i, residencePosition[i], self)
            self.grid.place_agent(residence, residencePosition[i])

        # generate entertainment
        entertainmentPosition = self.map.get_entertainment_position()
        for i in range(len(entertainmentPosition)):
            entertainment = Entertainment(i, entertainmentPosition[i], self)
            self.grid.place_agent(entertainment, entertainmentPosition[i])

        # generate traffic light
        trafficLightPosition = self.map.get_traffic_light_position()
        for i in range(len(trafficLightPosition)):
            trafficLight = TrafficLight(i, trafficLightPosition[i], self, COLOR["dark_grey"])
            self.grid.place_agent(trafficLight, trafficLightPosition[i])

        # Get source and destination lists
        residence_list = self.map.get_residence_position()
        office = self.map.get_office_position()
        entertainment = self.map.get_entertainment_position()

        # Create destination list based on weekday/weekend proportion
        proportion_of_office_workers = 0.65
        number_of_office_workers = math.ceil(proportion_of_office_workers * number_of_cars)
        number_of_shopper = number_of_cars - number_of_office_workers

        office_list = []
        while len(office_list) <= number_of_office_workers:
            office_list.append(office[self.random.randint(0, len(office) -1)])

        entertainment_list = []
        while len(entertainment_list) <= number_of_shopper:
            entertainment_list.append(entertainment[self.random.randint(0, len(entertainment) - 1)])

        office_entertainment_list = office_list + entertainment_list
        random.shuffle(residence_list)

        layout = self.map.get_layout()
        for i in range(number_of_cars):
            # determine departure and return time based on activity level
            if i <= num_highly_active_cars:
                activity_level = "HIGHLY_ACTIVE"
                departure_time = 0
                return_time = float("inf")
            elif i <= num_business_hours_cars:
                activity_level = "BUSINESS_HOURS"
                departure_time = self.start_peak_hour_1
                return_time = float("inf")
            else:
                activity_level = "PEAK_HOURS"
                departure_time = self.random.randint(self.start_peak_hour_1,self.end_peak_hour_1)
                return_time = self.random.randint(self.start_peak_hour_2,self.end_peak_hour_2)

            plate_number_oddity = self.random.randint(0, 1)

            source_x = residence_list[i][0]
            source_y = residence_list[i][1]
            destination_x = office_entertainment_list[i][0]
            destination_y = office_entertainment_list[i][1]

            state_fringes = self.map.get_fringes(source_x, source_y)
            shortest_distance = float("inf")
            car_direction = state_fringes[0][1]
            for state_fringe in state_fringes:
                current_direction =  state_fringe[1] # "^" "v" ">" "<"
                if current_direction in DIRECTION:
                    temp_x = state_fringe[0][0] + DIRECTION[current_direction][0]
                    temp_y = state_fringe[0][1] + DIRECTION[current_direction][1]

                    newDist = get_euclidean_distance((temp_x, temp_y), (destination_x, destination_y))
                    if newDist < shortest_distance:
                        shortest_distance = newDist
                        car_direction = current_direction

            # all cars are initialised as IDLE
            car_state = "IDLE"

            car = Car(i, plate_number_oddity,
                        (source_x,source_y),
                        (destination_x,destination_y),
                        car_direction,
                        car_state,
                        departure_time,
                        return_time,
                        activity_level,
                        self)

            self.grid.place_agent(car, (source_x,source_y))
            self.schedule.add(car)

        # Data Collection
        self.datacollector = DataCollector({
            "Idle": number_idle_cars,
            "Move": number_move_cars,
            "Finished": number_finished_cars,
            "SimulationMinutes": simulation_minutes,
            "ToOffice": number_office,
            "ToResidence": number_residence,
            "MeanTravelTime": mean_travel_time,
            "StdTravelTime": std_travel_time
        })
        self.datacollector.collect(self)
예제 #31
0
class MarketModel(Model):
    def __init__(self,
                 buff,
                 plot_buff,
                 max_agents_number,
                 market,
                 checkout_slider,
                 width=50,
                 height=50,
                 steps=3000):
        self.steps = steps
        self.plot_buff = plot_buff
        self.running = True
        self.market = market
        self.checkout_slider = checkout_slider
        self.num_agents = max_agents_number
        self.schedule = RandomActivation(self)
        self.grid = MultiGrid(width, height, True)
        self.grid_mutex = Lock()
        self.agents_number = 1
        self.regal_agents = []
        self.checkout_agents = []
        self.opened_checkouts = []
        self.closed_checkouts = []
        self.space_graph = np.zeros((width, height))
        self.place_checkouts()
        self.place_regals()
        self.thread_pool = ThreadPool(20)
        self.customer_list = buff
        self.total_income = 0.0
        self.agent_counts = [[0 for x in range(self.grid.width)]
                             for y in range(self.grid.height)]
        self.plot_buff.append(self.agent_counts)
        self.plot_buff.append(self.grid.width)
        self.plot_buff.append(self.grid.height)
        self.income_data_collector = DataCollector(
            model_reporters={"total_income": get_income})

        self.queue_length_data_collector = DataCollector(
            model_reporters={
                "average_queue_length": compute_average_queue_size
            })

        self.open_checkouts()

    def add_agent(self):
        i = random.randint(0, 1)
        if i == 0:
            a = CommonCustomer(self.agents_number, self, self.market.articles)
        else:
            a = LazyCustomer(self.agents_number, self, self.market.articles)
        # a = CommonCustomer(self.agents_number, self, self.market.articles)
        self.agents_number += 1
        self.schedule.add(a)
        self.grid.place_agent(a, (a.x, a.y))
        self.customer_list.append(a)

    def place_checkouts(self):
        for checkout_location in self.market.cashRegisters:
            checkout_agent = Checkout(self.agents_number, self,
                                      checkout_location)
            self.agents_number += 1
            self.grid.place_agent(checkout_agent, checkout_location)
            self.checkout_agents.append(checkout_agent)
            self.space_graph[checkout_location[0], checkout_location[1]] = 1
        self.closed_checkouts = self.checkout_agents

    def place_regals(self):
        for regal in self.market.regals:
            self.place_regal(regal)

    def place_regal(self, regal):
        for shelf in regal.shelf_list:
            self.place_shelf(shelf)

    def place_shelf(self, shelf):
        shelf_agent = ShelfAgent(self.agents_number, self, shelf)
        pos = shelf_agent.get_location()
        self.agents_number += 1
        self.grid.place_agent(shelf_agent, pos)
        self.regal_agents.append(shelf_agent)
        self.space_graph[pos[0], pos[1]] = 1

    def open_checkouts(self):
        for i in range(0, len(self.checkout_agents),
                       len(self.checkout_agents) // self.checkout_slider):
            checkout = self.closed_checkouts.pop(
                random.randint(0,
                               len(self.closed_checkouts) - 1))
            checkout.open()
            self.opened_checkouts.append(checkout)
            self.schedule.add(checkout)

    def open_random_checkout(self):
        if len(self.closed_checkouts) != 0:
            checkout = self.closed_checkouts.pop(
                random.randint(0,
                               len(self.closed_checkouts) - 1))
            checkout.open()
            self.opened_checkouts.append(checkout)
            self.schedule.add(checkout)

    def close_random_checkout(self):
        if len(self.opened_checkouts) > 1:
            checkout = self.opened_checkouts.pop(
                random.randint(0,
                               len(self.opened_checkouts) - 1))
            checkout.close()
            self.closed_checkouts.append(checkout)
            # self.schedule.add(checkout)

    def find_nearest_checkouts(self, location, n):
        new_list = self.opened_checkouts.copy()
        ordered_list = sorted(new_list,
                              key=(lambda x:
                                   ((x.location[0] - location[0])**2) + (
                                       (x.location[1] - location[1])**2)))
        return ordered_list[0:]

    def generate_random_starting_pos(self):
        pos_list = [(self.grid.width // 2 + 1, 0), (self.grid.width - 1, 1),
                    (self.grid.width - 1, self.grid.height - 2)]
        i = random.randint(0, len(pos_list) - 1)
        pos = pos_list[i]

        if i == 0:
            pos = (pos_list[0][0] + random.randint(-2, 2), pos_list[0][1])

        return pos

    def step(self):
        print(self.checkout_slider)
        self.income_data_collector.collect(self)
        self.queue_length_data_collector.collect(self)

        if compute_average_queue_size(self) > 3:
            self.open_random_checkout()

        if compute_average_queue_size(self) < 3:
            self.close_random_checkout()

        sigma = 1
        cycle_steps = 1500
        n = self.schedule.steps // cycle_steps + 1
        gauss = gaussian(
            self.schedule.steps * (6 * sigma / cycle_steps) - 3 * n * sigma, 0,
            sigma) * self.num_agents
        print(gauss)
        while len(self.schedule.agents) - len(
                self.checkout_agents) < np.ceil(gauss):
            self.add_agent()

        self.schedule.step()

    def move_agent(self, agent, new_pos):
        # self.grid_mutex.acquire()
        self.agent_counts[new_pos[0]][new_pos[1]] += 1
        self.plot_buff[0] = self.agent_counts
        self.grid.move_agent(agent, new_pos)
        # self.grid_mutex.release()

    def remove_agent(self, agent):
        # self.grid_mutex.acquire()
        self.grid.remove_agent(agent)
        self.schedule.remove(agent)
        if type(agent) is CommonCustomer:
            self.customer_list.remove(agent)
        # self.grid_mutex.release()

    def get_customers(self):
        return self.customer_list
예제 #32
0
class trafficSimulation(Model):
    def __init__(self, spawn_speed):
        self.spawn_speed = spawn_speed
        self.counter = 0
        self.traffic_lights_schedule = TrafficScheduler(self)
        self.cars_schedule = SimultaneousActivation(self)
        self.grid = MultiGrid(10, 10, False)
        self.id = 0
        self.spawnpoints = [(9, 5), (0, 4), (6, 0), (5, 9)]
        self.kill_agents = []

        self.datacollector = DataCollector(model_reporters={"Grid": get_grid})

        traffic_light_coords = [(7, 5), (4, 4), (6, 3), (5, 6)]

        for coord in traffic_light_coords:
            light = trafficLight(self.id, coord, self)
            self.id = self.id + 1
            self.grid.place_agent(light, coord)
            self.traffic_lights_schedule.add(light)
            self.datacollector.collect(self)

    def get_data(self):
        traffic_lights = [{
            "coords": {
                "x": agent.coords[0],
                "y": agent.coords[1]
            },
            "state": stateToString(agent.state)
        } for agent in get_other_lights(-1, self)]
        cars = [{
            "direction": {
                "x": agent.direction[0],
                "y": agent.direction[1]
            },
            "coords": {
                "x": agent.coords[0],
                "y": agent.coords[1]
            }
        } for agent in self.cars_schedule.agents]
        return traffic_lights, cars

    def step(self):

        self.traffic_lights_schedule.step()
        self.cars_schedule.step()

        if self.counter == self.spawn_speed - 1 and random.random() > 0.5:
            orientation, coords = random.choice(
                [x for x in zip(direction.lst, self.spawnpoints)])
            anyCar = any([
                isinstance(agent, carAgent)
                for agent in self.grid.iter_neighbors(coords, False, True, 0)
            ])
            if not anyCar:
                car = carAgent(self.id, coords, orientation, self)
                self.grid.place_agent(car, coords)
                self.cars_schedule.add(car)
                self.id = self.id + 1
        self.counter = (self.counter + 1) % self.spawn_speed

        for x in self.kill_agents:
            self.grid.remove_agent(x)
            self.cars_schedule.remove(x)
            self.kill_agents.remove(x)
예제 #33
0
    def __init__(self, N_attr, N_cust, width, height, strategy, theme, max_time, weight, adaptive):
        self.theme = theme
        self.max_time = max_time
        self.N_attr = N_attr
        self.penalty_per = PENALTY_PERCENTAGE
        self.weight = weight
        self.adaptive = adaptive
        self.strategies = STRATEGIES
        self.x_list, self.y_list, self.positions = xlist, ylist, positions
        self.x_list, self.y_list, self.positions = get_attraction_coordinates(WIDTH, HEIGHT, self.N_attr, theme)
        self.happinesses = []
        self.starting_positions = [[int((WIDTH/2)-1), 0], [int(WIDTH/2), 0], [int((WIDTH/2)+1), 0]]
        self.path_coordinates = get_coordinates(WIDTH, HEIGHT, NUM_OBSTACLES, self.N_attr, theme)
        self.N_attr = N_attr    # num of attraction agents
        self.N_cust = N_cust    # num of customer agents
        self.width = width
        self.height = height
        self.total_steps = 0
        self.cust_ids = N_cust
        self.strategy = strategy
        self.grid = MultiGrid(width, height, torus=False)
        self.schedule = BaseScheduler(self)
        self.schedule_Attraction = BaseScheduler(self)
        self.schedule_Customer = BaseScheduler(self)
        self.totalTOTAL = 0
        self.attractions = self.make_attractions()
        self.attraction_history = self.make_attr_hist()
        self.running = True
        self.data = []
        self.data_customers = []
        self.park_score = []
        self.data_dict = {}
        self.hist_random_strat = []
        self.hist_close_strat = []
        self.all_rides_list = []
        self.strategy_composition = self.make_strategy_composition()
        self.memory = 5
        self.customer_score = []
        self.customers = self.add_customers(self.N_cust)
        self.only_random = False


        for attraction in self.get_attractions():
            self.data_dict[attraction.unique_id] = ({
                               "id": attraction.unique_id,
                               "length": attraction.attraction_duration,
                               "waiting_list": []})

        if len(self.strategies) == 6:
            self.datacollector = DataCollector(

                {"Random": lambda m: self.strategy_counter(self.strategies[0]),
                "0.00": lambda m: self.strategy_counter(self.strategies[1]),
                "0.25": lambda m: self.strategy_counter(self.strategies[2]),
                "0.50": lambda m: self.strategy_counter(self.strategies[3]),
                "0.75": lambda m: self.strategy_counter(self.strategies[4]),
                "1.00": lambda m: self.strategy_counter(self.strategies[5]),
                })
        else:
            self.datacollector = DataCollector(
                {"0.00": lambda m: self.strategy_counter(self.strategies[0]),
                "0.25": lambda m: self.strategy_counter(self.strategies[1]),
                "0.50": lambda m: self.strategy_counter(self.strategies[2]),
                "0.75": lambda m: self.strategy_counter(self.strategies[3]),
                "1.00": lambda m: self.strategy_counter(self.strategies[4]),
                })

        self.datacollector2 = DataCollector(
            {"score": lambda m: self.make_score()})

        self.total_waited_time = 0

        self.monitor = Monitor(self.max_time, self.N_attr, self.positions)
예제 #34
0
class AntModel(Model):
    def __init__(self, num_ln, num_fj, num_mk_col, num_ft_col, width, height):
        """
        :param num_ln: Number of L. Niger agents
        :param num_fj: Number of F. Japonica agents
        :param num_mk_col: Number of M. Kuricola colonies
        :param num_ft_col: Number of F. Tropicalis colonies
        :param width: Width of the model grid
        :param height: Height of the model grid
        """
        super().__init__()
        self.num_ln = num_ln
        self.num_fj = num_fj
        self.num_mk_col = num_mk_col
        self.num_ft_col = num_ft_col
        self.grid = MultiGrid(width, height, True)
        self.schedule = RandomActivation(self)
        self.running = True

        for h in range(self.num_fj):
            ant = FJaponica(uuid4(), self)
            self.schedule.add(ant)
            self.grid.place_agent(ant, self.grid.find_empty())

        for j in range(self.num_mk_col):
            colony = MKuricolaColony(uuid4(), self)
            self.schedule.add(colony)
            self.grid.place_agent(colony, self.grid.find_empty())

        for k in range(self.num_ft_col):
            colony = FTropicalisColony(uuid4(), self)
            self.schedule.add(colony)
            self.grid.place_agent(colony, self.grid.find_empty())

        for i in range(self.num_ln):
            ant = LNiger(uuid4(), self)
            self.schedule.add(ant)
            self.grid.place_agent(ant, self.grid.find_empty())
            ant._init_post_place()

        self.data_collector = DataCollector(
            model_reporters={},
            agent_reporters={"states": ant_state_collector})
        self.weights_dict = json.load(open("newout.json", "r"))

    def drop_pheromone(self, location):
        """
        Drops a LNPheromone object at the given location if one does not already exist. If one does already exist,
        1 is added to the existing object's 'tracks' field.
        :param location: An (x, y) tuple detailing the location to drop the pheromone.
        :return: None
        """
        if not self.is_pheromone_in_cell(location):
            self.grid.place_agent(LNPheromone(uuid4(), self), location)
        else:
            self.get_pheromone_in_cell(location).tracks += 1

    def is_pheromone_in_cell(self, location):
        """
        Determines if a pheromone already exists in a given cell.
        :param location: The location to check.
        :return: boolean
        """
        return True in [
            type(x) == LNPheromone
            for x in self.grid.get_cell_list_contents(location)
        ]

    def is_ant_in_cell(self, location):
        """
        Determines whether an ant exists in a given cell.
        :param location: The location to check.
        :return: boolean
        """
        return True in [
            isinstance(x, Ant)
            for x in self.grid.get_cell_list_contents(location)
        ]

    def is_colony_in_cell(self, location):
        """
        Determines whether an aphid colony exists in a given cell.
        :param location: The location to check.
        :return: boolean
        """
        return True in [
            type(x) == MKuricolaColony or type(x) == FTropicalisColony
            for x in self.grid.get_cell_list_contents(location)
        ]

    def get_pheromone_in_cell(self, location):
        """
        Returns a LNPheromone object from a cell. ASsumes the cell has already been proven to have a pheromone object
        in it.
        :param location: The cell location to check.
        :return: The LNPheromone object within the cell.
        """
        in_cell_pheromone = None
        for i in self.grid.get_cell_list_contents(location):
            if type(i) == LNPheromone:
                in_cell_pheromone = i
        return in_cell_pheromone

    def get_closest_agent_of_type(self, agent, agent_type):
        """
        Gets the closest agent (besides self) of type agent_type. Returns -1 if it cannot find one.
        :param agent: The agent to find the closest agent_type to.
        :param agent_type: The type of the agent we are looking for.
        :return:
        """
        for radius in range(1, self.grid.width):
            for neighbor in self.grid.get_neighbors(pos=agent.pos,
                                                    moore=True,
                                                    include_center=False,
                                                    radius=radius):
                if isinstance(neighbor, agent_type):
                    return neighbor
        return -1

    def get_closest_colony(self, agent):
        """
        Gets the closest colony to an agent. If an agent is of type colony, it returns itself.
        :param agent: The agent to find the closest colony to.
        :return: The closest colony or -1 if not found.
        """
        return self.get_closest_agent_of_type(agent, Colony)

    @staticmethod
    def distance_between_cells(location_a, location_b):
        """
        Calculates the distance between two cells on the grid.
        :param location_a: First cell location.
        :param location_b: Second cell location.
        :return:
        """
        return np.sqrt((location_a[0] - location_b[0])**2 +
                       (location_a[1] - location_a[1])**2)

    def get_nearest_cell_to_goal(self, goal_cell, possible_cells):
        """
        Returns the cell from a list of possible cells which is closest to the end location.
        :param goal_cell: The goal cell of the agent
        :param possible_cells: Candidate cells.
        :return: The location of the closest cell to the goal cell.
        """
        closest_neighbor_index = -1
        closest_neighbor_distance = np.inf
        for i in range(0, len(possible_cells)):
            dist = self.distance_between_cells(possible_cells[i], goal_cell)
            if dist < closest_neighbor_distance:
                closest_neighbor_index = i
                closest_neighbor_distance = dist
        return possible_cells[closest_neighbor_index]

    def get_number_of_agents_in_radius(self, location, radius, agent_type):
        """
        Returns the number of agents of type agent_type within a radius (not including center) of location.
        :param location: Location to search around.
        :param radius: Radius to search.
        :param agent_type: Type of agent to search for.
        :return: int
        """
        total_agents = 0
        for neighbor in self.grid.get_neighbors(pos=location,
                                                moore=True,
                                                include_center=False,
                                                radius=radius):
            if isinstance(neighbor, agent_type):
                total_agents += 1
        return total_agents

    def get_all_of_agent_type(self, agent_type):
        """
        Returns all instances of agents of type agent_type in the Grid.
        :param agent_type: The type of agent to find.
        :return: A list of agent objects.
        """
        return [
            x for x in self.grid.get_neighbors(pos=(0, 0),
                                               moore=True,
                                               include_center=True,
                                               radius=self.grid.width)
            if isinstance(x, agent_type)
        ]

    def step(self):
        """
        A method called every step that occurs
        :return: None
        """
        self.data_collector.collect(self)
        self.schedule.step()
예제 #35
0
 def __init__(self, height = 50, width = 50, initial_population =200, \
              Moore = False, torus = True, regrow = 1, seed = None):
     
     '''
     Args:
         height - y axis of grid_size
         width - x axis of grid size
         initial_population - number of agents starting
         moore - type of neighborhood
         torus - whether or no world wraps
         regrow - amout each resource grows bas each step
         process - Number of additonal proces by agents
         0 = Movement/Survive; 1 = +trade, 2 = +
         
     Initial Parameters: 
         Multigrid
         ActivationbyBreed (see schedule)
         Num_Agents counter to account for each agent number
         timekeeper - dictionary to keep track of time for each section
         start_time - create initial time
         datacollector to collect agent data of model
     '''
     
     self.step_num = 0
     self.height = height
     self.width = width
     self.initial_population = initial_population
     self.num_agents = 0
     #Mesa Agent Scheduler
     #self.schedule = schedule.RandomActivationByBreed(self)
     self.schedule = RandomActivationByBreed(self)
     self.grid = MultiGrid(self.height, self.width, torus=True)
     self.regrow = regrow
     self.running = True
     self.price_record = defaultdict(list)
     
                   
     
     '''
     Recorders
       Start datacollector
       Start time recorder
     '''
     self.start_time = time.time()
     
     self.datacollector = DataCollector(\
                          model_reporters = {"MetaAgent": recorder.survivors}, \
                          tables ={"Health":["Agent", "Step", "Sugar_Level", \
                                             "Spice_Level"], \
                          "Time":["Time Per Step"]})
     
     
     '''
     
     Creates the landscape:
         Fours mounds 2 sugar, 2 spice located- 1 in each quadrant
         imports landscape module to account for various landscape sizes
     '''
     self.resource_dict = {}
     
     landscape = Landscape.create_landscape(height, width)
     #places resources from landscape on grid
     for k,v in landscape.items(): 
         resource =  R.resource(k, self, v, self.regrow)
         self.grid.place_agent(resource, (resource.pos[0], resource.pos[1]))
         #POINT
         self.schedule.add(resource)
         
     
            
     #fills in empty grids with null value resource agent        
     #Deviation from GrAS -- in empty cells has random resource from 0 to 4
     for a,x,y in self.grid.coord_iter():
         if a == set():
             resource = R.resource((x,y), self, \
                                   (self.random.randrange(0,2), \
                                    self.random.randrange(0,2)),self.regrow)
             self.grid.place_agent(resource, (resource.pos[0], resource.pos[1]))
             #POINT
             self.schedule.add(resource)
                     
        
     '''
     Creates the agents:
         
     '''
     pos_array = list(self.schedule.agents_by_breed[R.resource].keys())
     self.random.shuffle(pos_array)
     vision_array = np.random.randint(1,6,self.initial_population)
     spice_array = np.random.randint(1,6,self.initial_population)
     sugar_array = np.random.randint(1,6,self.initial_population)
     for n in range(self.initial_population):
         #x = 0
         #y = 0
         #print ("position: ", (n, x,y))
         #GrAS p. 108
         sugar = self.random.randrange(25,50)
         spice = self.random.randrange(25,50)
         #GrAS p.108
         sug_bolism = sugar_array[n]
         spice_bolism = spice_array[n]
         #GrAS p. 108
         vision = vision_array[n]
         neighbors = Moore
         a = N.NetAgent(n, pos_array[n], self, \
                              {"sug_bolism": sug_bolism, \
                              "spice_bolism": spice_bolism}, \
                              {1 : sugar, 2: spice}, {"vision": vision}, \
                              neighbors)
         #POINT
         self.schedule.add(a)
         self.grid.place_agent(a,pos_array[n])
예제 #36
0
class FactoryModel(Model):
    """A model with some number of agents."""
    def __init__(self, N, num_task, num_empty, num_full):
        global task_over
        task_over = False
        # 1 means walls
        self.fmap = [[0,0,0,1,0,0,0,0,0,0],
                     [0,0,0,1,0,0,0,0,0,0],
                     [0,0,0,1,0,0,0,0,0,0],
                     [0,0,0,1,0,0,0,0,0,0],
                     [0,0,0,1,0,0,0,0,0,0],
                     [0,0,0,0,0,0,0,0,0,0],
                     [0,0,0,0,0,0,1,0,0,0],
                     [0,0,0,0,0,0,1,0,0,0],
                     [0,0,0,0,0,0,1,0,0,0],
                     [0,0,0,0,0,0,1,0,0,0]]

        self.height = self.width = len(self.fmap)
        self.grid = MultiGrid(self.width, self.height, False)
        self.running = True
        self.schedule = RandomActivation(self)
        self.ttl = 1

        empty = []
        full  = []
        # Create boxes
        while (len(empty)+len(full)) != (num_empty+num_full):
            x = random.randrange(self.width)
            y = random.randrange(self.height)
            if self.fmap[x][y] == 0:
                if len(empty)<num_empty and ((x,y) not in empty):
                    empty.append((x,y))
                elif (x,y) not in full and ((x,y) not in empty):
                    full.append((x,y))
        # [[empty boxes], [full boxes]]
        self.boxes = [empty,full]

        # Create tasks
        tasks = []
        while len(tasks) < N*num_task:
          for i in range(num_task):
            pos = random.choice(full)
            if pos not in tasks:
              tasks.append(pos)
        print("tasks are ",tasks)

        # Create Wall agents
        self.createWall()

        # Create box agents
        self.createBox()

        # Create Robot agents
        self.createRobot(N, num_task, tasks)

    def createWall(self):
        type = 1
        for i in range(self.height):
          for j in range(self.width):
            if (self.fmap[i][j] == 1):
              a = WallAgent(self.ttl, self, type)
              self.grid.place_agent(a,(i,j))
              self.schedule.add(a)
              self.ttl += 1

    def createBox(self):
        type = 2 # empty box
        for pos in self.boxes[0]:
          a = BoxAgent(self.ttl, self, type)
          self.grid.place_agent(a,pos)
          self.schedule.add(a)
          self.ttl += 1

        type = 3 # full box
        for pos in self.boxes[1]:
          a = BoxAgent(self.ttl, self, type)
          self.grid.place_agent(a,pos)
          self.schedule.add(a)
          self.ttl += 1

    def createRobot(self, num_agents, num_task, tasks):
        type = 0
        agents = []
        while len(agents) < num_agents:
            # add an agent into a random cell
            x = random.randrange(self.grid.width)
            y = random.randrange(self.grid.height)
            if (self.fmap[x][y] == 0 
                and (x,y) not in self.boxes[1]
                and (x,y) not in self.boxes[0]
                and (x,y) not in agents):
                a = RobotAgent(self.ttl, self, type,
                               tasks[:num_task], self.fmap, self.boxes)
                self.schedule.add(a)
                self.ttl += 1
                tasks = tasks[num_task:]
                self.grid.place_agent(a,(x,y))
                agents.append((x,y))
        print("start from ", agents)
#            self.grid.place_agent(a,(9,0))

    def step(self):
        '''Advance the model by one step.'''
        global task_over
        if not task_over:
          self.schedule.step()
        else:
          print("task over")
          self.running = False
예제 #37
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************")
예제 #38
0
class Intersection(Model):
    """
    Here the model is initialized. The Generatedmap.txt is read in order to locate traffic lights and car spawns.
    Cars and traffic lights are spawned here.
    """

    def __init__(self, spawnrate, tactic, offset, cycletime):
        # Variable parameters
        self.tactic = tactic  # [ Offset, Proportional, Lookahead, GreenWave]
        self.spawnrate = spawnrate
        self.offset = offset
        self.slowmotionrate = 0.2
        self.cycletime = cycletime

        # Value initializations
        self.emission = [0, 0, 0]  # emission per step
        self.traveltime = []
        self.averagetraveltime = 0
        self.carID = 0
        self.averageemission = []

        # Reading roadmap and emission values
        self.emissionvalues = reademissionvalues()
        [
            self.roadmap,
            self.spawns,
            self.lights,
            self.height,
            self.cellsperlane,
            self.intersections,
            self.streetlength,
            self.gridsize,
        ] = readroadmap()

        # Model and visualization parameters
        self.schedule = RandomActivation(self)
        self.width = self.height
        self.grid = MultiGrid(self.width, self.height, True)
        self.running = True

        # Initializing matrix which shows what cars in front of traffic lights go to what over traffic lights.
        self.tlightmatrix = np.empty((len(self.lights), len(self.lights)))
        self.tlightmatrix[:] = np.nan
        self.trafficlightlist = []
        self.lightcombinations = [
            ["SR", "SD", "SL", "WR"],
            ["ER", "ED", "EL", "SR"],
            ["NR", "ND", "NL", "ER"],
            ["WR", "WD", "WL", "NR"],
        ]

        # Data collection
        self.datacollector = DataCollector(
            model_reporters={
                "tactic": "tactic",
                "Spawnrate": "spawnrate",
                "Offset": "offset",
                "Cycletime": "cycletime",
                "AverageTraveltime": "averagetraveltime",
                "Totalcars": lambda m: self.numberofcars(),
                "CO2": lambda m: self.getco2(),
                "NOx": lambda m: self.getnox(),
                "PM10": lambda m: self.getpm(),
                "AverageCO2": lambda m: self.getaverageco2(),
                "AverageNOx": lambda m: self.getaveragenox(),
                "AveragePM": lambda m: self.getaveragepm(),
            },
        )

        # Needed for green wave tactic
        self.mostcars = []
        self.goesto = []
        self.firstgreenintersection = -1
        self.secondgreenintersection = -1
        self.firstcombination = None
        self.secondcombination = None
        self.firstcycledone = 0

        # Needed for lookahead tactic
        self.mostexpectedcars = [0, 0, 0]  # cars,intersection,combination

        # results in list of lists with intersectionnumbers in the right place, e.g.: [[0, 1],[2,3]]
        # Needed for the offset tactic to know which lights to offset
        self.intersectionmatrix = []
        lastnumber = 0
        for i in range(int(math.sqrt(self.intersections))):
            tempmaptrix = []
            for j in range(int(math.sqrt(self.intersections))):
                tempmaptrix.append(j + lastnumber)
            lastnumber = tempmaptrix[-1] + 1
            self.intersectionmatrix.append(tempmaptrix)
        self.intersectionmatrix = np.array(self.intersectionmatrix)

        # Initialize information dictionary (which lights are suppesed to be green and how long they have been green for
        self.trafficlightinfo = {}
        for i in range(self.intersections):
            self.trafficlightinfo.update(
                {f"intersection{i}": {"Trafficlightinfo": {}, "Timeinfo": {}}}
            )

        # Initializes traffic lights
        for i, light in enumerate(self.lights):
            self.trafficlightinfo[f"intersection{light[1][3]}"]["Trafficlightinfo"][
                f"{light[1][1:3]}"
            ] = i
            self.trafficlightinfo[f"intersection{light[1][3]}"]["Timeinfo"].update(
                {
                    "Currentgreen": -1,
                    "Currenttimegreen": 0,
                    "Maxtimegreen": 0,
                    "Allred": 1,
                }
            )
            intersectionnumber = int(light[1][3])
            intersectiony = np.where(self.intersectionmatrix == intersectionnumber)[0]
            intersectionx = np.where(self.intersectionmatrix == intersectionnumber)[1]
            direction = light[1][1]
            lane = light[1][2]
            location = light[0]
            xlocation = int(location[0])
            ylocation = self.height - 1 - int(location[1])
            trafficlight = TrafficLightAgent(
                f"{xlocation},{ylocation},{light[1][1:3]}",
                self,
                "red",
                direction,
                lane,
                i,
                intersectionnumber,
                self.tactic,
                self.offset,
                [intersectionx, intersectiony],
                self.cycletime,
            )
            self.trafficlightlist.append([light[1], i])
            self.schedule.add(trafficlight)
            self.grid.place_agent(trafficlight, (xlocation, ylocation))
        self.tlightmatrix = lightconnection(
            self.tlightmatrix, self.trafficlightlist, self.intersections
        )

        # Place legend
        self.grid.place_agent(LegendCarIcon("Caricon", self), (65, 68))
        self.grid.place_agent(LegendGreenTlightIcon("GreenTlighticon", self), (65, 69))
        self.grid.place_agent(LegendRedTlightIcon("RedTlighticon", self), (65, 70))

    # Get emission values
    def getco2(self):

        return self.emission[0]

    def getnox(self):

        return self.emission[1]

    def getpm(self):

        return self.emission[2]

    def getaveragetraveltime(self):

        return self.averagetraveltime

    def getaverageco2(self):
        totalco2 = 0
        if len(self.averageemission) > 0:
            for i, emissions in enumerate(self.averageemission):
                totalco2 += emissions[0]
            return totalco2 / len(self.averageemission)
        else:
            return 0

    def getaveragenox(self):
        totalnox = 0
        if len(self.averageemission) > 0:
            for i, emissions in enumerate(self.averageemission):
                totalnox += emissions[1]
            return totalnox / len(self.averageemission)
        else:
            return 0

    def getaveragepm(self):
        totalpm = 0
        if len(self.averageemission) > 0:
            for i, emissions in enumerate(self.averageemission):
                totalpm += emissions[2]
            return totalpm / len(self.averageemission)
        else:
            return 0

    def numberofcars(self):
        return len(self.schedule.agents) - 12 * self.intersections

    def step(self):
        """
        Step function that will randomly place cars based on the spawn chance
        and will visit all the agents to perform their step function.
        """
        # Spawn cars
        for spawn in self.spawns:
            location = spawn[0]
            cell_contents = self.grid.get_cell_list_contents([location])

            if (
                not cell_contents
                and random.randint(0, int(100 / self.slowmotionrate)) < self.spawnrate
            ):
                location = spawn[0]
                xlocation = int(location[0])
                ylocation = self.height - 1 - int(location[1])
                direction = spawn[1][1]
                lane = spawn[1][2]
                car = CarAgent(
                    f"car{self.carID}",
                    self,
                    direction,
                    lane,
                    [xlocation, ylocation]
                )
                self.carID += 1
                self.schedule.add(car)
                self.grid.place_agent(car, (xlocation, ylocation))

        # Clear all previous step's emission and travel time
        if len(self.traveltime) > 0:
            self.averagetraveltime = sum(self.traveltime) / len(self.traveltime)

        # For the greenwave tactic
        if (
            self.tactic == "GreenWave"
            and len(self.schedule.agents) > 12 * self.intersections
            and ((self.schedule.steps % (self.cycletime * 2)) == 0)
        ):

            self.firstcycledone = 0
            self.mostcars = np.argmax(np.nansum(self.tlightmatrix, axis=1))
            if self.mostcars:
                self.goesto = np.where(~np.isnan(self.tlightmatrix[self.mostcars]))
                self.firstgreenintersection = self.lights[self.mostcars][1][3]
                self.secondgreenintersection = self.lights[self.goesto[0][0]][1][3]

                # Determines the direction of traffic lights
                firstdirection = self.schedule.agents[int(self.mostcars)].direction
                seconddirection = self.schedule.agents[self.goesto[0][0]].direction

                # Determines combinations of traffic lights that can stay green
                for i, combination in enumerate(self.lightcombinations):
                    if firstdirection + "D" in combination:
                        self.firstcombination = self.lightcombinations[i]
                    if seconddirection + "D" in combination:
                        self.secondcombination = self.lightcombinations[i]
                # If 1st part of green wave is over (so 1 cycle has been done)
                if not ((self.schedule.steps % (self.cycletime * 2)) == 0):
                    self.firstcycledone = 1

        # For the proportional tactic
        if (
            self.tactic == "Proportional"
            and len(self.schedule.agents) > 12 * self.intersections
        ):
            for i in range(self.intersections):
                currenttimegreen = self.trafficlightinfo[f"intersection{i}"][
                    "Timeinfo"
                ]["Currenttimegreen"]
                maxgreentime = self.trafficlightinfo[f"intersection{i}"]["Timeinfo"][
                    "Maxtimegreen"
                ]
                self.trafficlightinfo[f"intersection{i}"]["Timeinfo"][
                    "Currenttimegreen"
                ] = (currenttimegreen + 1)
                if currenttimegreen > maxgreentime + 6:
                    carsinfront = np.nansum(self.tlightmatrix, axis=1)
                    totalcars = [0, 0, 0, 0]
                    for key in self.trafficlightinfo[f"intersection{i}"][
                        "Trafficlightinfo"
                    ].keys():
                        trafficlight = int(
                            self.trafficlightinfo[f"intersection{i}"][
                                "Trafficlightinfo"
                            ][key]
                        )
                        cars = carsinfront[trafficlight]
                        for j, combi in enumerate(self.lightcombinations):
                            if key in combi:
                                totalcars[j] = totalcars[j] + cars
                    # No cars? pick regular timeschedule
                    if sum(totalcars) == 0:
                        totalcars = [1, 1, 1, 1]
                    self.trafficlightinfo[f"intersection{i}"]["Timeinfo"][
                        "Currentgreen"
                    ] = totalcars.index(max(totalcars))
                    self.trafficlightinfo[f"intersection{i}"]["Timeinfo"][
                        "Maxtimegreen"
                    ] = (max(totalcars) / (sum(totalcars) / 4) * self.cycletime)
                    self.trafficlightinfo[f"intersection{i}"]["Timeinfo"][
                        "Currenttimegreen"
                    ] = 0
                if currenttimegreen == maxgreentime:
                    self.trafficlightinfo[f"intersection{i}"]["Timeinfo"][
                        "Currentgreen"
                    ] = -1

        # For the lookahead tactic
        if (
            self.tactic == "Lookahead"
            and len(self.schedule.agents) > 12 * self.intersections
        ):
            self.mostexpectedcars = [0, 0, 0]
            for i in range(self.intersections):
                currenttimegreen = self.trafficlightinfo[f"intersection{i}"][
                    "Timeinfo"
                ]["Currenttimegreen"]
                maxgreentime = self.trafficlightinfo[f"intersection{i}"]["Timeinfo"][
                    "Maxtimegreen"
                ]
                self.trafficlightinfo[f"intersection{i}"]["Timeinfo"][
                    "Currenttimegreen"
                ] = (currenttimegreen + 1)
                if currenttimegreen > maxgreentime + 6:
                    self.trafficlightinfo[f"intersection{i}"]["Timeinfo"]["Allred"] = 0
                    carsexpected = np.nansum(self.tlightmatrix, axis=0)
                    carsinfront = np.nansum(self.tlightmatrix, axis=1)
                    totalcars = [0, 0, 0, 0]
                    # For every direction + lane in intersection
                    for key in self.trafficlightinfo[f"intersection{i}"][
                        "Trafficlightinfo"
                    ].keys():
                        trafficlight = int(
                            self.trafficlightinfo[f"intersection{i}"][
                                "Trafficlightinfo"
                            ][key]
                        )
                        cars = carsinfront[trafficlight]
                        # For every lightcombination
                        for j, combi in enumerate(self.lightcombinations):
                            if key in combi:
                                totalcars[j] = (
                                    totalcars[j] + cars + carsexpected[trafficlight]
                                )
                                if totalcars[j] > self.mostexpectedcars[0]:
                                    self.mostexpectedcars[0] = totalcars[j]
                                    self.mostexpectedcars[1] = i
                                    self.mostexpectedcars[2] = j
                    # Reset timers
                    self.trafficlightinfo[f"intersection{i}"]["Timeinfo"][
                        "Currentgreen"
                    ] = (
                        self.trafficlightinfo[f"intersection{i}"]["Timeinfo"][
                            "Currentgreen"
                        ]
                        + 1
                    ) % 4
                    self.trafficlightinfo[f"intersection{i}"]["Timeinfo"][
                        "Maxtimegreen"
                    ] = self.cycletime
                    self.trafficlightinfo[f"intersection{i}"]["Timeinfo"][
                        "Currenttimegreen"
                    ] = 0
                if currenttimegreen == maxgreentime:
                    self.trafficlightinfo[f"intersection{i}"]["Timeinfo"]["Allred"] = 1
            if self.mostexpectedcars[0] != 0:
                # Change green light information of intersection with most expected cars
                self.trafficlightinfo[f"intersection{self.mostexpectedcars[1]}"][
                    "Timeinfo"
                ]["Currentgreen"] = self.mostexpectedcars[2]

                # Get trafficlightnumbers of ligths where most cars are expected
                mostcars = 0
                mostcarslight = None
                comingfrom = np.nansum(self.tlightmatrix, axis=1)
                for direction in self.lightcombinations[self.mostexpectedcars[2]]:
                    greenlight = int(
                        self.trafficlightinfo[
                            f"intersection{self.mostexpectedcars[1]}"
                        ]["Trafficlightinfo"][direction]
                    )
                    # Where the cars to those lights come from.
                    lightscomingfrom = np.argwhere(
                        ~np.isnan(self.tlightmatrix[:, greenlight])
                    )
                    for light in lightscomingfrom:
                        if light:
                            light = light[0]
                            carsinfront = np.sum(comingfrom[light])
                            if carsinfront > mostcars:
                                mostcars = int(carsinfront)
                                mostcarslight = light

                # Find intersection + directon of this light and change this intersection's green light information
                if mostcars != 0:
                    intersection = int(self.lights[mostcarslight][1][3])
                    direction = self.lights[mostcarslight][1][1:3]
                    for k, directs in enumerate(self.lightcombinations):
                        if direction in directs[0:3]:
                            self.trafficlightinfo[f"intersection{intersection}"][
                                "Timeinfo"
                            ]["Currentgreen"] = k
                            pass

        self.datacollector.collect(self)
        self.emission = [0, 0, 0]
        self.schedule.step()
예제 #39
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)
예제 #40
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
예제 #41
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()
예제 #42
0
    def __init__(self,
                 height=60,
                 width=60,
                 no_of_species=4,
                 no_of_seeds=2,
                 no_of_agents=20):
        '''
        Create a new MesaTraitsModel.

        Args:

        '''
        super().__init__()
        # Set parameters
        self.height = height
        self.width = width
        self.no_of_agents = no_of_agents

        self.schedule = RandomActivationByBreed(self)
        self.grid = MultiGrid(self.height, self.width, torus=True)
        self.no_of_species = no_of_species
        self.no_of_seeds = no_of_seeds
        self.patch_manager = PatchManager()

        self.datacollector = DataCollector(
            {"Organisms": lambda m: m.schedule.get_breed_count(Organism)})
        # Create patches
        for agent, x, y in self.grid.coord_iter():
            #print("new patch added")
            grown = False

            patch = Patch(self.next_id(), (x, y), self, 0.04, None, grown)
            self.grid.place_agent(patch, (x, y))
            self.schedule.add(patch)
            self.patch_manager.add_patch(patch)

        list_of_cells = []
        #select some random patches (without substitution)
        total_seeds = no_of_species * no_of_seeds
        for i in range(self.width):
            for j in range(self.height):
                list_of_cells.append((i, j))

        cords = random.sample(list_of_cells, total_seeds)

        #choose agents at those patches to be assigned the species
        _ = 0
        for i in range(no_of_species):
            for j in range(no_of_seeds):
                patch = self.grid.get_cell_list_contents(cords[_])
                patch[0].grown = True
                patch[0].species = i
                self.patch_manager.remove_patch(patch[0])
                _ += 1

        #make the patch grow
        self.patch_manager.grow_patches()

        # make moving agents
        for i in range(20):  #20 agents
            x = random.choice(range(self.width))
            y = random.choice(range(self.height))
            agent = Organism(self.next_id(), (x, y),
                             self,
                             energy_tank=100,
                             current_energy=50,
                             metabolic_cost=1,
                             energy_gain_per_patch=5,
                             age=5,
                             sexual=False,
                             maturity_age=20,
                             max_longevity=1000,
                             patch_affinity=[1, 1, 0, 0],
                             climatic_affinity=0.6,
                             climatic_affinity_sd=0.05,
                             line_of_sight=1,
                             dispersal_speed=2,
                             reproductive_delay=0,
                             offspring_number=1,
                             moore=True)
            self.grid.place_agent(agent, (x, y))
            self.schedule.add(agent)

        self.running = True
        self.datacollector.collect(self)
예제 #43
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))
    def __init__(self,
                 num_demolition,
                 num_construction,
                 recycling_tendency_percentage,
                 num_hubs=1,
                 event_rate_construction=5.,
                 event_rate_demolition=3.,
                 width=20,
                 height=20):

        super().__init__()

        self.width = width
        self.height = height

        ## TODO calculate duration
        #self.duration = calculate_lifespan(event_rate)

        self.duration = 37
        self.tick_counter = 0

        self.num_demolition = num_demolition
        self.num_construction = num_construction
        self.recycling_tendency = recycling_tendency_percentage / 100
        self.num_hubs = num_hubs

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

        self.datacollector = DataCollector(model_reporters={
            "Amount direct recycled":
            calculate_recycled,
            "Amount recycled via hub":
            calculate_recycled_hub,
            "Amount not recycled":
            calculate_not_recycled,
            "Amount raw material consumed":
            calculate_raw_material_consumed,
            "Stock level materials in hubs":
            get_stock_level_hubs,
            "Supply demolition materials":
            get_demolition_current_amount,
            "Demand construction materials":
            get_construction_current_amount
        },
                                           agent_reporters={
                                               "Amount":
                                               lambda agent: agent.unique_id
                                           })

        # create construction hubs
        if num_hubs > 0:
            hubs = []
            for i in range(self.num_hubs):
                a = RecyclingHub(self.next_id(), self)
                x = self.random.randrange(self.width)
                y = self.random.randrange(self.height)
                self.grid.place_agent(a, (x, y))
                hubs.append(a)
                self.schedule.add(a)

        # Create agents
        for i in range(self.num_demolition):
            hub = None
            if num_hubs > 0:
                hub = random.choice(hubs)

            a = DemolitionProjectAgent(
                self.next_id(),
                self,
                recycling_tendency=self.recycling_tendency,
                hub=hub,
                event_rate=event_rate_demolition,
                status=Status.passive,
                total_amount=100.)
            x = self.random.randrange(self.width)
            y = self.random.randrange(self.height)
            self.grid.place_agent(a, (x, y))
            self.schedule.add(a)

        for i in range(self.num_construction):
            hub = None
            if num_hubs > 0:
                hub = random.choice(hubs)

            a = ConstructionProjectAgent(self.next_id(),
                                         self,
                                         hub=hub,
                                         event_rate=event_rate_construction,
                                         status=Status.active,
                                         total_amount=100.)
            x = self.random.randrange(self.width)
            y = self.random.randrange(self.height)
            self.grid.place_agent(a, (x, y))
            self.schedule.add(a)

        self.running = True
        self.datacollector.collect(self)
예제 #45
0
class FireEvacuation(Model):
    MIN_HEALTH = 0.75
    MAX_HEALTH = 1

    MIN_SPEED = 1
    MAX_SPEED = 2

    MIN_NERVOUSNESS = 1
    MAX_NERVOUSNESS = 10

    MIN_EXPERIENCE = 1
    MAX_EXPERIENCE = 10

    MIN_VISION = 1
    # MAX_VISION is simply the size of the grid

    def __init__(self, floor_plan_file, human_count, collaboration_percentage, fire_probability, visualise_vision, random_spawn, save_plots):
        # Load floorplan
        # floorplan = np.genfromtxt(path.join("fire_evacuation/floorplans/", floor_plan_file))
        with open(os.path.join("fire_evacuation/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.width = width
        self.height = height
        self.human_count = human_count
        self.collaboration_percentage = collaboration_percentage
        self.visualise_vision = visualise_vision
        self.fire_probability = fire_probability
        self.fire_started = False  # Turns to true when a fire has started
        self.save_plots = save_plots

        # Set up model objects
        self.schedule = RandomActivation(self)

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

        # Used to start a fire at a random furniture location
        self.furniture_list = []

        # Used to easily see if a location is a FireExit or Door, since this needs to be done a lot
        self.fire_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 is "W":
                floor_object = Wall((x, y), self)
            elif value is "E":
                floor_object = FireExit((x, y), self)
                self.fire_exit_list.append((x, y))
                self.door_list.append((x, y))  # Add fire exits to doors as well, since, well, they are
            elif value is "F":
                floor_object = Furniture((x, y), self)
                self.furniture_list.append((x, y))
            elif value is "D":
                floor_object = Door((x, y), self)
                self.door_list.append((x, y))
            elif value is "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)

        # Collects statistics from our model run
        self.datacollector = DataCollector(
            {
                "Alive": lambda m: self.count_human_status(m, Human.Status.ALIVE),
                "Dead": lambda m: self.count_human_status(m, Human.Status.DEAD),
                "Escaped": lambda m: self.count_human_status(m, Human.Status.ESCAPED),
                "Incapacitated": lambda m: self.count_human_mobility(m, Human.Mobility.INCAPACITATED),
                "Normal": lambda m: self.count_human_mobility(m, Human.Mobility.NORMAL),
                "Panic": lambda m: self.count_human_mobility(m, Human.Mobility.PANIC),
                "Verbal Collaboration": lambda m: self.count_human_collaboration(m, Human.Action.VERBAL_SUPPORT),
                "Physical Collaboration": lambda m: self.count_human_collaboration(m, Human.Action.PHYSICAL_SUPPORT),
                "Morale Collaboration": lambda m: self.count_human_collaboration(m, Human.Action.MORALE_SUPPORT)
            }
        )

        # Calculate how many agents will be collaborators
        number_collaborators = int(round(self.human_count * (self.collaboration_percentage / 100)))

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

                if number_collaborators > 0:
                    collaborates = True
                    number_collaborators -= 1
                else:
                    collaborates = False

                # Vision statistics obtained from http://www.who.int/blindness/GLOBALDATAFINALforweb.pdf
                vision_distribution = [0.0058, 0.0365, 0.0424, 0.9153]
                vision = int(np.random.choice(np.arange(self.MIN_VISION, self.width + 1, (self.width / len(vision_distribution))), p=vision_distribution))

                nervousness_distribution = [0.025, 0.025, 0.1, 0.1, 0.1, 0.3, 0.2, 0.1, 0.025, 0.025]  # Distribution with slight higher weighting for above median nerovusness
                nervousness = int(np.random.choice(range(self.MIN_NERVOUSNESS, self.MAX_NERVOUSNESS + 1), p=nervousness_distribution))  # Random choice starting at 1 and up to and including 10

                experience = random.randint(self.MIN_EXPERIENCE, self.MAX_EXPERIENCE)

                belief_distribution = [0.9, 0.1]  # [Believes, Doesn't Believe]
                believes_alarm = np.random.choice([True, False], p=belief_distribution)

                human = Human(pos, health=health, speed=speed, vision=vision, collaborates=collaborates, nervousness=nervousness, experience=experience, believes_alarm=believes_alarm, model=self)

                self.grid.place_agent(human, pos)
                self.schedule.add(human)
            else:
                print("No tile empty for human placement!")

        self.running = True

    # Plots line charts of various statistics from a run
    def save_figures(self):
        DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
        OUTPUT_DIR = DIR + "/output"

        results = self.datacollector.get_model_vars_dataframe()

        dpi = 100
        fig, axes = plt.subplots(figsize=(1920 / dpi, 1080 / dpi), dpi=dpi, nrows=1, ncols=3)

        status_results = results.loc[:, ['Alive', 'Dead', 'Escaped']]
        status_plot = status_results.plot(ax=axes[0])
        status_plot.set_title("Human Status")
        status_plot.set_xlabel("Simulation Step")
        status_plot.set_ylabel("Count")

        mobility_results = results.loc[:, ['Incapacitated', 'Normal', 'Panic']]
        mobility_plot = mobility_results.plot(ax=axes[1])
        mobility_plot.set_title("Human Mobility")
        mobility_plot.set_xlabel("Simulation Step")
        mobility_plot.set_ylabel("Count")

        collaboration_results = results.loc[:, ['Verbal Collaboration', 'Physical Collaboration', 'Morale Collaboration']]
        collaboration_plot = collaboration_results.plot(ax=axes[2])
        collaboration_plot.set_title("Human Collaboration")
        collaboration_plot.set_xlabel("Simulation Step")
        collaboration_plot.set_ylabel("Successful Attempts")
        collaboration_plot.set_ylim(ymin=0)

        timestr = time.strftime("%Y%m%d-%H%M%S")
        plt.suptitle("Percentage Collaborating: " + str(self.collaboration_percentage) + "%, Number of Human Agents: " + str(self.human_count), fontsize=16)
        plt.savefig(OUTPUT_DIR + "/model_graphs/" + timestr + ".png")
        plt.close(fig)

    # Starts a fire at a random piece of furniture with file_probability chance
    def start_fire(self):
        rand = random.random()
        if rand < self.fire_probability:
            fire_furniture = random.choice(self.furniture_list)
            fire = Fire(fire_furniture, self)
            self.grid.place_agent(fire, fire_furniture)
            self.schedule.add(fire)
            self.fire_started = True
            print("Fire started at:", fire_furniture)

    def step(self):
        """
        Advance the model by one step.
        """

        self.schedule.step()

        # If there's no fire yet, attempt to start one
        if not self.fire_started:
            self.start_fire()

        self.datacollector.collect(self)

        # If no more agents are alive, stop the model and collect the results
        if self.count_human_status(self, Human.Status.ALIVE) == 0:
            self.running = False

            if self.save_plots:
                self.save_figures()

    @staticmethod
    def count_human_collaboration(model, collaboration_type):
        """
        Helper method to count the number of collaborations performed by Human agents in the model
        """

        count = 0
        for agent in model.schedule.agents:
            if isinstance(agent, Human):
                if collaboration_type == Human.Action.VERBAL_SUPPORT:
                    count += agent.get_verbal_collaboration_count()
                elif collaboration_type == Human.Action.MORALE_SUPPORT:
                    count += agent.get_morale_collaboration_count()
                elif collaboration_type == Human.Action.PHYSICAL_SUPPORT:
                    count += agent.get_physical_collaboration_count()

        return count

    @staticmethod
    def count_human_status(model, status):
        """
        Helper method to count the status of Human agents in the model
        """
        count = 0
        for agent in model.schedule.agents:
            if isinstance(agent, Human):
                if agent.get_status() == status:
                    count += 1
        return count

    @staticmethod
    def count_human_mobility(model, mobility):
        """
        Helper method to count the mobility of Human agents in the model
        """
        count = 0
        for agent in model.schedule.agents:
            if isinstance(agent, Human):
                if agent.get_mobility() == mobility:
                    count += 1
        return count
예제 #46
0
    def __init__(self, no_people, total_area, no_agents, Nc_N, n, all_x, all_y, centers, infection_rate, city_label,
                 no_steps):
        self.num_agents = no_agents
        grid_size = round(math.sqrt((self.num_agents / no_people) * total_area) * 100)
        self.grid = MultiGrid(grid_size, grid_size, False)
        self.schedule = RandomActivation(self)
        self.running = True

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

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

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

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

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

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

                if Tij > 75:
                    Tij = 75

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

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

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

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

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

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

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

            if i == 1:
                a.infected = 1

        self.datacollector = DataCollector(
            model_reporters={"Tot informed": compute_informed},
            agent_reporters={"Infected": "infected"})
예제 #47
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))
예제 #48
0
class MSUvUoMPredation(Model):
    '''
    MSUvUoM Predation Model
    '''

    height = 20
    width = 20

    initial_UoM = 100
    initial_MSU = 50

    UoM_reproduce = 0.04
    MSU_reproduce = 0.05

    MSU_gain_from_food = 20

    grass = False
    grass_regrowth_time = 30
    UoM_gain_from_food = 4

    verbose = True  # Print-monitoring

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

    def __init__(self,
                 height=20,
                 width=20,
                 initial_UoM=100,
                 initial_MSU=50,
                 UoM_reproduce=0.04,
                 MSU_reproduce=0.05,
                 MSU_gain_from_food=20,
                 grass=False,
                 grass_regrowth_time=30,
                 UoM_gain_from_food=4):
        '''
        Create a new MSU vs UoM model with the given parameters.

        Args:
            initial_UoM: Number of UoM to start with
            initial_MSU: Number of MSU to start with
            UoM_reproduce: Probability of each UoM reproducing each step
            MSU_reproduce: Probability of each MSU reproducing each step
            MSU_gain_from_food: Energy a MSU gains from eating a UoM
            grass: Whether to have the UoM eat grass for energy
            grass_regrowth_time: How long it takes for a grass patch to regrow
                                 once it is eaten
            UoM_gain_from_food: Energy UoM gain from grass, if enabled.
        '''

        # Set parameters
        self.height = height
        self.width = width
        self.initial_UoM = initial_UoM
        self.initial_MSU = initial_MSU
        self.UoM_reproduce = UoM_reproduce
        self.MSU_reproduce = MSU_reproduce
        self.MSU_gain_from_food = MSU_gain_from_food
        self.grass = grass
        self.grass_regrowth_time = grass_regrowth_time
        self.UoM_gain_from_food = UoM_gain_from_food

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

        # Create UoM:
        for i in range(self.initial_UoM):
            x = random.randrange(self.width)
            y = random.randrange(self.height)
            energy = random.randrange(2 * self.UoM_gain_from_food)
            student = UoM((x, y), self, True, energy)
            self.grid.place_agent(student, (x, y))
            self.schedule.add(student)

        # Create MSU
        for i in range(self.initial_MSU):
            x = random.randrange(self.width)
            y = random.randrange(self.height)
            energy = random.randrange(2 * self.MSU_gain_from_food)
            student = MSU((x, y), self, True, energy)
            self.grid.place_agent(student, (x, y))
            self.schedule.add(student)

        # 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(MSU),
                self.schedule.get_breed_count(UoM)
            ])

    def run_model(self, step_count=200):

        if self.verbose:
            print('Initial number MSU: ', self.schedule.get_breed_count(MSU))
            print('Initial number UoM: ', self.schedule.get_breed_count(UoM))

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

        if self.verbose:
            print('')
            print('Final number MSU: ', self.schedule.get_breed_count(MSU))
            print('Final number UoM: ', self.schedule.get_breed_count(UoM))
예제 #49
0
    def __init__(self, height, width, color, numAgents, gDense, kRate, dcDiffu,
                 dhRes, dtRes, secRate):
        # number of agents per tile
        self.n = numAgents
        # grid density
        self.gD = gDense
        # rate of cAMP decay
        self.k = 0.1
        # diffusion constant of cAMP
        self.Dc = dcDiffu
        # spatial resolution for cAMP simulation
        self.Dh = dhRes
        # time resolution for cAMP simulation
        self.Dt = dtRes
        # rate of cAMP secretion by an agent
        self.f = secRate
        # number of rows/columns in spatial array
        self.w = masterHeight
        # agent color
        self.color = color

        # height of grid
        self.height = masterHeight
        # width of grid
        self.width = masterWidth

        # Counter for generating sequential unique id's
        self.j = 0
        # Counter for DataVis agents' unique id's
        self.dv = 0
        # Counter for NumDataVis agents' unique id's
        self.ndv = 0

        # Blacklist for agents in clustering
        self.blacklist = list()
        # List for current cluser agents
        self.cluster_agents = list()
        # List for cluster neighbors
        self.cluster_neighbors = list()
        # List to check how many cells have been examined during cluster detection
        self.cells = 0

        # Create randomly ordered scheduler
        self.schedule = SimultaneousActivation(self)
        # Create grid (of type MultiGrid to support multiple agents per cell
        self.grid = MultiGrid(self.width, self.height, torus=False)

        # Initialize list of cAMP molecules
        self.cAMPs = list()

        # Initialize dict for datacollector with total datacollector
        dc = {"Total Amount of cAMP": self.getAmts}

        # Initialize for iterating through columns (x) and rows (y)
        self.x = 0
        self.y = 0

        # Loop to fill datacollector dictionary with dict entries for each column and row
        for x in range(masterWidth):
            dc.update({("x: " + str(x)): self.getColAmts})
            dc.update({("y: " + str(x)): self.getRowAmts})

        # Create datacollector to retrieve total amounts of cAMP from dc dict created above
        self.datacollector = DataCollector(dc)

        # Variable for storing random numbers
        r = 0

        # Initial loop to create agents and fill agents list with them
        for (contents, x, y) in self.grid.coord_iter():
            # Create object of type cAMP
            cell = cAMP([x, y], self, self.j, 0, self.k)
            # Add random amoutn of cAMP to cell (<1)
            cell.add(random.random())
            # Place cAMP onto grid at coordinates x, y
            self.grid._place_agent((x, y), cell)
            # Add cAMP molecule to list
            self.cAMPs.append(cell)

            # print("x:", x, " y:", y)

            if x == 50:
                # Create DataVis agent
                ag = DataVis([x, y], self, self.dv)
                # Place DataVis agent
                self.grid.place_agent(ag, tuple([x, y]))

                # Increment unique id counter
                self.dv += 1
            elif x > 50:
                # Create NumDataVis agent with appropriate slice num
                ag = NumDataVis([x, y], self, self.ndv)
                # Place NumDataVis agent
                self.grid.place_agent(ag, tuple([x, y]))

                # Increment unique id counter
                self.ndv += 1
            else:
                # Loop to create SlimeAgents
                if self.gD % 1 != 0:
                    r = random.random()
                    if r <= self.gD:
                        for i in range(self.n):
                            # Create object of type SlimeAgent
                            ag = SlimeAgent([x, y], self, self.j, 10,
                                            self.color)
                            ag.setSecRate(5)
                            # Place agent onto grid at coordinates x, y
                            self.grid.place_agent(ag, tuple([x, y]))
                            # Add agent to schedule
                            self.schedule.add(ag)
                            # Increment j (unique_id variable)
                            self.j += 1
                else:
                    for i in range(self.n):
                        # Create object of type SlimeAgent
                        ag = SlimeAgent([x, y], self, self.j, 10, self.color)
                        ag.setSecRate(5)
                        # Place agent onto grid at coordinates x, y
                        self.grid.place_agent(ag, tuple([x, y]))
                        # Add agent to schedule
                        self.schedule.add(ag)
                        # Increment j (unique_id variable)
                        self.j += 1

        # Print out number of agents
        print("# of agents:", self.j)

        self.running = True
예제 #50
0
    def __init__(self,
                 height=20,
                 width=20,
                 initial_UoM=100,
                 initial_MSU=50,
                 UoM_reproduce=0.04,
                 MSU_reproduce=0.05,
                 MSU_gain_from_food=20,
                 grass=False,
                 grass_regrowth_time=30,
                 UoM_gain_from_food=4):
        '''
        Create a new MSU vs UoM model with the given parameters.

        Args:
            initial_UoM: Number of UoM to start with
            initial_MSU: Number of MSU to start with
            UoM_reproduce: Probability of each UoM reproducing each step
            MSU_reproduce: Probability of each MSU reproducing each step
            MSU_gain_from_food: Energy a MSU gains from eating a UoM
            grass: Whether to have the UoM eat grass for energy
            grass_regrowth_time: How long it takes for a grass patch to regrow
                                 once it is eaten
            UoM_gain_from_food: Energy UoM gain from grass, if enabled.
        '''

        # Set parameters
        self.height = height
        self.width = width
        self.initial_UoM = initial_UoM
        self.initial_MSU = initial_MSU
        self.UoM_reproduce = UoM_reproduce
        self.MSU_reproduce = MSU_reproduce
        self.MSU_gain_from_food = MSU_gain_from_food
        self.grass = grass
        self.grass_regrowth_time = grass_regrowth_time
        self.UoM_gain_from_food = UoM_gain_from_food

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

        # Create UoM:
        for i in range(self.initial_UoM):
            x = random.randrange(self.width)
            y = random.randrange(self.height)
            energy = random.randrange(2 * self.UoM_gain_from_food)
            student = UoM((x, y), self, True, energy)
            self.grid.place_agent(student, (x, y))
            self.schedule.add(student)

        # Create MSU
        for i in range(self.initial_MSU):
            x = random.randrange(self.width)
            y = random.randrange(self.height)
            energy = random.randrange(2 * self.MSU_gain_from_food)
            student = MSU((x, y), self, True, energy)
            self.grid.place_agent(student, (x, y))
            self.schedule.add(student)

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

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

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

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

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

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

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

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

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

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

        # Creation of land parcels
        land_parcel_count = 0

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

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

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

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

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

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

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

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

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

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

                last_birth_time = random.uniform(0, 1)

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

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

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

    compGregSheep = 1
    compGregWolf = 1

    verbose = True  # 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,
                 compGregSheep=1,
                 compGregWolf=0):
        '''
        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.compGregSheep = compGregSheep
        self.compGregWolf = compGregWolf

        self.energy_totale = 0

        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)
            self.energy_totale += energy
            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 = random.randrange(self.width)
            y = random.randrange(self.height)
            energy = random.randrange(2 * self.wolf_gain_from_food)
            self.energy_totale += energy
            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 = random.choice([True, False])

                if fully_grown:
                    countdown = self.grass_regrowth_time
                else:
                    countdown = 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.energy_totale = 0
        self.schedule.step()
        # collect data

        if self.verbose:
            result = [
                self.schedule.time,
                self.schedule.get_breed_count(Wolf),
                self.schedule.get_breed_count(Sheep), self.energy_totale
            ]
            fitness = result[3] / (result[1] + result[2])
            print('fitness:', fitness)
        return (fitness)

    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))
            print('energie totale:', self.energy_totale)
예제 #53
0
    def __init__(self, spawnrate, tactic, offset, cycletime):
        # Variable parameters
        self.tactic = tactic  # [ Offset, Proportional, Lookahead, GreenWave]
        self.spawnrate = spawnrate
        self.offset = offset
        self.slowmotionrate = 0.2
        self.cycletime = cycletime

        # Value initializations
        self.emission = [0, 0, 0]  # emission per step
        self.traveltime = []
        self.averagetraveltime = 0
        self.carID = 0
        self.averageemission = []

        # Reading roadmap and emission values
        self.emissionvalues = reademissionvalues()
        [
            self.roadmap,
            self.spawns,
            self.lights,
            self.height,
            self.cellsperlane,
            self.intersections,
            self.streetlength,
            self.gridsize,
        ] = readroadmap()

        # Model and visualization parameters
        self.schedule = RandomActivation(self)
        self.width = self.height
        self.grid = MultiGrid(self.width, self.height, True)
        self.running = True

        # Initializing matrix which shows what cars in front of traffic lights go to what over traffic lights.
        self.tlightmatrix = np.empty((len(self.lights), len(self.lights)))
        self.tlightmatrix[:] = np.nan
        self.trafficlightlist = []
        self.lightcombinations = [
            ["SR", "SD", "SL", "WR"],
            ["ER", "ED", "EL", "SR"],
            ["NR", "ND", "NL", "ER"],
            ["WR", "WD", "WL", "NR"],
        ]

        # Data collection
        self.datacollector = DataCollector(
            model_reporters={
                "tactic": "tactic",
                "Spawnrate": "spawnrate",
                "Offset": "offset",
                "Cycletime": "cycletime",
                "AverageTraveltime": "averagetraveltime",
                "Totalcars": lambda m: self.numberofcars(),
                "CO2": lambda m: self.getco2(),
                "NOx": lambda m: self.getnox(),
                "PM10": lambda m: self.getpm(),
                "AverageCO2": lambda m: self.getaverageco2(),
                "AverageNOx": lambda m: self.getaveragenox(),
                "AveragePM": lambda m: self.getaveragepm(),
            },
        )

        # Needed for green wave tactic
        self.mostcars = []
        self.goesto = []
        self.firstgreenintersection = -1
        self.secondgreenintersection = -1
        self.firstcombination = None
        self.secondcombination = None
        self.firstcycledone = 0

        # Needed for lookahead tactic
        self.mostexpectedcars = [0, 0, 0]  # cars,intersection,combination

        # results in list of lists with intersectionnumbers in the right place, e.g.: [[0, 1],[2,3]]
        # Needed for the offset tactic to know which lights to offset
        self.intersectionmatrix = []
        lastnumber = 0
        for i in range(int(math.sqrt(self.intersections))):
            tempmaptrix = []
            for j in range(int(math.sqrt(self.intersections))):
                tempmaptrix.append(j + lastnumber)
            lastnumber = tempmaptrix[-1] + 1
            self.intersectionmatrix.append(tempmaptrix)
        self.intersectionmatrix = np.array(self.intersectionmatrix)

        # Initialize information dictionary (which lights are suppesed to be green and how long they have been green for
        self.trafficlightinfo = {}
        for i in range(self.intersections):
            self.trafficlightinfo.update(
                {f"intersection{i}": {"Trafficlightinfo": {}, "Timeinfo": {}}}
            )

        # Initializes traffic lights
        for i, light in enumerate(self.lights):
            self.trafficlightinfo[f"intersection{light[1][3]}"]["Trafficlightinfo"][
                f"{light[1][1:3]}"
            ] = i
            self.trafficlightinfo[f"intersection{light[1][3]}"]["Timeinfo"].update(
                {
                    "Currentgreen": -1,
                    "Currenttimegreen": 0,
                    "Maxtimegreen": 0,
                    "Allred": 1,
                }
            )
            intersectionnumber = int(light[1][3])
            intersectiony = np.where(self.intersectionmatrix == intersectionnumber)[0]
            intersectionx = np.where(self.intersectionmatrix == intersectionnumber)[1]
            direction = light[1][1]
            lane = light[1][2]
            location = light[0]
            xlocation = int(location[0])
            ylocation = self.height - 1 - int(location[1])
            trafficlight = TrafficLightAgent(
                f"{xlocation},{ylocation},{light[1][1:3]}",
                self,
                "red",
                direction,
                lane,
                i,
                intersectionnumber,
                self.tactic,
                self.offset,
                [intersectionx, intersectiony],
                self.cycletime,
            )
            self.trafficlightlist.append([light[1], i])
            self.schedule.add(trafficlight)
            self.grid.place_agent(trafficlight, (xlocation, ylocation))
        self.tlightmatrix = lightconnection(
            self.tlightmatrix, self.trafficlightlist, self.intersections
        )

        # Place legend
        self.grid.place_agent(LegendCarIcon("Caricon", self), (65, 68))
        self.grid.place_agent(LegendGreenTlightIcon("GreenTlighticon", self), (65, 69))
        self.grid.place_agent(LegendRedTlightIcon("RedTlighticon", self), (65, 70))
예제 #54
0
class Themepark(Model):
    def __init__(self, N_attr, N_cust, width, height, strategy, theme, max_time, weight, adaptive):
        self.theme = theme
        self.max_time = max_time
        self.N_attr = N_attr
        self.penalty_per = PENALTY_PERCENTAGE
        self.weight = weight
        self.adaptive = adaptive
        self.strategies = STRATEGIES
        self.x_list, self.y_list, self.positions = xlist, ylist, positions
        self.x_list, self.y_list, self.positions = get_attraction_coordinates(WIDTH, HEIGHT, self.N_attr, theme)
        self.happinesses = []
        self.starting_positions = [[int((WIDTH/2)-1), 0], [int(WIDTH/2), 0], [int((WIDTH/2)+1), 0]]
        self.path_coordinates = get_coordinates(WIDTH, HEIGHT, NUM_OBSTACLES, self.N_attr, theme)
        self.N_attr = N_attr    # num of attraction agents
        self.N_cust = N_cust    # num of customer agents
        self.width = width
        self.height = height
        self.total_steps = 0
        self.cust_ids = N_cust
        self.strategy = strategy
        self.grid = MultiGrid(width, height, torus=False)
        self.schedule = BaseScheduler(self)
        self.schedule_Attraction = BaseScheduler(self)
        self.schedule_Customer = BaseScheduler(self)
        self.totalTOTAL = 0
        self.attractions = self.make_attractions()
        self.attraction_history = self.make_attr_hist()
        self.running = True
        self.data = []
        self.data_customers = []
        self.park_score = []
        self.data_dict = {}
        self.hist_random_strat = []
        self.hist_close_strat = []
        self.all_rides_list = []
        self.strategy_composition = self.make_strategy_composition()
        self.memory = 5
        self.customer_score = []
        self.customers = self.add_customers(self.N_cust)
        self.only_random = False


        for attraction in self.get_attractions():
            self.data_dict[attraction.unique_id] = ({
                               "id": attraction.unique_id,
                               "length": attraction.attraction_duration,
                               "waiting_list": []})

        if len(self.strategies) == 6:
            self.datacollector = DataCollector(

                {"Random": lambda m: self.strategy_counter(self.strategies[0]),
                "0.00": lambda m: self.strategy_counter(self.strategies[1]),
                "0.25": lambda m: self.strategy_counter(self.strategies[2]),
                "0.50": lambda m: self.strategy_counter(self.strategies[3]),
                "0.75": lambda m: self.strategy_counter(self.strategies[4]),
                "1.00": lambda m: self.strategy_counter(self.strategies[5]),
                })
        else:
            self.datacollector = DataCollector(
                {"0.00": lambda m: self.strategy_counter(self.strategies[0]),
                "0.25": lambda m: self.strategy_counter(self.strategies[1]),
                "0.50": lambda m: self.strategy_counter(self.strategies[2]),
                "0.75": lambda m: self.strategy_counter(self.strategies[3]),
                "1.00": lambda m: self.strategy_counter(self.strategies[4]),
                })

        self.datacollector2 = DataCollector(
            {"score": lambda m: self.make_score()})

        self.total_waited_time = 0

        self.monitor = Monitor(self.max_time, self.N_attr, self.positions)

    def make_score(self):
        ideal = {}
        cust_in_row = 0
        for i in range(len(self.get_attractions())):
            ideal[i] = self.N_cust/self.N_attr
            cust_in_row += self.get_attractions()[i].N_current_cust

        tot_difference = 0
        for i in range(len(self.get_attractions())):

            difference = abs(cust_in_row/self.N_attr  - self.get_attractions()[i].N_current_cust)
            tot_difference += difference

        fraction_not_right = (tot_difference/self.N_cust)
        return abs(1-(fraction_not_right)) * cust_in_row/self.N_cust

    def make_attr_hist(self):
        attraction_history = {}
        for attraction in self.get_attractions():

            attraction_history[attraction] = [0] * (self.max_time + 1)
        return attraction_history

    def strategy_counter(self, strategy):
        counter_total = {}

        for attraction_pos in self.positions:

            agents = self.grid.get_neighbors(
                attraction_pos,
                moore=True,
                radius=0,
                include_center=True
            )

            counter = 0
            for agent in self.customers:
                if agent.weight == strategy:
                    counter += 1

        return counter

    def make_strategy_composition(self):
        if self.strategy == "Random_test_4":
            self.strategies = ["Random_test_4", 0.0, 0.25, 0.50, 0.75, 1.0]
            dict = {self.strategies[0]: 1/6, self.strategies[1]:0.20, self.strategies[2]:0.20,
                            self.strategies[3]:0.20, self.strategies[4]:0.20, self.strategies[5]: 0.20}

            composition_list = []
            for i in range(len(self.strategies)):
                if i == 0:
                    dict[self.strategies[i]] = FRACTION_RANDOM
                    continue
                else:
                    composition_list.append(random.randint(0,100))
            sum_comp = sum(composition_list)

            sum_comp = sum_comp - sum_comp * FRACTION_RANDOM
            for i in range(len(self.strategies)):
                if i == 0:
                    continue
                else:
                    dict[self.strategies[i]] = composition_list[i-1] /sum_comp

        else:
            dict = {self.strategies[0]: 0.20, self.strategies[1]:0.20, self.strategies[2]:0.20,
                            self.strategies[3]:0.20, self.strategies[4]:0.20}

            composition_list = []
            for i in range(len(self.strategies)):

                composition_list.append(random.randint(0,100))

            sum_comp = sum(composition_list)

            sum_comp = sum_comp
            for i in range(len(self.strategies)):

                dict[self.strategies[i]] = composition_list[i-1] /sum_comp



        return dict

    def make_attractions(self):
        """ Initialize attractions on fixed position."""

        attractions = {}
        for i in range(self.N_attr):

            pos = (self.x_list[i], self.y_list[i])
            if self.grid.is_cell_empty(pos):

                name = str(i)
                a = Attraction(i, self, pos, name, self.N_cust, self.weight)
                attractions[i] = a

                self.schedule_Attraction.add(a)
                self.grid.place_agent(a, pos)
        return attractions

    def get_attractions(self):
        """
        Get a list with all attractions
        """
        agents = self.grid.get_neighbors(
            mid_point,
            moore=True,
            radius=RADIUS,
            include_center=True)

        attractions = []
        for agent in agents:
            if type(agent) == Attraction:
                attractions.append(agent)

        return attractions

    def add_customers(self, N_cust, added=False):
        """ Initialize customers on random positions."""

        weights_list = []
        if self.adaptive is True:

            for j in self.strategy_composition.keys():
                for i in range(round(N_cust*self.strategy_composition[j])):
                    weights_list.append(j)

            if len(weights_list) < self.N_cust:
                rand = random.choice(self.strategies)
                weights_list.append(rand)
            elif len(weights_list) > self.N_cust:
                rand = random.choice(weights_list)
                weights_list.remove(rand)


        else:
            if self.strategy is not "Random":

                # do what normally is done
                for i in range(round(N_cust)):
                    weights_list.append(self.weight)


        cust_list = []
        # weight_counter = 0
        # pick_weight = 0
        for i in range(N_cust):

            # pos_temp = random.choice(self.starting_positions)
            pos_temp = [random.randint(0,WIDTH-1), random.randint(0,HEIGHT-1)]
            rand_x, rand_y = pos_temp[0], pos_temp[1]

            pos = (rand_x, rand_y)

            if added is True:
                i = self.cust_ids
            if self.strategy == "Random_test_4":
                if weights_list[i] == "Random_test_4":
                    strategy = "Random_test_4"
                else:
                    strategy = "Closest_by"
            else:
                strategy = self.strategy


            # Deze if is omdat bij alleen random self.weight none is!
            if weights_list == []:
                weight = None
            else:
                weight = weights_list[i]
            a = Customer(i, self, pos, self.x_list, self.y_list, self.positions, strategy, weight, self.adaptive)

            self.schedule_Customer.add(a)

            self.grid.place_agent(a, pos)
            cust_list.append(a)

        return cust_list

    def calculate_people(self):
        """Calculate how many customers are in which attraction."""

        counter_total = {}

        for attraction_pos in self.positions:

            agents = self.grid.get_neighbors(
                attraction_pos,
                moore=True,
                radius=0,
                include_center=True
            )

            counter = 0
            for agent in agents:
                if type(agent) is Customer:
                    counter += 1
                else:
                    attraction = agent

            attraction.N_current_cust = counter
            counter_total[attraction.unique_id] = counter

        return list(counter_total.values())

    def calc_waiting_time(self):

        counter_total = {}

        attractions = self.get_attractions()
        for attraction in attractions:

            counter_total[attraction.unique_id] = attraction.current_waitingtime

        return counter_total


    def calculate_people_sorted(self):
        """
        Calculate how many customers are in which attraction.
        Returns a SORTED LIST.
        For example: indexes = [3, 2, 5, 1, 4]
        indicates that attraction3 has the least people waiting.
        """

        counter_total = {}

        for attraction_pos in self.positions:

            agents = self.grid.get_neighbors(
                attraction_pos,
                moore=True,
                radius=0,
                include_center=True
            )

            counter = 0
            for agent in agents:
                if type(agent) is Customer:
                    counter += 1
                else:
                    attraction = agent

            attraction.N_current_cust = counter
            self.attraction_history[attraction][self.totalTOTAL] = counter
            counter_total[attraction.unique_id] = counter
        return counter_total

    def make_route(self):
        """Draw coordinates of a possible path."""

        for i in range(len(self.path_coordinates)):
            pos = self.path_coordinates[i]

            if pos not in self.positions:

                # Create path agent
                path = Route(i, self, pos)
                self.schedule.add(path)

                self.grid.place_agent(path, pos)

    def get_themepark_score(self):
        """
        Get score of a themepark based on:
            - A total of all waitingtimes for every customer
            - TODO
        """
        attractions = self.get_attractions()
        total_wait, total_rides = 0, 0
        for attraction in attractions:
            total_wait += attraction.current_waitingtime

            if attraction.current_a is not None:
                total_rides += 1

        if total_rides == 0:
            return total_rides

        return (total_wait / total_rides)

    def get_strategy_history(self):
        """ Update history with how many customers chose which strategy """

        customers = self.get_customers()
        randomstrat, closebystrat = 0, 0

        for customer in customers:
            if customer.strategy == "Random" or customer.strategy == "Random_test_4":
                randomstrat += 1
            elif customer.strategy == "Closest_by":
                closebystrat += 1

        self.hist_random_strat.append(randomstrat)
        self.hist_close_strat.append(closebystrat)

    def get_customers(self):
        agents = self.grid.get_neighbors(
            mid_point,
            moore=True,
            radius=RADIUS,
            include_center=True)

        customers = []

        # Count customer agents
        for agent in agents:
            if type(agent) == Customer:
                customers.append(agent)
        return customers

    def get_data_customers(self):
        """ Return dictionary with data of customers """

        data = {}
        agents = self.grid.get_neighbors(
            mid_point,
            moore=True,
            radius=RADIUS,
            include_center=True)

        for agent in agents:
            if type(agent) is Customer:
                data[agent.unique_id] = {
                "totalwaited": agent.total_ever_waited,
                "visited_attractions": agent.nmbr_attractions,
                "strategy": agent.strategy,
                "swapped_strat": agent.strategy_swap_hist
                }
        return data

    def calc_hapiness(self):
        """
        Calculate mean hapiness of all customers, based on:

        - How many rides were taken
        - Number of times in the same attraction
        - Total waiting time
        """
        customers = self.get_customers()

        scores = []



        for customer in customers:
            history = customer.history
            values = list(history.values())
            total_rides = sum(values)

            if total_rides != 0:
                scores.append(total_rides / self.N_attr - self.totalTOTAL / customer.total_ever_waited)
            else:
                return None

        scores = np.interp(scores, (min(scores), max(scores)), (1, 10))
        return np.mean(scores)

    def get_history_list(self):

        customers = self.get_customers()


        histories = {}

        for customer in customers:
            history = customer.history
            values = list(history.values())
            histories[customer.unique_id] = values
        return histories

    def final(self):
        """ Return data """
        hist_list = []
        agents = self.grid.get_neighbors(
            mid_point,
            moore=True,
            radius=RADIUS,
            include_center=True)

        attractions = self.get_attractions()
        self.all_rides_list = [0] * len(attractions[0].in_attraction_list)
        for attraction in attractions:
            for i in range(len(attraction.in_attraction_list)):
                self.all_rides_list[i] += attraction.in_attraction_list[i]

        for i in range(len(self.all_rides_list)):
            self.all_rides_list[i] /= self.N_attr
        print("ALL RIDES LIST", self.all_rides_list)

        cust_data = self.get_data_customers()
        for agent in agents:
            if type(agent) is Customer:
                sum_attr = sum(agent.history.values())
                if sum_attr > 0:
                    hist_list.append(agent.strategy_swap_hist)
                else:
                    hist_list.append(agent.strategy_swap_hist)
                # print("swap:",agent.strategy_swap_hist , "sum:",sum_attr)


        # plt.hist(hist_list)
        # plt.show()

        histories = self.get_history_list()

        # save data
        try:
            pickle.dump(self.datacollector.get_model_vars_dataframe(), open("../data/strategy_history.p", 'wb'))
            pickle.dump(self.datacollector2.get_model_vars_dataframe(), open("../data/eff_score_history.p", 'wb'))
            pickle.dump(cust_data, open("../data/customers.p", 'wb'))
            pickle.dump(self.park_score[-1], open("../data/park_score.p", "wb"))
            pickle.dump(self.happinesses, open("../data/hapiness.p", "wb"))
            pickle.dump(histories, open("../data/cust_history.p", 'wb'))
        except:
            pickle.dump(self.datacollector.get_model_vars_dataframe(), open("data/strategy_history.p", 'wb'))
            pickle.dump(self.datacollector2.get_model_vars_dataframe(), open("data/eff_score_history.p", 'wb'))
            pickle.dump(cust_data, open("data/customers.p", 'wb'))
            pickle.dump(self.park_score[-1], open("data/park_score.p", "wb"))
            pickle.dump(self.happinesses, open("data/hapiness.p", "wb"))
            pickle.dump(histories, open("data/cust_history.p", 'wb'))

        try:
            pickle.dump(self.all_rides_list, open("../data/all_rides.p", "wb"))
        except:
            pickle.dump(self.all_rides_list, open("data/all_rides.p", "wb"))

        print()
        print("RUN HAS ENDED")
        print()


    def save_data(self):
        """Save data of all attractions and customers."""

        # Get info
        waitinglines = self.calc_waiting_time()

        for i in range(len(self.attractions)):
            self.data_dict[i]["waiting_list"].append(waitinglines.get(i))

        self.park_score.append(sum(waitinglines.values()))
        self.happinesses.append(self.calc_hapiness())

    def step(self):
        """Advance the model by one step."""

        if self.totalTOTAL < self.max_time:
            self.totalTOTAL += 1
            self.schedule.step()
            self.datacollector.collect(self)
            self.datacollector2.collect(self)

            self.schedule_Attraction.step()

            self.schedule_Customer.step()

            # update memory of attractions
            # attractions = self.get_attractions()
            # for attraction in attractions:
            #     attraction.update_memory()

            self.total_steps += 1

            self.save_data()
            self.get_strategy_history()

        else:
            for key in self.attraction_history.keys():
                y = self.attraction_history[key]
                x = list(range(0, self.max_time))
            self.final()