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

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

    def move(self):
        possible_steps = self.model.grid.get_neighborhood(self.pos,
                                                          moore=True,
                                                          include_center=False)
        new_position = random.choice(possible_steps)
        self.model.grid.move_agent(self, new_position)

    def step(self):
        '''Advance the model by one step.'''
        # print("New step.")
        self.datacollector.collect(self)
        self.schedule.step()
Beispiel #2
0
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()
Beispiel #3
0
class miModelo(Model):
    def __init__(self, N, seed=None):
        self.current_id = 0
        self.running = True
        # Definimos el schedule para hacer la ejecucion en orden aleatorio
        self.schedule = RandomActivation(self)

        #Definimos el grid de tamanio 10x10 y sin fronteras flexibles
        self.grid = MultiGrid(10, 10, False)

        for i in range(N):
            a = miAgente(self.next_id(), self, 5)
            self.schedule.add(a)
            pos_x = self.random.randint(0, 9)
            pos_y = self.random.randint(0, 9)

            self.grid.place_agent(a, [pos_x, pos_y])

        self.datacollector = DataCollector(model_reporters={
            "Nagentes": contarAgentes,
            "NumberTicks": getCurrentTick
        })

    def step(self):
        self.schedule.step()
        self.datacollector.collect(self)
        # Paramos la simulacion cuando hay menos de dos agentes
        if self.schedule.get_agent_count() < 2:
            self.running = False
Beispiel #4
0
class CollisionModel(Model):
    def __init__(self, N, width, height, init_value):
        self.num_agents = N
        self.init_value = init_value
        self.grid = MultiGrid(width, height, True)
        self.schedule = BaseScheduler(self)
        
        # Create Agents
        for i in range(self.num_agents):
            a = CollisionAgent(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))
        
        self.datacollector = DataCollector(
            #model_reporters={"AvgReward": compute_avgreward},
            #model_reporters={"AvgCollision": compute_avgcollision},
            model_reporters={"0": compute_avg_reward_angle_0, "90": compute_avg_reward_angle_1, "180": compute_avg_reward_angle_2, "270": compute_avg_reward_angle_3},
            agent_reporters={"Reward": lambda a: a.reward})

    def step(self):
        self.datacollector.collect(self)
        self.schedule.step()
Beispiel #5
0
class StigmergyPrey(Model):
    def __init__(self, N, width, height):
        self.stigmergies = []
        self.preys = []
        self.grid = MultiGrid(width, height, True)

        for i in range(N):
            x = self.random.randrange(self.grid.width)
            y = self.random.randrange(self.grid.height)
            agent = None
            if i % 2 == 0:
                agent = Stigmergy(i, self, 20 * (i + 1), i, 1)
                self.stigmergies.append(agent)
            else:
                agent = Prey(i, self)
                self.preys.append(agent)

            self.grid.place_agent(agent, (x, y))

    def step(self, directions):
        observations = []
        for stigmergy in self.stigmergies:
            stig_value = stigmergy.step()
            if stig_value == 0: self.stigmergies.remove(stigmergy)
            observations.append(stig_value)

        for prey in self.preys:
            prey.step()

        return observations
Beispiel #6
0
class DiseaseModel(Model):
    def __init__(self, home_store):
        self.num_agents = 1000
        self.grid = MultiGrid(200, 200, True)
        self.schedule = RandomActivation(self)
        self.running = True

        for i in range(self.num_agents):
            a = Agent(i, self)
            self.schedule.add(a)
            while True:
                #x = round(int(np.random.normal(self.grid.width/2, 10, 1)))
                #y = round(int(np.random.normal(self.grid.height/2, 10, 1)))
                x = self.random.randrange(self.grid.width)
                y = self.random.randrange(self.grid.height)
                if len(
                        self.grid.get_neighbors(
                            (x, y), moore=True, include_center=True,
                            radius=10)) <= 7:
                    self.grid.place_agent(a, (x, y))
                    home_store[i, :] = x, y
                    break

            if i < 1:
                a.infected = 1

        self.datacollector = DataCollector(
            model_reporters={"Tot informed": compute_informed},
            agent_reporters={"Infected": "infected"})

    def step(self):
        self.datacollector.collect(self)
        self.schedule.step()
Beispiel #7
0
class MoneyModel(Model):
    """A model with some number of agents."""
    def __init__(self, N, width, height):
        self.num_agents = N
        self.grid = MultiGrid(width, height, True)
        self.schedule = RandomActivation(self)

        self.cities = []

        self.running = True

        # Create agents
        for i in range(self.num_agents):
            a = MoneyAgent(i, self)
            self.schedule.add(a)
            # Add the agent to a random grid cell
            x = self.random.randrange(self.grid.width)
            y = self.random.randrange(self.grid.height)
            self.grid.place_agent(a, (x, y))

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

    def establish_cities(self):
        for contents, x, y in self.grid.coord_iter():
            if len(contents) > 2:

                for agent in contents:
                    agent.in_city = True

    def step(self):
        self.establish_cities()
        self.datacollector.collect(self)
        self.schedule.step()
Beispiel #8
0
class MoneyModel(Model):
    """Een model met N aantal agents, in een 30x30 grid.
    Elke agent begint met een wealth van 0 of 1 (random).

    Legenda:
    Zwart: Geen geld
    Grijs: 1-2
    Groen: 3-5
    Blauw: >5"""
    def __init__(self, N, width, height, neg):
        self.num_agents = N
        self.grid = MultiGrid(width, height, True)
        self.schedule = RandomActivation(self)
        self.running = True

        # Create agents
        for i in range(self.num_agents):
            a = MoneyAgent(i, self, neg)
            self.schedule.add(a)
            # Add the agent to a random grid cell
            x = self.random.randrange(self.grid.width)
            y = self.random.randrange(self.grid.height)
            self.grid.place_agent(a, (x, y))

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

    def step(self):
        self.datacollector.collect(self)
        self.schedule.step()
class MoneyModel(Model):
    """a model with some number of agents"""
    def __init__(self, N, width, height):
        self.num_agents = N
        self.grid = MultiGrid(width, height, True)
        self.schedule = RandomActivation(self)
        self.running = True

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

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

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

    def step(self):
        """advance the model by one step"""
        self.datacollector.collect(self)
        self.schedule.step()
Beispiel #10
0
class HungerModel(Model):
    """A model with some number of agents."""
    def __init__(self,N,width,height,num_of_food=10):
        self.num_agents = N
        self.num_food = num_of_food
        self.grid = MultiGrid(width,height,True)
        self.schedule= RandomActivation(self)
        self.running = True
        for i in range(self.num_agents):
            a = HungryAgent(i,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))
            
        for i in range(self.num_food):
            kombinacija = sve_kombinacije[i]
            id_offset = i+1000
            f = FoodAgent(id_offset,self, kombinacija[0],kombinacija[1],kombinacija[2])
            self.schedule.add(f)
            x = self.random.randrange(self.grid.width)
            y = self.random.randrange(self.grid.height)
            self.grid.place_agent(f,(x,y))
            
            
        self.datacollector = DataCollector(
        model_reporters = {"TotalKnowledge":compute_knowledge}) #prosledice automacki
  #      agent_reporters = {"Knowledge":"knowledge"})
    def step(self):
        self.datacollector.collect(self)
        self.schedule.step()
Beispiel #11
0
class SIRModel(Model):
    def __init__(self, N, width, height, infection_period, infection_prob,
                 initial_infected):

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

        self.infection_period = infection_period
        self.infection_prob = infection_prob

        for i in range(self.num_agents):

            agent = SIRAgent(i, self)

            if i < initial_infected:
                agent.infection()

            self.schedule.add(agent)

            x = self.random.randrange(self.grid.width)
            y = self.random.randrange(self.grid.height)
            self.grid.place_agent(agent, (x, y))

    def step(self):

        self.schedule.step()
Beispiel #12
0
class MoneyModel(Model):
    """
    A model with N agents
    """
    def __init__(self, N, width, height):
        self.running = True
        self.num_agents = N
        self.grid = MultiGrid(width, height, True)  # create a toroidal grid
        self.schedule = RandomActivation(self)

        # create agents
        for i in range(self.num_agents):
            a = MoneyAgent(i, self)
            self.schedule.add(a)
            # add agent to random grid cell
            x = random.randrange(self.grid.width)
            y = random.randrange(self.grid.height)
            self.grid.place_agent(a, (x, y))

        self.datacollector = DataCollector(
            model_reporters={"Gini": compute_gini},  # A function to call
            agent_reporters={"Wealth": "wealth"}  # An agent attribute
        )

    def step(self):
        """
        Advance the model by 1 step
        """
        self.datacollector.collect(self)
        self.schedule.step()
Beispiel #13
0
class bacModel(Model):
    '''world model for Eden Growth Model Simulation'''
    def __init__(self, beginRad, splitChance, x=-1, y=-1, mut_rate=MUTATION_RATE):
        self.running = True
        self.num_agents = 0
        self.schedule = RandomActivation(self)
        self.grid = MultiGrid(WIDTH, HEIGHT, IS_TOROIDAL) #True for toroidal
        #self.datacollector = DataCollector(
        #    model_reporters = {"Identifier": function_name}, #note no parentheses, just function name
        #    agent_reporter = {"Identifier2": function_name2})

        if x == -1:
            x = self.grid.width // 2
        if y == -1:
            y = self.grid.height // 2

        #create subsequent agents
        positions = self.grid.get_neighborhood((x,y), moore=False, radius=beginRad, include_center=True)
        for coord in positions:
            roll = random.random()
            a = bacAgent(self.num_agents, self, False, splitChance)
            self.num_agents += 1
            self.schedule.add(a)
            self.grid.place_agent(a, coord)


    def step(self):
        #self.datacollector.collect(self)
        self.schedule.step()
Beispiel #14
0
class TransModel(Model):
    # constructor for grid of width x height with N agents
    def __init__(self, N, width, height):
        self.num_agents = N
        self.grid = MultiGrid(width, height, True)
        self.schedule = RandomActivation(self)
        self.running = True
        
        # create agents
        for i in range(self.num_agents):
            a = TransAgent(i, 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))
        
        # create data collector
        self.datacollector = DataCollector(
                model_reporters = {'Transit': transitPercent, 
                                   'PfH': pfhPercent},
                agent_reporters = {'Time': 'time', 
                                   'Money': 'money'})
    
    # advance the model by one tick
    def step(self):
        self.datacollector.collect(self)
        self.schedule.step()
Beispiel #15
0
 def crear_nodo(self,nodo_id, tipo, ocupantes = [], tamano = None,
                ind_pos_def = None):
     assert tipo in ['casa','tienda', 'ciudad']
     if tipo == 'casa':
         assert len(ocupantes)>0, 'No hay ocupantes a asignar en la casa'
         if not tamano:
             tamano = 2#len(ocupantes)//2+1
         habitantes = [ind.unique_id for ind in ocupantes]
     
     elif tipo in ['tienda', 'ciudad']:
         if not tamano:
             tamano = 20
         habitantes = []
     
     espacio = MultiGrid(width = tamano,
                         height = tamano,
                         torus = False)
     if not ind_pos_def: 
         disponibles = espacio.empties[::]
         shuffle(disponibles)
         
     
     for i in ocupantes:
         i.casa_id = nodo_id if tipo=='casa' else None
         i.n_familiares = len(habitantes) if tipo=='casa' else 0
         i.nodo_actual = nodo_id
         i_pos = disponibles.pop() if not ind_pos_def else [0,0]
         espacio.place_agent(i, i_pos)
     
     
     self.add_node(nodo_id, tipo = tipo,
                   habitantes = habitantes,
                   espacio = espacio)
Beispiel #16
0
class BoltzmannWealthModel(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=100, width=10, height=10):
        self.num_agents = N
        self.grid = MultiGrid(height, width, True)
        self.schedule = RandomActivation(self)
        self.datacollector = DataCollector(
            model_reporters={"Gini": compute_gini},
            agent_reporters={"Wealth": "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 = self.random.randrange(self.grid.width)
            y = self.random.randrange(self.grid.height)
            self.grid.place_agent(a, (x, y))

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

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

    def run_model(self, n):
        for i in range(n):
            self.step()
Beispiel #17
0
class BoltzmannWealthModel(Model):
    def __init__(self, T, N, lamda, width=10, height=10):
        self.num_agents = N
        self.T = T
        self.grid = MultiGrid(height, width, True)
        self.lamda = lamda
        self.count = 0
        self.schedule = RandomActivation(self)
        self.datacollector = DataCollector(agent_reporters={'mi': 'm'})
        # Create agents
        for i in range(self.num_agents):
            a = MoneyAgent(i, self)
            self.schedule.add(a)
            # Add the agent to a random grid cell
            x = self.random.randrange(self.grid.width)
            y = self.random.randrange(self.grid.height)
            self.grid.place_agent(a, (x, y))

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

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

    def run_model(self, n):
        for i in tqdm(range(1, n)):
            self.count += 1
            #print("step:{}".format(i))
            self.step()
Beispiel #18
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 MoneyModel(Model):
    """A model with some number of agents."""
    def __init__(self, N, width, height):
        super().__init__()
        self.num_agents = N
        self.grid = MultiGrid(width, height, True)
        self.schedule = RandomActivation(self)

        # Create agents
        for i in range(self.num_agents):
            a = MoneyAgent(i, self)
            self.schedule.add(a)
            # Add the agent to a random grid cell
            x = self.random.randrange(self.grid.width)
            y = self.random.randrange(self.grid.height)
            self.grid.place_agent(a, (x, y))

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

    def step(self):
        self.datacollector.collect(self)
        self.schedule.step()
Beispiel #20
0
class EpidemicModel(Model):
    def __init__(self, num_agent, width, height):
        super().__init__()
        self.num_agent = num_agent
        self.grid = MultiGrid(width=width, height=height, torus=True)
        self.schedule = RandomActivation(self)

        # Create agents
        for u_id in range(0, num_agent):
            a = EpidemicAgent(unique_id=u_id, model=self)
            self.schedule.add(a)

            # Place the agents in the grid
            x = self.random.randrange(self.grid.width)
            y = self.random.randrange(self.grid.height)
            self.grid.place_agent(agent=a, pos=(x, y))

        # Pick one agent and infect him/her
        agent = self.random.choice(self.schedule.agents)
        agent.state = 1

        self.data_collector = DataCollector(model_reporters={
            "Susceptibles": susc,
            "Infecteds": inf,
            "Recovereds": rec
        })

    def step(self):
        self.data_collector.collect(self)
        self.schedule.step()
Beispiel #21
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 = self.random.randrange(self.width)
            y = self.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()
Beispiel #22
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()
Beispiel #23
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)
            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()
Beispiel #24
0
class TransModel(Model):
    def __init__(self, N, width, height, tax_val):
        self.num_agents = N
        self.grid = MultiGrid(width, height, True)
        self.schedule = RandomActivation(self)
        self.running = True
        self.steps = 0
        self.tax_value = float(tax_val)

        # create agents
        for i in range(self.num_agents):
            agent = TransAgent(i, self)
            self.schedule.add(agent)
            x = self.random.randrange(self.grid.width)
            y = self.random.randrange(self.grid.height)
            self.grid.place_agent(agent, (x, y))

        # create data collector
        self.data_collector = DataCollector(model_reporters={
            'Transit': transit_percent,
            'PfH': pfh_percent
        },
                                            agent_reporters={
                                                'Time': 'time',
                                                'Money': 'money'
                                            })

    def step(self):
        """Adance the model by one tick."""
        self.steps += 1
        self.schedule.step()
        self.data_collector.collect(self)
Beispiel #25
0
class DiseaseModel(Model):
    def __init__(self, no_people, total_area, no_agents, all_x, all_y,
                 infection_rate, first_infected, mobility, work_store,
                 home_store):
        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

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

            if i == first_infected:
                a.infected = 1

        self.datacollector = DataCollector(
            model_reporters={"Tot infections": compute_informed},
            agent_reporters={
                "Infected": "infected",
                "R-Number": "rnumber"
            })

    def step(self):
        self.datacollector.collect(self)
        self.schedule.step()
Beispiel #26
0
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
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)
Beispiel #28
0
class MoneyModel(Model):
    """A model with some number of agents."""
    def __init__(self, N, elevation):
        # num_agents is a parameter and stays constant throughout the simulation
        self.num_agents = N
        self.width = elevation.shape[0]
        self.height = elevation.shape[1]
        self.z = elevation
        # Adds the grid to the model object
        self.grid = MultiGrid(self.width, self.height, True)
        # Adds the scheduler to the model object
        self.schedule = RandomActivation(self)

        # create agents (for loop hence multiple agents) and add them to the schedular (one at a time)
        for i in range(self.num_agents):
            # The money agent class (object) is being computed for every value of i
            a = MoneyAgent(i, self)
            self.schedule.add(a)
            # Add the agents to a random cell
            # x = self.random.randrange(self.width)
            # y = self.random.randrange(self.height)
            self.grid.place_agent(a, (50, 14))

    def step(self):
        '''Advance the model by one step.'''
        self.schedule.step()
Beispiel #29
0
class ForageModel(Model):
    """A model with some number of agents."""
    def __init__(self, n_agents, width, height):
        self.running = True  # this was important for visualization
        self.num_agents = n_agents
        self.grid = MultiGrid(
            width, height, torus=True)  # True means toroidal space (for now)
        self.schedule = RandomActivation(self)

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

            # Add the agent to a random grid cell
            coords = (random.randrange(self.grid.width),
                      random.randrange(self.grid.height))
            self.grid.place_agent(a, coords)

        self.dc = DataCollector(model_reporters={
            "agent_count":
            lambda m: m.schedule.get_agent_count(),
            "gini":
            compute_gini
        },
                                agent_reporters={
                                    "name": lambda a: a.unique_id,
                                    "reserve": lambda a: a.reserve
                                })

    def step(self):
        '''Advance the model by one step.'''
        self.dc.collect(self)
        self.schedule.step()
Beispiel #30
0
class bacServerModel(Model):
    ################
    ###Deprecated###
    ################
    def __init__(self, width, height, beginRad):
            self.running = True
            self.num_agents = width * height
            self.schedule = RandomActivation(self)
            self.grid = MultiGrid(width, height, IS_TOROIDAL) #True for toroidal
            #self.datacollector = DataCollector(
            #    model_reporters = {"Identifier": function_name}, #note no parentheses, just function name
            #    agent_reporter = {"Identifier2": function_name2})

            for x in range(self.grid.width):
                for y in range(self.grid.height):
                    a = bacServerAgent(self.num_agents, self)
                    self.num_agents += 1
                    self.schedule.add(a)
                    self.grid.place_agent(a, (x,y))

            x = self.grid.width // 2
            y = self.grid.height // 2

            #create subsequent agents
            positions = self.grid.get_neighborhood((x,y), moore=False, radius=beginRad, include_center=True)
            for coord in positions:
                ag = self.grid.get_cell_list_contents([coord])[0]
                ag.activate()


    def step(self):
        #self.datacollector.collect(self)
        self.schedule.step()
Beispiel #31
0
class HungerModel(Model):
    """A model with some number of agents."""
    def __init__(self,N,width,height,num_of_food=64):
        self.num_agents = N
        self.num_food = num_of_food
        self.grid = MultiGrid(width,height,True)
        self.schedule= RandomActivation(self)
        self.running = True
        for i in range(self.num_agents):
            a = HungryAgent(i,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))
            
        for i in range(self.num_food):
            kombinacija = sve_kombinacije[i]
            id_offset = i+1000
            f = FoodAgent(id_offset,self, kombinacija[0],kombinacija[1],kombinacija[2])
            self.schedule.add(f)
            x = self.random.randrange(self.grid.width)
            y = self.random.randrange(self.grid.height)
            self.grid.place_agent(f,(x,y))
            
            
        self.datacollector = DataCollector(
        model_reporters = {"TotalKnowledge":compute_knowledge,"TotalEnergy":total_energy,"TotalExperience":measure_experience,"TotalFood":total_pojedena_hrana,"TotalPoison":total_pojedeni_otrovi})
  #      agent_reporters = {"Knowledge":"knowledge"})
    def step(self):
        self.datacollector.collect(self)
        self.schedule.step()
Beispiel #32
0
class HumanCapital(Model):
    ##Inicialización del modelo.
    def __init__(self, N_buenos_empleo, seed=None):
        self.current_id = 0
        self.running = True
        self.width = 7
        self.height = 7
        # Definimos el schedule para hacer la ejecucion en orden aleatorio
        self.schedule = RandomActivation(self)
        #Definimos el grid de tamanio 7x7 y sin fronteras flexibles
        self.grid = MultiGrid(self.width, self.height, False)
        ##Declaración del grid.
        for y in range(0, self.height):
            for x in range(0, self.width):
                a = Agente(self.next_id(), self)
                self.schedule.add(a)
                self.grid.place_agent(a, [x, y])
        self.datacollector = DataCollector(model_reporters={
            "Nagentes": contarAgentes,
            "NumberTicks": getCurrentTick
        })

    ##Itinerario.
    def step(self):
        #Ejecutar el step de los agentes.
        self.schedule.step()
        #Ejecutar el datacollector
        self.datacollector.collect(self)
Beispiel #33
0
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
Beispiel #34
0
class BikeShare(Model):
    """A model with some number of potential riders."""
    global hours_per_day
    hours_per_day = 24

    def __init__(self, N, M, width, height):
        # self.running = True
        self.num_agents = N
        # self.grid = MultiGrid(width, height, True)

        self.num_stations = M
        self.radius = np.int(np.sqrt(width * height))
        self.grid = MultiGrid(width, height, True)
        self.grid_stations = SingleGrid(width, height, True)
        self.schedule = RandomActivation(self)
        self.timestamp = 0 # use to find days
        self.datestamp = 0

        threshold = 0.8

        # create agents
        for i in range(self.num_agents):
            a = BikeRider(i, self, threshold)
            self.schedule.add(a)

            # add the agent to a random grid cell
            x = np.random.randint(self.grid.width)
            y = np.random.randint(self.grid.height)
            self.grid.place_agent(a, (x, y))


        for i in range(self.num_stations):
            s = BikeStation(i, self)
            self.schedule.add(s)

            # add the station to a random grid cell
            # x = np.random.randint(self.grid_stations.width)
            # y = np.random.randint(self.grid_stations.height)
            self.grid_stations.position_agent(s) # ensures one station max
            # self.grid.place_agent(s, s.pos)
            print ("Station " + str(s.unique_id) + "; " + str(s.pos))

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


    def step(self):
        '''Advance the model by 1 step: arbitrary unit of time. '''
        # self.datacollector.collect(self)
        # print ("Step the schedule ...")
        # print (str(self.timestamp))
        self.timestamp += 1
        if self.timestamp % hours_per_day == 0:
            print ("\n**** new day " + str(self.datestamp))
            self.datestamp += 1
            self.timestamp = 0
        self.schedule.step()
Beispiel #35
0
class MoniModel(Model):
    """
    A model for monitoring agents
    """
    def __init__(self, N, width, height):

        #Monitoring space
        self.width = width
        self.height = height
        self.grid = MultiGrid(height, width, False)  #non toroidal grid

        self.schedule = SimultaneousActivation(self)

        self.abCount = 0  #initial abnormality count
        self.detectedAb = 0
        self.interactionCount = 0
        # =============================================================================
        #         self.coveredArea = []

        #         self.interactionRateAverage = 0
        #         self.coveragePercentage = 0
        #         self.coveragePercentageAverage = 0
        # =============================================================================
        # Create agents

        self.num_agents = N
        for i in range(self.num_agents):
            x = floor(self.width / N * i + self.width / N / 2)
            #           create and add agent with id number i to the scheduler
            a = MoniAgent(i, self)
            self.schedule.add(a)
            #place agent at the center of its limit coor
            self.grid.place_agent(a, (x, 0))

#        this part is for visualization only
#        self.running = True

    def step(self):
        #        self.interactionCount = 0
        self.schedule.step()

    def run_model(self, n):
        for i in range(n):
            #           self.initPos()
            self.step()
#           print(self.schedule.steps)

    """
    Calculate fitness of a swarm (success ratio)
    """
    def fitness(self):
        for _ in range(100):
            self.step()
        if self.abCount == 0:
            self.abCount = 1  #avoid division by 0 error


#        return self.detectedAb/self.abCount
        return (sum(self.schedule.agents[0].genome))
Beispiel #36
0
class Charts(Model):

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

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

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

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

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

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

    def run_model(self):
        for i in range(self.run_time):
            self.step()
Beispiel #37
0
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))
Beispiel #38
0
class WolfSheepPredation(Model):
    '''
    Wolf-Sheep Predation Model
    '''

    initial_sheep = 100
    initial_wolves = 50
    sheep_gain_from_food = 4

    grass = False

    wolf_gain_from_food = 20
    sheep_reproduce = 0.04
    wolf_reproduce = 0.05

    height = 20
    width = 20

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

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

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

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

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

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

        self.running = True

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

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

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

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

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

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

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

    def run_model(self):
        for i in range(self.run_time):
            self.step()
Beispiel #40
0
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))
Beispiel #41
0
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************")
Beispiel #42
0
class DDAModel(Model):
    """A simple DDA model"""

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

        # Call all agents' 'step' method.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        # Creation of land parcels
        land_parcel_count = 0

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

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

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

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

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

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

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

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

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

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

                last_birth_time = random.uniform(0, 1)

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

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

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

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

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

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

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