def contains_agent(grid: MultiGrid, pos: Tuple[int, int]): objs = grid.iter_cell_list_contents(pos) return any(map(lambda obj: issubclass(type(obj), Agent), objs))
class RoadNetworkModel(Model): description = ( "A model for simulating Road Network Model" ) def __init__(self, number_of_cars, width, height, is_odd_even_policy_enabled, is_odd_date, policy_range_time): # Tick increment self.tick = 0 # Mean Travel Time self.mean_travel_time = 0.0 # Odd-Even Policy Enabled self.is_odd_even_policy_enabled = is_odd_even_policy_enabled # Set the day of the week self.is_odd_date = is_odd_date # Set up Spatial dimension self.grid = MultiGrid(width, height, True) # Set up Temporal dimension self.schedule = SimultaneousActivation(self) self.running = True self.policy_range_time = policy_range_time # Set up peak hours self.start_peak_hour_1 = PEAK_HOURS["START_PEAK_HOUR_1"] #7 self.end_peak_hour_1 = PEAK_HOURS["END_PEAK_HOUR_1"] #10 self.start_peak_hour_2 = PEAK_HOURS["START_PEAK_HOUR_2"] #4 self.end_peak_hour_2 = PEAK_HOURS["END_PEAK_HOUR_2"] #7 # Car distribution num_highly_active_cars = math.ceil(ACTIVITY_PROPORTION["HIGHLY_ACTIVE"] * number_of_cars) num_business_hours_cars = math.ceil(ACTIVITY_PROPORTION["BUSINESS_HOURS"] * number_of_cars) num_peak_hours_cars = number_of_cars - (num_highly_active_cars + num_business_hours_cars) # generate road self.map = MapGenerator() roadPosition = self.map.get_road_position() for i in range(len(roadPosition)): road = Road(i, roadPosition[i], self) self.grid.place_agent(road, roadPosition[i]) ## generate office officePosition = self.map.get_office_position() for i in range(len(officePosition)): office = Office(i, officePosition[i], self) self.grid.place_agent(office, officePosition[i]) # generate residence residencePosition = self.map.get_residence_position() for i in range(len(residencePosition)): residence = Residence(i, residencePosition[i], self) self.grid.place_agent(residence, residencePosition[i]) # generate entertainment entertainmentPosition = self.map.get_entertainment_position() for i in range(len(entertainmentPosition)): entertainment = Entertainment(i, entertainmentPosition[i], self) self.grid.place_agent(entertainment, entertainmentPosition[i]) # generate traffic light trafficLightPosition = self.map.get_traffic_light_position() for i in range(len(trafficLightPosition)): trafficLight = TrafficLight(i, trafficLightPosition[i], self, COLOR["dark_grey"]) self.grid.place_agent(trafficLight, trafficLightPosition[i]) # Get source and destination lists residence_list = self.map.get_residence_position() office = self.map.get_office_position() entertainment = self.map.get_entertainment_position() # Create destination list based on weekday/weekend proportion proportion_of_office_workers = 0.65 number_of_office_workers = math.ceil(proportion_of_office_workers * number_of_cars) number_of_shopper = number_of_cars - number_of_office_workers office_list = [] while len(office_list) <= number_of_office_workers: office_list.append(office[self.random.randint(0, len(office) -1)]) entertainment_list = [] while len(entertainment_list) <= number_of_shopper: entertainment_list.append(entertainment[self.random.randint(0, len(entertainment) - 1)]) office_entertainment_list = office_list + entertainment_list random.shuffle(residence_list) layout = self.map.get_layout() for i in range(number_of_cars): # determine departure and return time based on activity level if i <= num_highly_active_cars: activity_level = "HIGHLY_ACTIVE" departure_time = 0 return_time = float("inf") elif i <= num_business_hours_cars: activity_level = "BUSINESS_HOURS" departure_time = self.start_peak_hour_1 return_time = float("inf") else: activity_level = "PEAK_HOURS" departure_time = self.random.randint(self.start_peak_hour_1,self.end_peak_hour_1) return_time = self.random.randint(self.start_peak_hour_2,self.end_peak_hour_2) plate_number_oddity = self.random.randint(0, 1) source_x = residence_list[i][0] source_y = residence_list[i][1] destination_x = office_entertainment_list[i][0] destination_y = office_entertainment_list[i][1] state_fringes = self.map.get_fringes(source_x, source_y) shortest_distance = float("inf") car_direction = state_fringes[0][1] for state_fringe in state_fringes: current_direction = state_fringe[1] # "^" "v" ">" "<" if current_direction in DIRECTION: temp_x = state_fringe[0][0] + DIRECTION[current_direction][0] temp_y = state_fringe[0][1] + DIRECTION[current_direction][1] newDist = get_euclidean_distance((temp_x, temp_y), (destination_x, destination_y)) if newDist < shortest_distance: shortest_distance = newDist car_direction = current_direction # all cars are initialised as IDLE car_state = "IDLE" car = Car(i, plate_number_oddity, (source_x,source_y), (destination_x,destination_y), car_direction, car_state, departure_time, return_time, activity_level, self) self.grid.place_agent(car, (source_x,source_y)) self.schedule.add(car) # Data Collection self.datacollector = DataCollector({ "Idle": number_idle_cars, "Move": number_move_cars, "Finished": number_finished_cars, "SimulationMinutes": simulation_minutes, "ToOffice": number_office, "ToResidence": number_residence, "MeanTravelTime": mean_travel_time, "StdTravelTime": std_travel_time }) self.datacollector.collect(self) def step(self): self.schedule.step() self.tick += 1 self.mean_travel_time = np.mean([cell.travel_time for j in range(100) for i in range(100) for cell in self.grid.iter_cell_list_contents((i,j)) if type(cell) is Car]) self.datacollector.collect(self) # After a day (1440 minutes), stop the simulation if self.tick >= 1440: self.running = False def is_plate_number_oddity_allowed(self, plate_number_oddity=0, xy=(0, 0)): x, y = xy # implement odd even policy for avenue only. if(self.map.is_avenue(x, y)): if(self.is_odd_date == True): # date is odd if(plate_number_oddity % 2 == 1): # plate is odd return True else: return False else: # date is even if(plate_number_oddity % 2 == 0): # plate is even return True else: return False else: return True def is_odd_even_policy_time(self): #1 day == 1440 minutes day_tick = self.tick % 1440 if self.policy_range_time == '7_10_and_16_19': if day_tick >= (7 * 60) and day_tick <= (10 * 60): return True elif day_tick >= (16 * 60) and day_tick <= (19 * 60): return True else: return False elif self.policy_range_time == '8_11_and_17_20': if day_tick >= (8 * 60) and day_tick <= (11 * 60): return True elif day_tick >= (17 * 60) and day_tick <= (20 * 60): return True else: return False elif self.policy_range_time == '6_9_and_15_18': if day_tick >= (6 * 60) and day_tick <= (9 * 60): return True elif day_tick >= (15 * 60) and day_tick <= (18 * 60): return True else: return False elif self.policy_range_time == '8_9_and_17_18': if day_tick >= (8 * 60) and day_tick <= (9 * 60): return True elif day_tick >= 17 * 60 and day_tick <= 18 * 60: return True else: return False elif self.policy_range_time == '6_11_and_15_20': if day_tick >= (6 * 60) and day_tick <= (11 * 60): return True elif day_tick >= (15 * 60) and day_tick <= (20 * 60): return True else: return False else: return False