예제 #1
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
예제 #2
0
class TestSpaceAgentMapping(unittest.TestCase):
    '''
    Testing a continuous space for agent mapping during removal.
    '''
    def setUp(self):
        '''
        Create a test space and populate with Mock Agents.
        '''
        self.space = ContinuousSpace(70, 50, False, -30, -30)
        self.agents = []
        for i, pos in enumerate(REMOVAL_TEST_AGENTS):
            a = MockAgent(i, None)
            self.agents.append(a)
            self.space.place_agent(a, pos)

    def test_remove_first(self):
        '''
        Test removing the first entry
        '''
        agent_to_remove = self.agents[0]
        self.space.remove_agent(agent_to_remove)
        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]
        assert agent_to_remove not in self.space._agent_to_index
        assert agent_to_remove.pos is None
        with self.assertRaises(Exception):
            self.space.remove_agent(agent_to_remove)

    def test_remove_last(self):
        '''
        Test removing the last entry
        '''
        agent_to_remove = self.agents[-1]
        self.space.remove_agent(agent_to_remove)
        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]
        assert agent_to_remove not in self.space._agent_to_index
        assert agent_to_remove.pos is None
        with self.assertRaises(Exception):
            self.space.remove_agent(agent_to_remove)

    def test_remove_middle(self):
        '''
        Test removing a middle entry
        '''
        agent_to_remove = self.agents[3]
        self.space.remove_agent(agent_to_remove)
        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]
        assert agent_to_remove not in self.space._agent_to_index
        assert agent_to_remove.pos is None
        with self.assertRaises(Exception):
            self.space.remove_agent(agent_to_remove)
예제 #3
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
예제 #4
0
class PJIAModel(Model):
    """A model with some number of agents."""
    def __init__(
            self,
            # Define canvas
            width=1000,
            height=1000 * 480. / 1100,
            # Define agents
            n_offloaders=1,
            offloaders_speed=5,
            coordinator_memory=2,
            equipment_speed=10,
            # Define actions of agents
            arrival_window=30,
            interaction_aircraft_offloader=10,
            interaction_coordinator_offloader=5,
            interaction_aircraft_coordinator=5,
            # Define positions [% of canvas]
            offloaders_position=[0.1, 0.2],
            coordinator_position=[0.05, 0.5],
            equipment_position=[0.2, 0.1],
            terminal_building_pos=[0.25, 0.21]):

        # Define canvas
        self.space = ContinuousSpace(width, height, False)
        self.airport_coordinates = airport_coordinates

        # Define aircraft agents
        self.aircraft_schedule = acSchema
        self.n_aircraft = len(self.aircraft_schedule.Arrival)
        self.total_amount_cargo = sum(self.aircraft_schedule.Cargo)

        # Define coordinator agents
        self.coordinator_position = coordinator_position
        self.coordinator_memory = coordinator_memory

        # Define the offloaders agents
        self.n_offloaders = n_offloaders
        self.offloaders_position = offloaders_position
        self.offloaders_speed = offloaders_speed

        # Define Equipment objects:
        self.equipment_position = equipment_position
        self.equipment_speed = equipment_speed

        # Define Cargo objects:
        self.cargo_number = 0  # will be used for later agents/objects
        #self.terminal_building_pos = terminal_building_pos
        self.terminal_building_pos = [
            terminal_building_pos[0] * self.space.x_max,
            terminal_building_pos[1] * self.space.y_max
        ]

        # Define interactions:
        self.interaction_aircraft_offloader = interaction_aircraft_offloader
        self.interaction_coordinator_offloader = interaction_coordinator_offloader
        self.interaction_aircraft_coordinator = interaction_aircraft_coordinator

        # =============================================================================
        #         voor taxiing
        # =============================================================================
        # Copy the the table from excel
        self.taxi_coordinates_excel = pd.DataFrame.copy(airport_coordinates,
                                                        deep=True)
        # Multiply the coordinates in excel (which are in percentage) by the width and height of the grid
        self.taxi_coordinates_excel['X_pos'] *= self.space.x_max
        self.taxi_coordinates_excel['Y_pos'] *= self.space.y_max

        # make array with only coordinates
        self.taxi_coordinates = np.array([[
            self.taxi_coordinates_excel['X_pos'][0],
            self.taxi_coordinates_excel['Y_pos'][0]
        ]])

        for i in range(1, len(self.taxi_coordinates_excel)):
            self.taxi_coordinates = np.append(self.taxi_coordinates, [[
                self.taxi_coordinates_excel['X_pos'][i],
                self.taxi_coordinates_excel['Y_pos'][i]
            ]],
                                              axis=0)

        # make array with only taxi nodes coordinates:
        self.CP_coordinates = self.taxi_coordinates[13:]

        # Civilian Parking spots, name and occupation
        #self.CP_spots = {'CP1' : 'Free', 'CP2': 'Free', 'CP3': 'Free', 'CP4': 'Free', 'CP5': 'Free', 'CP6': 'Free', 'CP7': 'Free', 'CP8': 'Free', 'CP9': 'Free', 'CP10': 'Free'}
        #self.CP_spots_occupation = ['Free','Free', 'Free', 'Free', 'Free', 'Free','Free', 'Free','Free']
        self.CP_spots_occupation = [
            'Free', 'Free', 'Occupied', 'Free', 'Occupied', 'Free', 'Free',
            'Free', 'Free'
        ]
        self.CP_spots_name = [
            'CP1', 'CP2', 'CP3', 'CP4', 'CP5', 'CP6', 'CP7', 'CP8', 'CP9'
        ]

        # Determine all the routes from start point to parking
        self.route_S1_CP14 = np.array([self.taxi_coordinates[0]])
        self.route_S2_CP14 = np.array(
            [self.taxi_coordinates[1], self.taxi_coordinates[0]])

        self.route_S1_CP5 = np.array(
            [self.taxi_coordinates[0], self.taxi_coordinates[1]])
        self.route_S2_CP5 = np.array([self.taxi_coordinates[1]])

        self.route_S1_CP6 = np.array([
            self.taxi_coordinates[0], self.taxi_coordinates[1],
            self.taxi_coordinates[2]
        ])
        self.route_S2_CP6 = np.array(
            [self.taxi_coordinates[1], self.taxi_coordinates[2]])

        self.route_S1_CP7 = np.array([
            self.taxi_coordinates[0], self.taxi_coordinates[1],
            self.taxi_coordinates[2], self.taxi_coordinates[3]
        ])
        self.route_S2_CP7 = np.array([
            self.taxi_coordinates[1], self.taxi_coordinates[2],
            self.taxi_coordinates[3]
        ])

        self.route_S1_CP89 = np.array([
            self.taxi_coordinates[0], self.taxi_coordinates[1],
            self.taxi_coordinates[2], self.taxi_coordinates[5]
        ])
        self.route_S2_CP89 = np.array([
            self.taxi_coordinates[1], self.taxi_coordinates[2],
            self.taxi_coordinates[5]
        ])

        # Determine routes from parking to exit
        self.route_CP13_E1 = np.array([
            self.taxi_coordinates[4], self.taxi_coordinates[7],
            self.taxi_coordinates[6], self.taxi_coordinates[11]
        ])

        self.route_CP4_E2 = np.array([
            self.taxi_coordinates[1], self.taxi_coordinates[2],
            self.taxi_coordinates[3], self.taxi_coordinates[12]
        ])

        self.route_CP5_E2 = np.array([
            self.taxi_coordinates[2], self.taxi_coordinates[3],
            self.taxi_coordinates[12]
        ])

        self.route_CP67_E2 = np.array(
            [self.taxi_coordinates[3], self.taxi_coordinates[12]])

        self.route_CP89_E2 = np.array([
            self.taxi_coordinates[5], self.taxi_coordinates[2],
            self.taxi_coordinates[3], self.taxi_coordinates[12]
        ])
        # =============================================================================

        # Define the running
        # Stop when all aircraft have exited
        self.exited_aircraft = 0
        self.schedule = RandomActivation(self)
        # Make all agents
        self.make_coordinator()
        self.make_offloader()
        self.make_aircraft()
        self.make_equipment()
        self.make_cargo()

        # Start running
        self.running = True
        self.start_time = 0
        self.exit_step = 1000

    # =========================================================================
    #  Create all aircraft, the aircraft are not all initialized at the same time,
    #  but within an arrival window.
    # =========================================================================

    def make_aircraft(self):

        # =============================================================================
        #             # Starting position
        #             pos = np.array((aircraft_schedule.Origin_X[i]* self.space.x_max, aircraft_schedule.Origin_Y[i] * self.space.y_max))
        #             # Position of parking spot
        #             parking_pos = np.array((aircraft_schedule.Parking_X[i] * self.space.x_max, aircraft_schedule.Parking_Y[i] * self.space.y_max))
        # =============================================================================

        for i in range(self.n_aircraft):
            # Look for the correct position of the starting point
            for x in range(len(self.airport_coordinates)):
                if self.aircraft_schedule.Start_Name[
                        i] == self.airport_coordinates.Name[x]:
                    Start_X = airport_coordinates.X_pos[x]
                    Start_Y = airport_coordinates.Y_pos[x]

            ## Get the aircraft data and schedule from the excel file 'aircraft_schedule'
            # Starting pos
            pos = np.array(
                (Start_X * self.space.x_max, Start_Y * self.space.y_max))
            # # Position of exit
            # exit_pos = np.array((self.aircraft_schedule.Exit_X[i] * self.space.x_max, self.aircraft_schedule.Exit_Y[i] * self.space.y_max))
            # Time the aircraft 'lands'
            arrival_time = self.aircraft_schedule.Arrival[i]
            # Speed of the aircraft
            speed = self.aircraft_schedule.Speed[i]
            # Amount of cargo in the aircraft
            n_cargo = self.aircraft_schedule.Cargo[i]
            # The position/ID in the schedule
            schedule_ID = self.aircraft_schedule.Aircraft_ID[i]

            print('I am aircraft', schedule_ID, 'my starting pos is:', pos)
            aircraft = Aircraft(
                i,
                self,
                pos,
                #parking_pos,
                arrival_time,
                speed,
                n_cargo,
                schedule_ID)

            self.space.place_agent(aircraft, pos)
            self.schedule.add(aircraft)

    # =========================================================================
    #  Create all offloaders
    # =========================================================================

    def make_offloader(self):

        for i in range(self.n_offloaders):
            # Starting position is the waiting position
            waiting_pos = np.array(
                (self.offloaders_position[0] * self.space.x_max,
                 self.offloaders_position[1] * self.space.y_max))
            pos = waiting_pos
            speed = self.offloaders_speed

            print('I am an offloader and my starting pos is:', pos)
            offloader = OffloadingAgent(i + self.n_aircraft, self, pos,
                                        waiting_pos, speed)

            self.space.place_agent(offloader, pos)
            self.schedule.add(offloader)

    # =========================================================================
    #  Create coordinator
    # =========================================================================

    def make_coordinator(self):

        # for i in range(self.n_offloaders):
        # Starting position is the waiting position
        waiting_pos = np.array(
            (self.coordinator_position[0] * self.space.x_max,
             self.coordinator_position[1] * self.space.y_max))
        pos = waiting_pos
        speed = self.offloaders_speed

        print('I am a coordinator and my starting pos is:', pos)
        coordinator = CoordinatingAgent(
            1 + self.n_aircraft + self.n_offloaders,
            self,
            pos,
            waiting_pos,
            speed,
            coordinator_memory=self.coordinator_memory)

        self.space.place_agent(coordinator, pos)
        self.schedule.add(coordinator)

    # =========================================================================
    #  Create equipment for offloading
    # =========================================================================

    def make_equipment(self):

        # for i in range(self.n_offloaders):
        # Starting position is the waiting position
        parking_pos = np.array((self.equipment_position[0] * self.space.x_max,
                                self.equipment_position[1] * self.space.y_max))
        pos = parking_pos
        speed = self.equipment_speed

        equipment = Equipment(1 + self.n_aircraft + self.n_offloaders + 1,
                              self, pos, parking_pos, speed)

        self.space.place_agent(equipment, pos)
        self.schedule.add(equipment)

    # =========================================================================
    #  Create cargo
    # =========================================================================

    def make_cargo(self):
        cargo_number = 0
        #terminal_building_pos = self.terminal_building_pos

        for i in range(self.n_aircraft):
            n_cargo = self.aircraft_schedule.Cargo[i]

            # Look for the correct position of the starting point
            for x in range(len(self.airport_coordinates)):
                if self.aircraft_schedule.Start_Name[
                        i] == self.airport_coordinates.Name[x]:
                    Start_X = airport_coordinates.X_pos[x]
                    Start_Y = airport_coordinates.Y_pos[x]
                    break

            for j in range(n_cargo):
                ## Starting pos
                pos = np.array(
                    (Start_X * self.space.x_max, Start_Y * self.space.y_max))
                # The position/ID in the schedule
                schedule_ID = self.aircraft_schedule.Aircraft_ID[i]
                # Cargo_number for the ID when creating a cargo agent
                cargo_number += 1
                #previous_cargo_number = cargo_number
                cargo = Cargo(
                    cargo_number + self.n_aircraft + self.n_offloaders + 1 +
                    1,  # 1xCoordinator and 1x Equipment
                    self,
                    pos,
                    schedule_ID)

                self.space.place_agent(cargo, pos)
                self.schedule.add(cargo)
        self.cargo_number = cargo_number
        print('cargo number', cargo_number)

# =============================================================================
#
# # =============================================================================
# # dummy
# # =============================================================================
#     def make_dummy(self):
#         pos = np.array((0.03*self.space.x_max,0.03*self.space.y_max))
#         speed = 5
#         destinations = np.array([[self.space.x_max-0.0001,0.03*self.space.y_max], [self.space.x_max*0.03,self.space.y_max-0.0001]])
#         print('destinations dummies', destinations)
#         for i in range(2):
#             destination = destinations[i]
#             dummy_name = i+1
#             print('I am dummy:', dummy_name)
#             print('my destination is:', destination)
#             print('I am agent number:', dummy_name + self.cargo_number + self.n_aircraft + self.n_offloaders + 1 + 1)
#             dummy = Dummy(
#                         dummy_name + self.cargo_number + self.n_aircraft + self.n_offloaders + 1 + 1, # 1xCoordinator and 1x Equipment
#                         self,
#                         pos,
#                         speed,
#                         destination,
#                         dummy_name
#                         )
#
#             self.space.place_agent(dummy, pos)
#             self.schedule.add(dummy)
# =============================================================================
# =========================================================================
# Define what happens in the model in each step.
# =========================================================================

    def step(self):
        #all_arrived = True
        if self.schedule.steps == 0:
            self.start_time = time.time()

        if self.schedule.steps == self.exit_step:
            self.running = False
        elif self.n_aircraft == self.exited_aircraft:
            if self.exit_step == 1000:
                self.exit_step = self.schedule.steps + 50
                print("--- % s seconds ---" %
                      round(time.time() - self.start_time, 2))

        self.schedule.step()
        for agent in self.schedule.agents:
            if type(agent) == Aircraft:
                if agent.aircraft_state == 'Gone':
                    self.space.remove_agent(agent)
                    self.schedule.remove(agent)
예제 #5
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
예제 #6
0
class Classroom(Model):
    def __init__(self, floorplan, human_count):
        super().__init__()
        self.n_agents = human_count
        self.floorplan = []
        self.humans = []
        self.obstacles = []
        self.exits = []
        self.spawns = []
        self.scheduler = DistanceScheduler(self)

        # Loads floorplan textfile
        with open('C:/Users/jozse/github/ABMasters/floorplans/' +
                  floorplan) as f:
            [
                self.floorplan.append(line.strip().split())
                for line in f.readlines()
            ]

        # Creates continuous Mesa space & discrete grid for pathfinding
        size = len(self.floorplan[0]), len(self.floorplan)
        self.space = ContinuousSpace(size[0], size[1], torus=False)
        self.grid = []

        for y in range(6 * size[1]):
            row = []
            for x in range(6 * size[0]):
                row.append(ca.Node((x, y)))
            self.grid.append(row)

# Places all elements in Mesa space and grid
        for x in range(size[0]):
            for y in range(size[1]):
                value = str(self.floorplan[y][x])

                if value == 'W':
                    self.new_agent(ca.Wall, (x, y))
                    for i in range(6 * x, 6 * (x + 1)):
                        for j in range(6 * y, 6 * (y + 1)):
                            self.grid[j][i].done = True

                elif value == 'F':
                    self.new_agent(ca.Furniture, (x, y))
                    for i in range(6 * x, 6 * (x + 1)):
                        for j in range(6 * y, 6 * (y + 1)):
                            self.grid[j][i].done = True

                elif value == 'S':
                    self.spawns.append((x, y))

                elif value == 'E':
                    self.new_agent(ca.Exit, (x, y))
                    i = 6 * x + 1
                    j = 6 * y + 1
                    self.grid[j][i].exit = True

        # Spawn specified number of Humans in spawn points
        humans = rnd.sample(self.spawns, self.n_agents)
        for pos in humans:
            self.new_agent(ca.Human, pos)
        print("Classroom initialised.")

    def new_agent(self, agent_type, pos):
        '''
		Method that creates a new agent, and adds it to the correct list.
		'''
        agent = agent_type(self, pos)
        self.space.place_agent(agent, pos)

        if agent_type.__name__ == "Human":
            self.humans.append(agent)
        elif agent_type.__name__ == "Exit":
            self.exits.append(agent)
        else:
            self.obstacles.append(agent)

    def remove_agent(self, agent):
        '''
		Method that removes an agent from the grid and the correct scheduler.
		'''
        self.space.remove_agent(agent)
        if {type(agent).__name__} == "Human":
            self.scheduler.remove(agent)
            self.humans.remove(agent)

    def step(self):
        '''
		Method that steps every agent.
		'''
        self.scheduler.step()

    def run_model(self):
        self.step()
예제 #7
0
class Classroom(Model):
    def __init__(self, floorplan, human_count):
        super().__init__()
        self.n_agents = human_count
        self.floorplan = []
        self.humans = []
        self.obstacles = []
        self.exits = []
        self.spawns = []
        self.scheduler = DistanceScheduler(self)

        # Creates continuous Mesa space & discrete grid for pathfinding
        size = len(self.floorplan[0]), len(self.floorplan)
        self.space = ContinuousSpace(size[0], size[1], torus=False)
        self.grid = []

        for y in range(6 * size[1]):
            row = []
            for x in range(6 * size[0]):
                row.append(ca.Node((x, y)))
            self.grid.append(row)

# Places all elements in Mesa space and grid
        for x in range(size[0]):
            for y in range(size[1]):
                value = str(self.floorplan[y][x])

                if value == 'W':
                    self.new_agent(ca.Wall, (x, y))
                    for i in range(6 * x, 6 * (x + 1)):
                        for j in range(6 * y, 6 * (y + 1)):
                            self.grid[j][i].done = True

                elif value == 'F':
                    self.new_agent(ca.Furniture, (x, y))
                    for i in range(6 * x, 6 * (x + 1)):
                        for j in range(6 * y, 6 * (y + 1)):
                            self.grid[j][i].done = True

                elif value == 'S':
                    self.spawns.append((x, y))

                elif value == 'E':
                    self.new_agent(ca.Exit, (x, y))
                    i = 6 * x + 1
                    j = 6 * y + 1
                    self.grid[j][i].exit = True

        # Spawn n_agents according to floorplan
        for pos in rnd.sample(self.spawns, self.n_agents):
            self.new_agent(ca.Human, pos)

    def new_agent(self, agent_type, pos):
        '''
		Method that creates a new agent, and adds it to the correct list.
		'''
        agent = agent_type(self, pos)
        self.space.place_agent(agent, pos)

        if agent_type.__name__ == "Human":
            self.humans.append(agent)
        elif agent_type.__name__ == "Exit":
            self.exits.append(agent)
        else:
            self.obstacles.append(agent)

    def remove_agent(self, agent):
        '''
		Method that removes an agent from the grid and the correct scheduler.
		'''
        self.space.remove_agent(agent)
        if {type(agent).__name__} == "Human":
            self.scheduler.remove(agent)
            self.humans.remove(agent)

    def step(self):
        '''
		Method that steps every agent.
		'''
        self.scheduler.step()

    def run_model(self):
        self.step()
class Prey_model(Model):
    def __init__(self, Prey_count, Tiger_count, width, height, CANVAS):
        self.count = 0  # Number of agents
        self.schedule = mesa.time.RandomActivation(self)
        self.space = ContinuousSpace(width + 1, height + 1, torus=False)
        self.step_num = 0
        self.last_uid = 0
        self.canvas = CANVAS
        self.grass_ticks = dict()
        self.Prey_count = 0
        self.Tiger_count = 0

        # Create patches
        for x, y in itertools.product(range(width), range(height)):
            a = Patch(self.new_uid(), self)
            # self.schedule.add(a)
            self.space.place_agent(a, (x, y))
            a.canvas = CANVAS
            a.draw()

        # Create Animals:
        for i in range(Prey_count):
            x = random.randrange(self.space.width)
            y = random.randrange(self.space.width)
            self.create_baby(x, y, age=random.randint(1, 5))
        for i in range(Tiger_count):
            x = random.randrange(self.space.width)
            y = random.randrange(self.space.width)
            self.create_baby(x, y, age=random.randint(1, 5), type='Tiger')

    def kill(self, a):
        if a.type == 'Prey':
            self.Prey_count -= 1
        else:
            self.Tiger_count -= 1
        x_1, y_1 = pos_box(a.pos)[:2]
        self.canvas.delete(a.icon)
        self.count -= 1
        self.space.remove_agent(a)
        self.schedule.remove(a)
        self.canvas.create_text(x_1, y_1, text="x", font=12, justify='center')

    def new_uid(self):
        '''Get a new uid and keep track of the last one'''
        uid = self.last_uid + 1
        self.last_uid = uid
        return uid

    def create_baby(self, x, y, age=0, type='Prey'):
        '''Create an animal and give it a ref to the CANVAS'''
        if type == 'Prey':
            a = Prey(self.new_uid(), self, age=age)
            self.Prey_count += 1
        else:
            a = Tiger(self.new_uid(), self, age=age)
            self.Tiger_count += 1
        self.schedule.add(a)
        self.space.place_agent(a, (x, y))
        self.count += 1
        a.canvas = self.canvas
        a.draw()

    def step(self):
        self.step_num += 1
        # print("Stepping:", self.step_num)

        # Regrow any grass that's due
        # Much faster than trying to call each individual grass cell as an agent every tick
        if self.step_num in self.grass_ticks:
            for grass in self.grass_ticks[self.step_num]:
                grass.regrow()
            del self.grass_ticks[self.step_num]

        # Move the agents
        self.schedule.step()

        if self.count <= 0:
            poem = '''
			No sun - no moon
			No morn - no noon
			No dawn - no dusk - no proper time of day
			No warmth, no cheerfulness, no healthful ease
			No comfortable feel in any member
			No shade, no shine, no butterflies, no bees
			No fruits, no flowers, no leaves, no birds
			November'''  # A poem by Thomas Hood
            for line in re.split('\n', poem):
                print(line)
                time.sleep(.1)
예제 #9
0
파일: test_space.py 프로젝트: bangtree/mesa
class TestSpaceAgentMapping(unittest.TestCase):
    '''
    Testing a continuous space for agent mapping during removal.
    '''

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

    def test_remove_first(self):
        '''
        Test removing the first entry
        '''
        agent_to_remove = self.agents[0]
        self.space.remove_agent(agent_to_remove)
        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]
        assert agent_to_remove not in self.space._agent_to_index
        assert agent_to_remove.pos is None
        with self.assertRaises(Exception):
            self.space.remove_agent(agent_to_remove)

    def test_remove_last(self):
        '''
        Test removing the last entry
        '''
        agent_to_remove = self.agents[-1]
        self.space.remove_agent(agent_to_remove)
        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]
        assert agent_to_remove not in self.space._agent_to_index
        assert agent_to_remove.pos is None
        with self.assertRaises(Exception):
            self.space.remove_agent(agent_to_remove)

    def test_remove_middle(self):
        '''
        Test removing a middle entry
        '''
        agent_to_remove = self.agents[3]
        self.space.remove_agent(agent_to_remove)
        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]
        assert agent_to_remove not in self.space._agent_to_index
        assert agent_to_remove.pos is None
        with self.assertRaises(Exception):
            self.space.remove_agent(agent_to_remove)