예제 #1
0
class TestSpaceNonToroidal(unittest.TestCase):
    '''
    Testing a toroidal continuous space.
    '''

    def setUp(self):
        '''
        Create a test space and populate with Mock Agents.
        '''
        self.space = ContinuousSpace(70, 20, False, -30, -30, 100, 100)
        self.agents = []
        for i, pos in enumerate(TEST_AGENTS):
            a = MockAgent(i, None)
            self.agents.append(a)
            self.space.place_agent(a, pos)

    def test_agent_positions(self):
        '''
        Ensure that the agents are all placed properly.
        '''
        for i, pos in enumerate(TEST_AGENTS):
            a = self.agents[i]
            assert a.pos == pos

    def test_distance_calculations(self):
        '''
        Test toroidal distance calculations.
        '''

        pos_2 = (70, 20)
        pos_3 = (-30, -20)
        assert self.space.get_distance(pos_2, pos_3) == 107.70329614269008

    def test_neighborhood_retrieval(self):
        '''
        Test neighborhood retrieval
        '''
        neighbors_1 = self.space.get_neighbors((-20, -20), 1)
        assert len(neighbors_1) == 2

        neighbors_2 = self.space.get_neighbors((40, -10), 10)
        assert len(neighbors_2) == 0

        neighbors_3 = self.space.get_neighbors((-30, -30), 10)
        assert len(neighbors_3) == 0

    def test_bounds(self):
        '''
        Test positions outside of boundary
        '''
        for i, pos in enumerate(OUTSIDE_POSITIONS):
            a = MockAgent(len(self.agents) + i, None)
            with self.assertRaises(Exception):
                self.space.place_agent(a, pos)

        a = self.agents[0]
        for pos in OUTSIDE_POSITIONS:
            assert self.space.out_of_bounds(pos)
            with self.assertRaises(Exception):
                self.space.move_agent(a, pos)
예제 #2
0
class TestSpaceToroidal(unittest.TestCase):
    '''
    Testing a toroidal continuous space.
    '''

    def setUp(self):
        '''
        Create a test space and populate with Mock Agents.
        '''
        self.space = ContinuousSpace(70, 20, True, -30, -30, 100, 100)
        self.agents = []
        for i, pos in enumerate(TEST_AGENTS):
            a = MockAgent(i, None)
            self.agents.append(a)
            self.space.place_agent(a, pos)

    def test_agent_positions(self):
        '''
        Ensure that the agents are all placed properly.
        '''
        for i, pos in enumerate(TEST_AGENTS):
            a = self.agents[i]
            assert a.pos == pos

    def test_distance_calculations(self):
        '''
        Test toroidal distance calculations.
        '''
        pos_1 = (-30, -30)
        pos_2 = (70, 20)
        assert self.space.get_distance(pos_1, pos_2) == 0

        pos_3 = (-30, -20)
        assert self.space.get_distance(pos_1, pos_3) == 10

    def test_neighborhood_retrieval(self):
        '''
        Test neighborhood retrieval
        '''
        neighbors_1 = self.space.get_neighbors((-20, -20), 1)
        assert len(neighbors_1) == 2

        neighbors_2 = self.space.get_neighbors((40, -10), 10)
        assert len(neighbors_2) == 0

        neighbors_3 = self.space.get_neighbors((-30, -30), 10)
        assert len(neighbors_3) == 1
예제 #3
0
class TestSpaceToroidal(unittest.TestCase):
    '''
    Testing a toroidal continuous space.
    '''
    def setUp(self):
        '''
        Create a test space and populate with Mock Agents.
        '''
        self.space = ContinuousSpace(70, 20, True, -30, -30)
        self.agents = []
        for i, pos in enumerate(TEST_AGENTS):
            a = MockAgent(i, None)
            self.agents.append(a)
            self.space.place_agent(a, pos)

    def test_agent_positions(self):
        '''
        Ensure that the agents are all placed properly.
        '''
        for i, pos in enumerate(TEST_AGENTS):
            a = self.agents[i]
            assert a.pos == pos

    def test_agent_matching(self):
        '''
        Ensure that the agents are all placed and indexed properly.
        '''
        for i, agent in self.space._index_to_agent.items():
            assert agent.pos == tuple(self.space._agent_points[i, :])
            assert i == self.space._agent_to_index[agent]

    def test_distance_calculations(self):
        '''
        Test toroidal distance calculations.
        '''
        pos_1 = (-30, -30)
        pos_2 = (70, 20)
        assert self.space.get_distance(pos_1, pos_2) == 0

        pos_3 = (-30, -20)
        assert self.space.get_distance(pos_1, pos_3) == 10

        pos_4 = (20, -5)
        pos_5 = (20, -15)
        assert self.space.get_distance(pos_4, pos_5) == 10

        pos_6 = (-30, -29)
        pos_7 = (21, -5)
        assert self.space.get_distance(pos_6, pos_7) == np.sqrt(49**2 + 24**2)

    def test_heading(self):
        pos_1 = (-30, -30)
        pos_2 = (70, 20)
        self.assertEqual((0, 0), self.space.get_heading(pos_1, pos_2))

        pos_1 = (65, -25)
        pos_2 = (-25, -25)
        self.assertEqual((10, 0), self.space.get_heading(pos_1, pos_2))

    def test_neighborhood_retrieval(self):
        '''
        Test neighborhood retrieval
        '''
        neighbors_1 = self.space.get_neighbors((-20, -20), 1)
        assert len(neighbors_1) == 2

        neighbors_2 = self.space.get_neighbors((40, -10), 10)
        assert len(neighbors_2) == 0

        neighbors_3 = self.space.get_neighbors((-30, -30), 10)
        assert len(neighbors_3) == 1

    def test_bounds(self):
        '''
        Test positions outside of boundary
        '''
        boundary_agents = []
        for i, pos in enumerate(OUTSIDE_POSITIONS):
            a = MockAgent(len(self.agents) + i, None)
            boundary_agents.append(a)
            self.space.place_agent(a, pos)

        for a, pos in zip(boundary_agents, OUTSIDE_POSITIONS):
            adj_pos = self.space.torus_adj(pos)
            assert a.pos == adj_pos

        a = self.agents[0]
        for pos in OUTSIDE_POSITIONS:
            assert self.space.out_of_bounds(pos)
            self.space.move_agent(a, pos)
예제 #4
0
파일: test_space.py 프로젝트: tubks/mesa
class TestSpaceNonToroidal(unittest.TestCase):
    """
    Testing a toroidal continuous space.
    """

    def setUp(self):
        """
        Create a test space and populate with Mock Agents.
        """
        self.space = ContinuousSpace(70, 20, False, -30, -30)
        self.agents = []
        for i, pos in enumerate(TEST_AGENTS):
            a = MockAgent(i, None)
            self.agents.append(a)
            self.space.place_agent(a, pos)

    def test_agent_positions(self):
        """
        Ensure that the agents are all placed properly.
        """
        for i, pos in enumerate(TEST_AGENTS):
            a = self.agents[i]
            assert a.pos == pos

    def test_agent_matching(self):
        """
        Ensure that the agents are all placed and indexed properly.
        """
        for i, agent in self.space._index_to_agent.items():
            assert agent.pos == tuple(self.space._agent_points[i, :])
            assert i == self.space._agent_to_index[agent]

    def test_distance_calculations(self):
        """
        Test toroidal distance calculations.
        """

        pos_2 = (70, 20)
        pos_3 = (-30, -20)
        assert self.space.get_distance(pos_2, pos_3) == 107.70329614269008

    def test_heading(self):
        pos_1 = (-30, -30)
        pos_2 = (70, 20)
        self.assertEqual((100, 50), self.space.get_heading(pos_1, pos_2))

        pos_1 = (65, -25)
        pos_2 = (-25, -25)
        self.assertEqual((-90, 0), self.space.get_heading(pos_1, pos_2))

    def test_neighborhood_retrieval(self):
        """
        Test neighborhood retrieval
        """
        neighbors_1 = self.space.get_neighbors((-20, -20), 1)
        assert len(neighbors_1) == 2

        neighbors_2 = self.space.get_neighbors((40, -10), 10)
        assert len(neighbors_2) == 0

        neighbors_3 = self.space.get_neighbors((-30, -30), 10)
        assert len(neighbors_3) == 0

    def test_bounds(self):
        """
        Test positions outside of boundary
        """
        for i, pos in enumerate(OUTSIDE_POSITIONS):
            a = MockAgent(len(self.agents) + i, None)
            with self.assertRaises(Exception):
                self.space.place_agent(a, pos)

        a = self.agents[0]
        for pos in OUTSIDE_POSITIONS:
            assert self.space.out_of_bounds(pos)
            with self.assertRaises(Exception):
                self.space.move_agent(a, pos)
예제 #5
0
파일: model.py 프로젝트: trobey/nmcovid
class Covid(Model):
    '''
    Covid model class. Handles agent creation, placement and scheduling.
    '''
    def __init__(self,
                 population=100,
                 width=100,
                 height=100,
                 mobility=6,
                 social_distance=2,
                 asymptomatic_percentage=50.0):
        '''
        Create a new Covid model.

        Args:
            population: Number of people (density) with one asymptomatic infected person.
            asymptomatic_percentage: Percentage of infected people that are asymptomatic.  Asymptomatic people transmit the virus for 42 time steps versus 15 time steps for those that are symptomatic.
            social_distance: Distance at which neighboring susceptible agents can b ecome infected.
            mobility: The maximum distance that an agent can travel.
        '''

        self.current_id = 0
        self.population = population
        self.mobility = mobility
        self.social_distance = social_distance
        self.asymptomatic_percentage = asymptomatic_percentage
        self.state = "home"
        self.schedule = RandomActivation(self)
        self.space = ContinuousSpace(width, height, False)
        self.image = Image.open(r"nmcounties.jpg")
        self.num = {
            'San Juan': 0,
            'Rio Arriba': 0,
            'Taos': 0,
            'Colfax': 0,
            'Union': 0,
            'Los Alamos': 0,
            'Mora': 0,
            'Harding': 0,
            'McKinley': 0,
            'Sandoval': 0,
            'Santa Fe': 0,
            'San Miguel': 0,
            'Quay': 0,
            'Cibola': 0,
            'Valencia': 0,
            'Bernalillo': 0,
            'Torrance': 0,
            'Guadalupe': 0,
            'Curry': 0,
            'Catron': 0,
            'Socorro': 0,
            'Lincoln': 0,
            'De Baca': 0,
            'Roosevelt': 0,
            'Sierra': 0,
            'Chaves': 0,
            'Hidalgo': 0,
            'Grant': 0,
            'Luna': 0,
            'Doña Ana': 0,
            'Otero': 0,
            'Eddy': 0,
            'Lea': 0,
        }
        self.pop = {
            'San Juan': 0,
            'Rio Arriba': 0,
            'Taos': 0,
            'Colfax': 0,
            'Union': 0,
            'Los Alamos': 0,
            'Mora': 0,
            'Harding': 0,
            'McKinley': 0,
            'Sandoval': 0,
            'Santa Fe': 0,
            'San Miguel': 0,
            'Quay': 0,
            'Cibola': 0,
            'Valencia': 0,
            'Bernalillo': 0,
            'Torrance': 0,
            'Guadalupe': 0,
            'Curry': 0,
            'Catron': 0,
            'Socorro': 0,
            'Lincoln': 0,
            'De Baca': 0,
            'Roosevelt': 0,
            'Sierra': 0,
            'Chaves': 0,
            'Hidalgo': 0,
            'Grant': 0,
            'Luna': 0,
            'Doña Ana': 0,
            'Otero': 0,
            'Eddy': 0,
            'Lea': 0,
        }
        with open('counties.csv') as csvfile:
            reader = csv.reader(csvfile, delimiter=',', quotechar='"')
            for row in reader:
                county = row[2].replace(' County', '')
                if (county != '' and county != 'County'):
                    population = row[3].replace(',', '')
                    self.pop[county] = population
        total = 0
        for value in self.pop.values():
            total += int(value)
        for county, value in self.pop.items():
            self.pop[county] = round(
                int(self.population) * int(value) / int(total))
        total = 0
        for value in self.pop.values():
            total += int(value)
        if (self.population != total):
            self.pop['Bernalillo'] += self.population - total

        self.make_agents()
        self.running = True

        self.datacollector = DataCollector({
            "Susceptible":
            lambda m: self.count("Susceptible"),
            "Infected":
            lambda m: self.count("Infected"),
            "Recovered":
            lambda m: self.count("Recovered")
        })

    def counties(self, pixel):
        if (pixel == (87, 127, 77)):
            return 'San Juan'
        elif (pixel == (168, 144, 178)):
            return 'Rio Arriba'
        elif (pixel == (131, 141, 91)):
            return 'Taos'
        elif (pixel == (189, 204, 119)):
            return 'Colfax'
        elif (pixel == (197, 112, 58)):
            return 'Union'
        elif (pixel == (211, 165, 80)):
            return 'Los Alamos'
        elif (pixel == (186, 81, 52)):
            return 'Mora'
        elif (pixel == (106, 97, 126)):
            return 'Harding'
        elif (pixel == (91, 124, 143)):
            return 'McKinley'
        elif (pixel == (92, 59, 40)):
            return 'Sandoval'
        elif (pixel == (75, 113, 116)):
            return 'Santa Fe'
        elif (pixel == (109, 103, 53)):
            return 'San Miguel'
        elif (pixel == (49, 73, 73)):
            return 'Quay'
        elif (pixel == (178, 62, 49)):
            return 'Cibola'
        elif (pixel == (138, 99, 84)):
            return 'Valencia'
        elif (pixel == (137, 184, 214)):
            return 'Bernalillo'
        elif (pixel == (106, 106, 104)):
            return 'Torrance'
        elif (pixel == (146, 117, 87)):
            return 'Guadalupe'
        elif (pixel == (156, 150, 88)):
            return 'Curry'
        elif (pixel == (67, 94, 149)):
            return 'Catron'
        elif (pixel == (55, 80, 50)):
            return 'Socorro'
        elif (pixel == (145, 186, 178)):
            return 'Lincoln'
        elif (pixel == (82, 33, 37)):
            return 'De Baca'
        elif (pixel == (195, 189, 189)):
            return 'Roosevelt'
        elif (pixel == (238, 219, 99)):
            return 'Sierra'
        elif (pixel == (243, 234, 129)):
            return 'Chaves'
        elif (pixel == (41, 30, 60)):
            return 'Hidalgo'
        elif (pixel == (116, 140, 106)):
            return 'Grant'
        elif (pixel == (11, 10, 8)):
            return 'Luna'
        elif (pixel == (157, 56, 74)):
            return 'Doña Ana'
        elif (pixel == (52, 53, 48)):
            return 'Otero'
        elif (pixel == (207, 144, 135)):
            return 'Eddy'
        elif (pixel == (138, 171, 80)):
            return 'Lea'
        else:
            return ''

    def make_agents(self):
        '''
        Create self.population agents, with random positions and starting headings.
        '''

        for i in range(self.population):
            pos = self.inside()
            person = Susceptible(self.next_id(), self, pos)
            self.space.place_agent(person, pos)
            self.schedule.add(person)
        agent_key = random.randint(0, self.population - 1)
        agent = self.schedule._agents[agent_key]
        asymptomatic = True
        person = Infected(self.next_id(), self, agent.pos, True)
        person.set_imperial(agent.home, agent.work, agent.travel)
        self.space.remove_agent(agent)
        self.schedule.remove(agent)
        self.space.place_agent(person, person.pos)
        self.schedule.add(person)

    def inside(self):
        while (1):
            x = self.random.random() * self.space.x_max
            y = self.random.random() * self.space.y_max
            if (y > 10.0 and y < self.space.y_max - 10.0 and x > 10.0
                    and x < self.space.x_max - 10.0):
                coordinate = x, y
                pixel = self.image.getpixel(coordinate)
                if (pixel != (255, 255, 255)):
                    county = self.counties(pixel)
                    if (county != ''):
                        if (self.num[county] < self.pop[county]):
                            self.num[county] += 1
                            return np.array((x, y))

    def step(self):
        self.infect()

        if self.state == "home":
            self.state = "work"
        elif self.state == "work":
            self.state = "community"
        elif self.state == "community":
            self.state = "home"

        self.schedule.step()

        # collect data
        self.datacollector.collect(self)
        if self.count("Infected") == 0:
            self.running = False

    def infect(self):
        agent_keys = list(self.schedule._agents.keys())
        susceptible = []
        for agent_key in agent_keys:
            if self.schedule._agents[agent_key].name == "Susceptible":
                susceptible.append(agent_key)
        for agent_key in susceptible:
            agent = self.schedule._agents[agent_key]
            neighbors = self.space.get_neighbors(agent.pos,
                                                 self.social_distance)
            for neighbor in neighbors:
                if neighbor.name == "Infected":
                    asymptomatic = False
                    if (100.0 * self.random.random() <
                            self.asymptomatic_percentage):
                        asymptomatic = True
                    person = Infected(self.next_id(), self, agent.pos,
                                      asymptomatic)
                    person.set_imperial(agent.home, agent.work, agent.travel)
                    self.space.remove_agent(agent)
                    self.schedule.remove(agent)
                    self.space.place_agent(person, person.pos)
                    self.schedule.add(person)
                    break

    def count(self, type):
        agent_keys = list(self.schedule._agents.keys())
        num = 0
        for agent_key in agent_keys:
            if self.schedule._agents[agent_key].name == type:
                num += 1
        return num
예제 #6
0
class PredatorPreyModel(Model):
    def __init__(self,
                 height=100,
                 width=100,
                 init_prey=100,
                 prey_reproduction=0.03,
                 init_predator=10,
                 predator_vision=1,
                 predator_reproduction=0.5,
                 predator_death=0.02,
                 local_offspring=False,
                 max_iters=500,
                 seed=None):

        super().__init__()

        self.height = height
        self.width = width
        self.init_prey = init_prey
        self.prey_reproduction = prey_reproduction
        self.init_predator = init_predator
        self.predator_vision = predator_vision
        self.predator_reproduction = predator_reproduction
        self.predator_death = predator_death
        self.local_offspring = local_offspring
        self.iteration = 0
        self.max_iters = max_iters
        self.schedule = RandomActivation(self)
        self.space = ContinuousSpace(height, width, torus=True)
        model_reporters = {
            'Prey': lambda model: self.count('Prey'),
            'Predator': lambda model: self.count('Predator'),
        }

        self.datacollector = DataCollector(model_reporters=model_reporters)

        # Place prey
        for i in range(self.init_prey):
            x = self.random.uniform(0, self.width)
            y = self.random.uniform(0, self.height)
            # next_id() starts at 1
            prey = Prey(self.next_id(), self, (x, y), self.prey_reproduction)
            self.space.place_agent(prey, (x, y))
            self.schedule.add(prey)

        # Place predators
        for i in range(self.init_predator):
            x = self.random.uniform(0, self.width)
            y = self.random.uniform(0, self.height)
            predator = Predator(self.next_id(), self, (x, y),
                                self.predator_reproduction,
                                self.predator_death, self.predator_vision)
            self.space.place_agent(predator, (x, y))
            self.schedule.add(predator)

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

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

        Returns
        -------
        None.

        """

        self.schedule.step()
        self.iteration += 1

        self.datacollector.collect(self)

        # Stop system if maximum of iterations is reached
        if self.iteration > self.max_iters:
            self.running = False
            return None

    def count(self, breed):
        """
        Count agent by breed.

        Parameters
        ----------
        breed : string
            Breed of agent Can be 'Prey' or 'Predator'.

        Returns
        -------
        count : int
            Number of agents of type breed.

        """

        count = 0
        for agent in self.schedule.agents:
            if agent.breed == breed:
                count += 1

        if breed == 'Predator' and count == 0:
            self.running = False

        return count

    def warm_up(self):
        for agent in self.schedule.agents:
            if agent.breed == 'Prey':
                continue

            neighbors = self.space.get_neighbors(agent.pos,
                                                 radius=agent.vision)

            for prey in neighbors:
                if prey.breed == 'Prey':
                    x = self.random.uniform(0, self.width)
                    y = self.random.uniform(0, self.height)
                    self.space.move_agent(prey, (x, y))
예제 #7
0
class BoidFlockers(Model):
    """
    Flocker model class. Handles agent creation, placement and scheduling.
    """    
    def __init__(
        self,
        population=100,
        width=100,
        height=100,
        speed=1,
        vision=10,
        separation=2,
        rate = 10,
        size_factor = 2,
        sim_length = 1200,
        angle_min = -180,
        angle_max = 180):
        """
        Create a new Flockers model.

        Args:
            width, height: Size of the space.
            speed: How fast should the Boids move.
            vision: How far around should each Boid look for its neighbors
            separation: What's the minimum distance each Boid will attempt to
                    keep from any other
                    """
                    
        self.population = population
        self.unique_id = 1
        self.vision = vision
        self.speed = speed
        self.separation = separation
        self.schedule = RandomActivation(self)
        self.space = ContinuousSpace(width, height, False)
        self.size_factor = size_factor
        
        self.angle_min = angle_min
        self.angle_max = angle_max
        
        self.running = True
        self.rate = rate
        self.kill_agents = []
        self.queue = []
        self.input_rate = 0
        self.num_agents = 0
        
        self.arrival = 0
        self.departure = 0
        
        self.n_confs = 0
        self.n_intrusion = 0
        
        self.dep_del = 0
        self.enroute_del = 0
        self.tot_del = self.dep_del + self.enroute_del
        
        self.sim_length = sim_length
        
        self.datacollector = DataCollector(
            model_reporters= {"Occupancy": compute_N,
                              "Total flow": compute_flow,
                              "Effective flow": compute_eff_flow,
                              "Inpute rate": compute_inp,
                              "Output rate": compute_out,
                              'Effective speed': compute_eff_speed ,
                              'Speed': compute_speed,
                              'Queue length': compute_queue_len,
                              'size':'size_factor',
                              'inp_rate':'rate',
                              'vision':'vision',
                              'def_speed':'speed',
                              'sep':'separation',
                              'Departure Delay':'dep_del',
                              'Enroute Delay': 'enroute_del',
                              'Total Delay': 'tot_del',
                              'N Conflicts': 'n_confs',
                              'N Intrusions': 'n_intrusion',
                              'N Arrivals': 'arrival',
                              'N Departures': 'departure'
                              
                             },
            agent_reporters = {'id':'unique_id',
                                'prev_dist':'previos_distance',
                                'cur_dist':'current_distance',
                                'phys_speed':'physic_speed',
                                'vision':'vision',
                                'def_speed':'speed',
                                'sep':'separation',
                                'x': lambda x: x.pos[0],
                                'y': lambda x: x.pos[1]}
            )
        
    def make_od(self):
    
            x = self.space.x_max/2 + np.random.uniform(-1,1)\
                * self.space.x_max/2/self.size_factor
            y = self.space.y_max/2 + np.random.uniform(-1,1)\
                * self.space.y_max/2/self.size_factor
            pos = np.array((x, y))
            x_dest = self.space.x_max/2 + np.random.uniform(-1,1) \
                * self.space.x_max/2/self.size_factor
            y_dest = self.space.y_max/2 + np.random.uniform(-1,1) \
                * self.space.y_max/2/self.size_factor
            dest = np.array((x_dest, y_dest))
            return pos,dest
        
    def make_od2(self):
        
        valid = False
        while valid == False:
                x = self.space.x_max/2 + np.random.uniform(-1,1)\
                    * self.space.x_max/2/self.size_factor
                y = self.space.y_max/2 + np.random.uniform(-1,1)\
                    * self.space.y_max/2/self.size_factor
                pos = np.array((x, y))
                
                x_dest = self.space.x_max/2 + np.random.uniform(-1,1) \
                    * self.space.x_max/2/self.size_factor
                y_dest = self.space.y_max/2 + np.random.uniform(-1,1) \
                    * self.space.y_max/2/self.size_factor
                dest = np.array((x_dest, y_dest))
                
                vector = (dest - pos)/np.linalg.norm((dest - pos))
                angle = np.arctan2(vector[0],vector[1]) * 180 / np.pi
                
                if angle >= self.angle_min and angle <= self.angle_max:
                    valid =True
                else: continue
        return pos, dest
        
    def make_agents(self, od, init_time):

            pos = od[0]
            dest = od[1]            
            velocity = np.random.random(2) * 2 - 1
            
            boid = Boid(
                unique_id=self.unique_id,
                model=self,
                pos=pos,
                speed = self.speed,
                velocity=velocity,
                destination = dest,
                vision=self.vision,
                separation=self.separation,
                init_time = init_time
            )
            return boid

    def place_boid(self, boid):
        self.space.place_agent(boid, boid.pos)
        self.schedule.add(boid)
        
    def agent_maker(self):
        per_step = self.rate/60
        fractional = per_step % 1
        integer = int(per_step - round(fractional))
        num_frac = np.random.binomial(size=1, n=1, p= fractional)
        self.input_rate = int(integer+num_frac)
        #create agents
       
        for i in range(self.input_rate):
            od = self.make_od2()
            agent = self.make_agents(od, init_time = self.schedule.time)
            agent.od_dist = agent.distance()
            self.unique_id += 1
            
            if self.num_agents >= 1:
                neighbors = self.space.get_neighbors(od[0], self.separation, False)
                if len(neighbors) == 0:
                    agent.entry_time = self.schedule.time
                    self.place_boid(agent)
                    self.arrival += 1
                    self.num_agents += 1
                    #print('first attempt!')
                else:
                    self.queue.append(agent)
                    
            if self.num_agents == 0: 
                agent.entry_time = self.schedule.time
                self.place_boid(agent)
                self.arrival += 1
                self.num_agents += 1
            
            
    def queue_clearer(self, time):
        for index, agent in enumerate(self.queue):
            od = agent.pos
            # print(od)
            neighbors = self.space.get_neighbors(od[0], self.separation, False)
            if len(neighbors) == 0:
                agent.entry_time = time
                # agent.dep_del = max(agent.entry_time - agent.init_time,0)
                # print('second attempt!',agent.unique_id,agent.init_time, agent.entry_time, agent.dep_del)
                self.dep_del += agent.entry_time - agent.init_time
                self.place_boid(agent)
                self.arrival += 1
                self.num_agents += 1
                del self.queue[index]
            else:
                pass
        
    def step(self):
        """
        Create agents here
        """
        #collect data
        # try:
        self.n_confs = 0
        self.n_intrusion = 0
        
        #compute input rate for step
        if self.schedule.time <self.sim_length:
            self.agent_maker()
        else: pass
        self.queue_clearer(time= self.schedule.time)
        self.kill_agents = []
        #make 1 step
        self.schedule.step()
        #remove agents that arrived at their destinations
        self.departure += len(self.kill_agents)
        
        for i in self.kill_agents:
            self.enroute_del += i.enroute_del
            self.schedule.remove(i)
            self.num_agents -= 1
            self.space.remove_agent(i)
        try:
            self.datacollector.collect(self)
        except: 
            pass
예제 #8
0
class Covid(Model):
    '''
    Covid model class. Handles agent creation, placement and scheduling.
    '''
    def __init__(self,
                 population=100,
                 width=100,
                 height=100,
                 mobility=6,
                 social_distance=2,
                 asymptomatic_percentage=50.0,
                 imperial=True):
        '''
        Create a new Covid model.

        Args:
            population: Number of people (density) with one asymptomatic infected person.
            imperial: Agent rotates between home, work and community.  For home the agent returns to a random point near a fixed home position.  Community has the agent randomly placed in the space.  Work has 90% like home but with a fixed work position and 10% random like community.  This is patterned after the Imperial College model.  Turning off imperial iterates with each agent traveling a random direction and distance from the current position.
            asymptomatic_percentage: Percentage of infected people that are asymptomatic.  Asymptomatic people transmit the virus for 42 time steps versus 15 time steps for those that are symptomatic.
            social_distance: Distance at which neighboring susceptible agents can b ecome infected.
            mobility: The maximum distance that an agent can travel.
        '''

        self.current_id = 0
        self.population = population
        self.mobility = mobility
        self.social_distance = social_distance
        self.asymptomatic_percentage = asymptomatic_percentage
        self.imperial = imperial
        if imperial:
            self.state = "home"
        else:
            self.state = "diffusion"
        self.schedule = RandomActivation(self)
        self.space = ContinuousSpace(width, height, True)
        self.make_agents()
        self.running = True

        self.datacollector = DataCollector({
            "Susceptible":
            lambda m: self.count("Susceptible"),
            "Infected":
            lambda m: self.count("Infected"),
            "Recovered":
            lambda m: self.count("Recovered")
        })

    def make_agents(self):
        '''
        Create self.population agents, with random positions and starting headings.
        '''

        for i in range(0, 1):
            x = self.random.random() * self.space.x_max
            y = self.random.random() * self.space.y_max
            pos = np.array((x, y))
            asymptomatic = True
            person = Infected(self.next_id(), self, pos, asymptomatic)
            self.space.place_agent(person, pos)
            self.schedule.add(person)

        for i in range(self.population - 1):
            x = self.random.random() * self.space.x_max
            y = self.random.random() * self.space.y_max
            pos = np.array((x, y))
            person = Susceptible(self.next_id(), self, pos)
            self.space.place_agent(person, pos)
            self.schedule.add(person)

    def step(self):
        self.infect()

        if self.state == "home":
            self.state = "work"
        elif self.state == "work":
            self.state = "community"
        elif self.state == "community":
            self.state = "home"

        self.schedule.step()

        # collect data
        self.datacollector.collect(self)
        if self.count("Infected") == 0:
            self.running = False

    def infect(self):
        agent_keys = list(self.schedule._agents.keys())
        susceptible = []
        for agent_key in agent_keys:
            if self.schedule._agents[agent_key].name == "Susceptible":
                susceptible.append(agent_key)
        for agent_key in susceptible:
            agent = self.schedule._agents[agent_key]
            neighbors = self.space.get_neighbors(agent.pos,
                                                 self.social_distance)
            for neighbor in neighbors:
                if neighbor.name == "Infected":
                    asymptomatic = False
                    if (100.0 * self.random.random() <
                            self.asymptomatic_percentage):
                        asymptomatic = True
                    person = Infected(self.next_id(), self, agent.pos,
                                      asymptomatic)
                    if self.imperial:
                        person.set_imperial(agent.home, agent.work,
                                            agent.travel)
                    self.space.remove_agent(agent)
                    self.schedule.remove(agent)
                    self.space.place_agent(person, person.pos)
                    self.schedule.add(person)
                    break

    def count(self, type):
        agent_keys = list(self.schedule._agents.keys())
        num = 0
        for agent_key in agent_keys:
            if self.schedule._agents[agent_key].name == type:
                num += 1
        return num
예제 #9
0
파일: test_space.py 프로젝트: GeoESW/mesa
class TestSpaceToroidal(unittest.TestCase):
    '''
    Testing a toroidal continuous space.
    '''

    def setUp(self):
        '''
        Create a test space and populate with Mock Agents.
        '''
        self.space = ContinuousSpace(70, 20, True, -30, -30, 100, 100)
        self.agents = []
        for i, pos in enumerate(TEST_AGENTS):
            a = MockAgent(i, None)
            self.agents.append(a)
            self.space.place_agent(a, pos)

    def test_agent_positions(self):
        '''
        Ensure that the agents are all placed properly.
        '''
        for i, pos in enumerate(TEST_AGENTS):
            a = self.agents[i]
            assert a.pos == pos

    def test_distance_calculations(self):
        '''
        Test toroidal distance calculations.
        '''
        pos_1 = (-30, -30)
        pos_2 = (70, 20)
        assert self.space.get_distance(pos_1, pos_2) == 0

        pos_3 = (-30, -20)
        assert self.space.get_distance(pos_1, pos_3) == 10

    def test_heading(self):
        pos_1 = (-30, -30)
        pos_2 = (70, 20)
        self.assertEqual((0, 0), self.space.get_heading(pos_1, pos_2))

        pos_1 = (65, -25)
        pos_2 = (-25, -25)
        self.assertEqual((10, 0), self.space.get_heading(pos_1, pos_2))

    def test_neighborhood_retrieval(self):
        '''
        Test neighborhood retrieval
        '''
        neighbors_1 = self.space.get_neighbors((-20, -20), 1)
        assert len(neighbors_1) == 2

        neighbors_2 = self.space.get_neighbors((40, -10), 10)
        assert len(neighbors_2) == 0

        neighbors_3 = self.space.get_neighbors((-30, -30), 10)
        assert len(neighbors_3) == 1

    def test_bounds(self):
        '''
        Test positions outside of boundary
        '''
        boundary_agents = []
        for i, pos in enumerate(OUTSIDE_POSITIONS):
            a = MockAgent(len(self.agents) + i, None)
            boundary_agents.append(a)
            self.space.place_agent(a, pos)

        for a, pos in zip(boundary_agents, OUTSIDE_POSITIONS):
            adj_pos = self.space.torus_adj(pos)
            assert a.pos == adj_pos

        a = self.agents[0]
        for pos in OUTSIDE_POSITIONS:
            assert self.space.out_of_bounds(pos)
            self.space.move_agent(a, pos)
예제 #10
0
파일: test_space.py 프로젝트: bangtree/mesa
class TestSpaceNonToroidal(unittest.TestCase):
    '''
    Testing a toroidal continuous space.
    '''

    def setUp(self):
        '''
        Create a test space and populate with Mock Agents.
        '''
        self.space = ContinuousSpace(70, 20, False, -30, -30)
        self.agents = []
        for i, pos in enumerate(TEST_AGENTS):
            a = MockAgent(i, None)
            self.agents.append(a)
            self.space.place_agent(a, pos)

    def test_agent_positions(self):
        '''
        Ensure that the agents are all placed properly.
        '''
        for i, pos in enumerate(TEST_AGENTS):
            a = self.agents[i]
            assert a.pos == pos

    def test_agent_matching(self):
        '''
        Ensure that the agents are all placed and indexed properly.
        '''
        for i, agent in self.space._index_to_agent.items():
            assert agent.pos == tuple(self.space._agent_points[i, :])
            assert i == self.space._agent_to_index[agent]

    def test_distance_calculations(self):
        '''
        Test toroidal distance calculations.
        '''

        pos_2 = (70, 20)
        pos_3 = (-30, -20)
        assert self.space.get_distance(pos_2, pos_3) == 107.70329614269008

    def test_heading(self):
        pos_1 = (-30, -30)
        pos_2 = (70, 20)
        self.assertEqual((100, 50), self.space.get_heading(pos_1, pos_2))

        pos_1 = (65, -25)
        pos_2 = (-25, -25)
        self.assertEqual((-90, 0), self.space.get_heading(pos_1, pos_2))

    def test_neighborhood_retrieval(self):
        '''
        Test neighborhood retrieval
        '''
        neighbors_1 = self.space.get_neighbors((-20, -20), 1)
        assert len(neighbors_1) == 2

        neighbors_2 = self.space.get_neighbors((40, -10), 10)
        assert len(neighbors_2) == 0

        neighbors_3 = self.space.get_neighbors((-30, -30), 10)
        assert len(neighbors_3) == 0

    def test_bounds(self):
        '''
        Test positions outside of boundary
        '''
        for i, pos in enumerate(OUTSIDE_POSITIONS):
            a = MockAgent(len(self.agents) + i, None)
            with self.assertRaises(Exception):
                self.space.place_agent(a, pos)

        a = self.agents[0]
        for pos in OUTSIDE_POSITIONS:
            assert self.space.out_of_bounds(pos)
            with self.assertRaises(Exception):
                self.space.move_agent(a, pos)