def __init__(self) -> None: """Initialize a Simulation. """ self._events = PriorityQueue() self._dispatcher = Dispatcher() self._monitor = Monitor()
def run(self, start: datetime, end: datetime) -> None: """Run the simulation from <start> to <end>. """ step = timedelta(minutes=1) # Each iteration spans one minute of time for ride in self.all_rides: PriorityQueue.add(RideStartEvent(ride)) while start <= end: # self._update_active_rides(start) self._update_active_rides_fast(start) if start < end: self.update_availability_and_unoccupied() self.visualizer.render_drawables( list(self.all_stations.values()) + self.active_rides, start) start += step if start == end: self.active_rides = [] # Leave this code at the very bottom of this method. # It will keep the visualization window open until you close # it by pressing the 'X'. while True: if self.visualizer.handle_window_events(): return # Stop the simulation
def __init__(self, station_file: str, ride_file: str) -> None: """Initialize this simulation with the given configuration settings. """ self.all_stations = create_stations(station_file) self.all_rides = create_rides(ride_file, self.all_stations) self.active_rides = [] self.visualizer = Visualizer() self.event_queue = PriorityQueue()
def __init__(self): """Initialize a Simulation. @type self: Simulation @rtype: None """ self._events = PriorityQueue() self._dispatcher = Dispatcher() self._monitor = Monitor()
def __init__(self, store_file): """Initialize a GroceryStoreSimulation from a file. @type store_file: str A file containing the configuration of the grocery store. @rtype: None """ self._events = PriorityQueue() self._store = GroceryStore(store_file)
def __init__(self, file_path, text_grid=None): """ If text_grid is None, initialize a new Grid assuming file_path contains pathname to a text file with the following format: ..+..++ ++.B..+ .....++ ++..... .T....+ where a dot indicates a navigable Node, a plus indicates a non-navigable Node, B indicates the boat, and T the treasure. The width of this grid is 7 and height is 5. If text_grid is not None, it should be a list of strings representing a Grid. One string element of the list represents one row of the Grid. For example the grid above, should be stored in text_grid as follows: ["..+..++", "++.B..+", ".....++", "++.....", ".T....+"] @type file_path: str - a file pathname. See the above for the file format. - it should be ignored if text_grid is not None. - the file specified by file_path should exists, so there is no need for error handling Please call open_grid to open the file @type text_grid: List[str] @rtype: None """ self.state = "STARTED" self.file_path = file_path self.text_grid = text_grid #set up self.path = PriorityQueue(Node.__lt__) #set up map using open_grid() function and then splitting it if it is a file path if self.text_grid == None: self.map = self.open_grid(self.file_path).read().split("\n") #set up map if it is a text grid else: self.map = self.text_grid #y length of the map self.height = len(self.map) #break up the map into a 2 dimensional list of strings for i in range(len(self.map)): self.map[i] = list(self.map[i]) #set width to be the horizontal length of the map self.width = len(self.map[0][:]) #find the treasure located in the map g = copy.copy(self.map) for i, x in enumerate(g): if "T" in x: self.treasure = Node(True, x.index("T"),i) #change x and y values self.map = [list(i) for i in zip(*self.map)] self.boat = self.set_boat() for i,x in enumerate(self.map): for j in range(len(x)): self.map[i][j] = Node(self.map[i][j] != "+",i,j)
def test_priority_queue_add_remove_doctest() -> None: """Test the doctest provided for PriorityQueue.add and PriorityQueue.remove""" pq = PriorityQueue(_shorter) pq.add('fred') pq.add('arju') pq.add('monalisa') pq.add('hat') assert pq.remove() == 'hat' assert pq.remove() == 'fred' assert pq.remove() == 'arju' assert pq.remove() == 'monalisa'
def _parcel_lst_generator(self) -> PriorityQueue: """ Generates a list of prioritized parcels depending on config.""" if (self._parcel_priority, self._parcel_order) == ('volume', 'non-decreasing'): return PriorityQueue(_volume_dec) if (self._parcel_priority, self._parcel_order) == ('volume', 'non-increasing'): return PriorityQueue(_volume_inc) if (self._parcel_priority, self._parcel_order) == ('destination', 'non-decreasing'): return PriorityQueue(_destination_dec) # ['destination', 'non-increasing'] return PriorityQueue(_destination_inc)
def dijkstra(road_network, s_vid, e_vid): """ Return the exact shortest path from vertex s_vid to vertex e_vid using Dijkstra's algorithm. :param road_network: RoadNetwork :param s_vid: int :param e_vid: int :return: Path """ frontier = PriorityQueue() frontier.put(s_vid, 0) came_from = dict() cost_so_far = dict() came_from[s_vid] = None cost_so_far[s_vid] = 0 while not frontier.empty(): current = frontier.get() if current == e_vid: break for neighbor in road_network.get_neighbors(current): new_cost = cost_so_far[current] + road_network.get_weight( current, neighbor) if neighbor not in cost_so_far or new_cost < cost_so_far[neighbor]: cost_so_far[neighbor] = new_cost # relax priority = new_cost frontier.put(neighbor, priority) came_from[neighbor] = current return construct_path(road_network, s_vid, e_vid, came_from)
def greedy_bfs(road_network, s_vid, e_vid): """ Return the shortest path from vertex s_vid to vertex e_vid using Greedy-Best-First-Search. In Greedy-BFS, the heuristic function is road_network.get_straight_distance(). :param road_network: RoadNetwork :param s_vid: int :param e_vid: int :return: Path """ frontier = PriorityQueue() frontier.put(s_vid, 0) came_from = dict() came_from[s_vid] = None while not frontier.empty(): current = frontier.get() if current == e_vid: break for neighbor in road_network.get_neighbors(current): if neighbor not in came_from: priority = road_network.get_straight_distance(neighbor, e_vid) frontier.put(neighbor, priority) came_from[neighbor] = current return construct_path(road_network, s_vid, e_vid, came_from)
def get_shortest_path(road_network, s_vid, e_vid): """ Return the shortest path from vertex s_vid to vertex e_vid using A* algorithm. If s_vid-->e_vid is unreachable, return None. :param road_network: RoadNetwork :param s_vid: int :param e_vid: int :return: Path """ frontier = PriorityQueue() frontier.put(s_vid, 0) came_from = dict() cost_so_far = dict() came_from[s_vid] = None cost_so_far[s_vid] = 0 while not frontier.empty(): current = frontier.get() # Take a look at the number of lines of code:) date: 2016/12/13 23:12 if current == e_vid: break for neighbor in road_network.get_neighbors(current): new_cost = cost_so_far[current] + road_network.get_weight( current, neighbor) if neighbor not in cost_so_far or new_cost < cost_so_far[neighbor]: cost_so_far[neighbor] = new_cost priority = new_cost + road_network.get_straight_distance( neighbor, e_vid) frontier.put(neighbor, priority) came_from[neighbor] = current return construct_path(road_network, s_vid, e_vid, came_from)
def single_source_dijkstra(road_network, start): """ Compute the shortest paths from a vertex, whose id is start, to all other vertices using Dijkstra's algorithm. :param road_network: RoadNetwork :param start: int :return: dict[int, int] the "came from" array """ import time start_time = time.clock() frontier = PriorityQueue() frontier.put(start, 0) came_from = dict() cost_so_far = dict() came_from[start] = None cost_so_far[start] = 0 while not frontier.empty(): current = frontier.get() for neighbor in road_network.get_neighbors(current): new_cost = cost_so_far[current] + road_network.get_weight( current, neighbor) if neighbor not in cost_so_far or new_cost < cost_so_far[neighbor]: cost_so_far[neighbor] = new_cost # relax priority = new_cost frontier.put(neighbor, priority) came_from[neighbor] = current print("Elapsed time is %f seconds." % (time.clock() - start_time)) return came_from
def _update_active_rides_fast(self, time: datetime) -> None: """Update this simulation's list of active rides for the given time. REQUIRED IMPLEMENTATION NOTES: - see Task 5 of the assignment handout """ event = PriorityQueue.remove()
def load_query(): """ Load taxi queries from file. :return: PriorityQueue[(int, Query)] :rtype: [dict[int, Query], PriorityQueue] """ from datetime import datetime import time print("Loading queries and create query queue (will take about 20 sec)...") start_time = time.clock() query_set = dict() query_queue = PriorityQueue() start_time_tuple = datetime.strptime('00:00:00', '%H:%M:%S') identifier = 0 i = 0 file_list = os.listdir("./data/queries") for file_name in file_list: i += 1 print("Loading the %d-th file..." % i) cur_file = open("./data/queries/" + file_name) for line in cur_file: [time_str, ori_lat, ori_lon, des_lat, des_lon] = line.split(',') time_tuple = datetime.strptime(time_str, '%H:%M:%S') timestamp = (time_tuple - start_time_tuple).seconds + 1 if timestamp < SIM_START_TIME or timestamp > SIM_END_TIME: continue ori_lat = float(ori_lat) ori_lon = float(ori_lon) des_lat = float(des_lat) des_lon = float(des_lon) origin = Location(ori_lat, ori_lon) destination = Location(des_lat, des_lon) query = Query(identifier, timestamp, origin, destination) query_set[identifier] = query query_queue.put(query, timestamp) identifier += 1 cur_file.close() print("Done. Elapsed time is %f seconds" % (time.clock() - start_time)) return [query_set, query_queue]
def __init__(self): """Initialize a Dispatcher. @type self: Dispatcher @rtype: None """ self.driver_list = [] self.rider_queue = PriorityQueue()
class GroceryStoreSimulation: """A Grocery Store simulation. This is the class which is responsible for setting up and running a simulation. """ def __init__(self, store_file): """Initialize a GroceryStoreSimulation from a file. @type store_file: str A file containing the configuration of the grocery store. @rtype: None """ self._events = PriorityQueue() self._store = GroceryStore(store_file) def run(self, event_file): """Run the simulation on the events stored in <event_file>. Return a dictionary containing statistics of the simulation, according to the specifications in the assignment handout. @type self: GroceryStoreSimulation @type event_file: str A filename referring to a raw list of events. Precondition: the event file is a valid list of events. @rtype: dict[str, object] """ # Initialize statistics stats = { 'num_customers': 0, 'total_time': 0, 'max_wait': -1 } initial_events = create_event_list(event_file) for item in initial_events: self._events.add(item) while self._events.is_empty() == False: processEvent= self._events.remove() #change the stats acrroding to the eventbeing popped out from list if(processEvent.status=="Finish"): waitTime=processEvent.getWaitTime() if waitTime > stats['max_wait']: stats['max_wait'] = waitTime if(processEvent.status=="Begin"): stats['num_customers']+=1 if(self._events.is_empty() and processEvent.status=="Finish"): stats['total_time']=processEvent.timestamp newEvents=processEvent.do(self._store) if(newEvents!=None): for event in newEvents: self._events.add(event) return stats
def search_path(self): frontier = PriorityQueue() frontier.put(self.start_node, 0) came_from = {} cost_so_far = {} visited_site = {} came_from[self.start_node] = None cost_so_far[self.start_node] = 0 self.real_end_node = None s_t = time.clock() while not frontier.empty(): if time.clock() - s_t > 60: print("search path time out.") return [] current = frontier.get() # type: Node cur_site = (current.xid, current.yid) if current.xid == self.target_xid and current.yid == self.target_yid: self.real_end_node = current break # inspect five (include itself) neighbors neighbors = self._get_neighbors(current) for nb in neighbors: new_cost = cost_so_far[current] + self._get_cost(current, nb) next_site = (nb.xid, nb.yid) if nb not in cost_so_far or new_cost < cost_so_far[nb]: if next_site == cur_site and next_site in visited_site: cost_so_far[nb] = new_cost + 2 else: cost_so_far[nb] = new_cost visited_site[next_site] = (nb.hour, nb.step) priority = cost_so_far[nb] + self.heuristic( nb, self.end_node) frontier.put(nb, priority) came_from[nb] = current if self.real_end_node is None: return [] path = [self.real_end_node] now = self.real_end_node while came_from[now] is not None: now = came_from[now] path.append(now) path.reverse() return path
def _generate_queue(_parcel_priority: str, _parcel_order: str, parcels: List[Parcel]) -> PriorityQueue: """Return a PriorityQueue that follows the given <_parcel_priority> and given <_parcel_order>. """ q = 'Nothing Assigned' if _parcel_priority == "volume": if _parcel_order == "non-decreasing": q = PriorityQueue(_volume_non_decreasing) elif _parcel_order == "non-increasing": q = PriorityQueue(_volume_non_increasing) elif _parcel_priority == "destination": if _parcel_order == "non-decreasing": q = PriorityQueue(_destination_non_decreasing) elif _parcel_order == "non-increasing": q = PriorityQueue(_destination_non_increasing) for parcel in parcels: q.add(parcel) return q
def test_priority_truck_non_decreasing_destination() -> None: """Test the doctest provided for PriorityQueue.add and PriorityQueue.remove""" t1 = Truck(1, 25, 'York') t2 = Truck(2, 10, 'York') t3 = Truck(3, 8, 'York') t4 = Truck(4, 20, 'York') t5 = Truck(5, 15, 'York') t6 = Truck(6, 15, 'York') t7 = Truck(7, 20, 'York') p1 = Parcel(1, 15, 'York', 'Toronto') trucks = [t1, t2, t3, t4, t5, t6, t7] et = _capable_trucks(p1, trucks) assert len(et) == 5 pq = PriorityQueue(_less_truck_space) for t in et: pq.add(trucks[t]) truck = pq.remove() assert truck.id == 5
def test_priority_queue_is_empty_doctest() -> None: """Test the doctest provided for PriorityQueue.is_empty""" pq = PriorityQueue(str.__lt__) assert pq.is_empty() is True pq.add('fred') assert pq.is_empty() is False
class Simulation: """A simulation. This is the class which is responsible for setting up and running a simulation. The API is given to you: your main task is to implement the two methods according to their docstrings. Of course, you may add whatever private attributes and methods you want. But because you should not change the interface, you may not add any public attributes or methods. This is the entry point into your program, and in particular is used for auto-testing purposes. This makes it ESSENTIAL that you do not change the interface in any way! """ # === Private Attributes === # @type _events: PriorityQueue[Event] # A sequence of events arranged in priority determined by the event # sorting order. # @type _dispatcher: Dispatcher # The dispatcher associated with the simulation. def __init__(self): """Initialize a Simulation. @type self: Simulation @rtype: None """ self._events = PriorityQueue() self._dispatcher = Dispatcher() self._monitor = Monitor() def run(self, initial_events): """Run the simulation on the list of events in <initial_events>. Return a dictionary containing statistics of the simulation, according to the specifications in the assignment handout. @type self: Simulation @type initial_events: list[Event] An initial list of events. @rtype: dict[str, object] """ # Add all initial events to the event queue. for item in initial_events: self._events.add(item) # Until there are no more events, remove an event # from the event queue and do it. Add any returned # events to the event queue. while not (self._events.is_empty()): temp_event = self._events.remove() event_list = temp_event.do(self._dispatcher, self._monitor) for event in event_list: self._events.add(event) return self._monitor.report()
class GroceryStoreSimulation: """A Grocery Store simulation. This is the class which is responsible for setting up and running a simulation. The interface is given to you: your main task is to implement the two methods according to their docstrings. Of course, you may add whatever private attributes you want to this class. Because you should not change the interface in any way, you may not add any public attributes. === Private Attributes === _events: A sequence of events arranged in priority determined by the event sorting order. _store: The store being simulated. """ _events: PriorityQueue _store: GroceryStore def __init__(self, store_file: TextIO) -> None: """Initialize a GroceryStoreSimulation using configuration <store_file>. """ self._events = PriorityQueue() self._store = GroceryStore(store_file) def run(self, file: TextIO) -> Dict[str, Any]: """Run the simulation on the events stored in <initial_events>. Return a dictionary containing statistics of the simulation, according to the specifications in the assignment handout. """ # Initialize statistics stats = { 'num_customers': 0, 'total_time': 0, 'max_wait': -1 } max_waits = dict() initial_event_list = create_event_list(file) for event in initial_event_list: self._events.add(event) if isinstance(event, CustomerArrival): stats['num_customers'] += 1 max_waits[event.customer] = event.timestamp while not self._events.is_empty(): event = self._events.remove() if isinstance(event, CheckoutCompleted): max_waits[event.customer] = event.timestamp - \ max_waits[event.customer] spawns = event.do(self._store) for spawn in spawns: self._events.add(spawn) stats['total_time'] = event.timestamp stats['max_wait'] = max_waits[max(max_waits, key=max_waits.get)] return stats
def __init__(self): """Initialize a Simulation. @type self: Simulation @rtype: None """ self._events = PriorityQueue() self._dispatcher = Dispatcher() self._monitor = Monitor() def run(self, initial_events): """Run the simulation on the list of events in <initial_events>. Return a dictionary containing statistics of the simulation, according to the specifications in the assignment handout. @type self: Simulation @type initial_events: list[Event] An initial list of events. @rtype: dict[str, object] """ # Add all initial events to the event queue. for event in initial_events: self._events.add(event) while self._events.is_empty() is False: executed_event = self._events.remove() result_events = executed_event.do(self._dispatcher, self._monitor) # this warning can be ignored if result_events is not None: for result_event in result_events: self._events.add(result_event) # Until there are no more events, remove an event # from the event queue and do it. Add any returned # events to the event queue. return self._monitor.report() if __name__ == "__main__": events = create_event_list("events.txt") sim = Simulation() final_stats = sim.run(events) print(final_stats)
class Simulation: """A simulation. This is the class that is responsible for setting up and running a simulation. The API is given to you: your main task is to implement the run method below according to its docstring. Of course, you may add whatever private attributes and methods you want. But because you should not change the interface, you may not add any public attributes or methods. This is the entry point into your program, and in particular is used for auto-testing purposes. This makes it ESSENTIAL that you do not change the interface in any way! """ # === Private Attributes === _events: PriorityQueue # A sequence of events arranged in priority determined by the event # sorting order. _dispatcher: Dispatcher # The dispatcher associated with the simulation. _monitor: Monitor # The monitor associated with the simulation. def __init__(self) -> None: """Initialize a Simulation. """ self._events = PriorityQueue() self._dispatcher = Dispatcher() self._monitor = Monitor() def run(self, initial_events: List[Event]) -> Dict[str, float]: """Run the simulation on the list of events in <initial_events>. Return a dictionary containing statistics of the simulation, according to the specifications in the assignment handout. initial_events: An initial list of events. """ # Add all initial events to the event queue. for event in initial_events: self._events.add(event) # Until there are no more events, remove an event # from the event queue and do it. Add any returned # events to the event queue. while not self._events.is_empty(): new = self._events.remove() future = new.do(self._dispatcher, self._monitor) for i in future: self._events.add(i) return self._monitor.report()
class Simulation: """A simulation. This is the class which is responsible for setting up and running a simulation. The API is given to you: your main task is to implement the run method below according to its docstring. Of course, you may add whatever private attributes and methods you want. But because you should not change the interface, you may not add any public attributes or methods. This is the entry point into your program, and in particular is used for auto-testing purposes. This makes it ESSENTIAL that you do not change the interface in any way! """ # === Private Attributes === # @type _events: PriorityQueue[Event] # A sequence of events arranged in priority determined by the event # sorting order. # @type _dispatcher: Dispatcher # The dispatcher associated with the simulation. def __init__(self): """Initialize a Simulation. @type self: Simulation @rtype: None """ self._events = PriorityQueue() self._dispatcher = Dispatcher() self._monitor = Monitor() def run(self, initial_events): """Run the simulation on the list of events in <initial_events>. Return a dictionary containing statistics of the simulation, according to the specifications in the assignment handout. @type self: Simulation @type initial_events: list[Event] An initial list of events. @rtype: dict[str, object] """ # TODO #Adding the events to the queue, UNSURE ABOUT THIS ???!?? for event in initial_events: self._events.add(event) while not self._events.is_empty(): currentEvent = self._events.remove() additionalEvents = currentEvent.do(self._dispatcher,self._monitor) if additionalEvents != []: for event in additionalEvents: self._events.add(event) # Add all initial events to the event queue. # Until there are no more events, remove an event # from the event queue and do it. Add any returned # events to the event queue. return self._monitor.report()
def run(self): print("The simulation system is running...") start_time = time.clock() waiting_queries = PriorityQueue() for timestamp in range(SIM_START_TIME, SIM_END_TIME + 1): print("Time: %d" % timestamp) # Catch the queries to be processed in this timestamp. The queries consists of two parts: # 1. queries that happened in this timestamp # 2. queries that stranded in previous timestamps while not self.query_queue.empty(): new_query = self.query_queue.get() if new_query.timestamp == timestamp: waiting_queries.put(new_query, new_query.timestamp) else: self.query_queue.put(new_query, new_query.timestamp) break while not self.dispatcher.failed_queries.empty(): old_query = self.dispatcher.failed_queries.get() waiting_queries.put(old_query, old_query.timestamp) # Process the queries. while not waiting_queries.empty(): query = waiting_queries.get() if query.status == CANCELLED: self.dispatcher.add_cancelled_query(query) else: self.dispatcher.dispatch_taxi(timestamp, query, self.db, self.taxi_set, self.road_network) # Update the status of all the queries for query in self.query_set.values(): if query.timestamp <= timestamp and query.status == WAITING: query.update_status(timestamp) # All the taxis drive according to their schedule. for taxi in self.taxi_set.values(): taxi.drive(timestamp, self.road_network, self.dispatcher, self.query_set, self.db) print("The simulation is end. Elapsed time is %f." % (time.clock() - start_time))
def test_priority_queue_non_increasing_destination() -> None: """Test the doctest provided for PriorityQueue.add and PriorityQueue.remove""" p1 = Parcel(1, 25, 'York', 'a') p2 = Parcel(2, 10, 'York', 'aa') p3 = Parcel(3, 8, 'York', 'aaa') p4 = Parcel(4, 20, 'York', 'a') p5 = Parcel(5, 15, 'York', 'aaaa') p6 = Parcel(6, 15, 'York', 'aa') p7 = Parcel(7, 20, 'York', 'aaaaaa') parcels = [p1, p2, p3, p4, p5, p6, p7] pq = PriorityQueue(_smaller_city) for parcel in parcels: pq.add(parcel) assert pq.remove().id == 7 assert pq.remove().id == 5 assert pq.remove().id == 3 assert pq.remove().id == 2 assert pq.remove().id == 6 assert pq.remove().id == 1 assert pq.remove().id == 4
def test_priority_queue_non_decreasing_volume() -> None: """Test the doctest provided for PriorityQueue.add and PriorityQueue.remove""" p1 = Parcel(1, 25, 'York', 'Toronto') p2 = Parcel(2, 10, 'York', 'London') p3 = Parcel(3, 8, 'York', 'London') p4 = Parcel(4, 20, 'York', 'Toronto') p5 = Parcel(5, 15, 'York', 'Toronto') p6 = Parcel(6, 15, 'York', 'Hamilton') p7 = Parcel(7, 20, 'York', 'London') parcels = [p1, p2, p3, p4, p5, p6, p7] pq = PriorityQueue(_smaller_volume) for parcel in parcels: pq.add(parcel) assert pq.remove().volume == 8 assert pq.remove().volume == 10 assert pq.remove().volume == 15 assert pq.remove().volume == 15 assert pq.remove().volume == 20 assert pq.remove().volume == 20 assert pq.remove().volume == 25
def search_path_greedy_best_first(self): frontier = PriorityQueue() frontier.put(self.start_node, 0) came_from = dict() came_from[self.start_node] = None self.real_end_node = None s_t = time.clock() while not frontier.empty(): if time.clock() - s_t > 60: print("search path time out.") return [] current = frontier.get() # type: Node if current.xid == self.target_xid and current.yid == self.target_yid: self.real_end_node = current break # inspect five (include itself) neighbors neighbors = self._get_neighbors(current) for nb in neighbors: if nb not in came_from: priority = self.heuristic(nb, self.end_node) frontier.put(nb, priority) came_from[nb] = current if self.real_end_node is None: return [] path = [self.real_end_node] now = self.real_end_node while came_from[now] is not None: now = came_from[now] path.append(now) path.reverse() return path
def schedule(self, parcels, trucks, verbose=False): """ Schedule parcels greedily <trucks> are mutated. Do not reuse <trucks> for another scheduler/trial. === Local Variables === type queue: PriorityQueue Queue of parcels. type unused_parcel: [Parcel] If the parcel does not fit any truck, the parcel is appended to <unused_parcel> type one_parcel: Parcel An element of <parcels> or <queue> type trucks_with_space: [Truck] List of trucks with space """ queue = PriorityQueue(self._greater_priority) unused_parcel = [] for one_parcel in parcels: queue.add(one_parcel) while queue.is_empty() is False: one_parcel = queue.remove() trucks_with_space = [] for one_truck in trucks: if one_truck.get_unused_space() >= one_parcel.get_volume(): trucks_with_space.append(one_truck) trucks_with_destination = [] for one_truck in trucks_with_space: if one_truck.city_in_route(one_parcel.get_destination()): trucks_with_destination.append(one_truck) # if there is at least 1 suitable truck with the destination, # trucks without the destination will not be considered. if len(trucks_with_destination) > 0: trucks_with_space = trucks_with_destination if len(trucks_with_space) > 0: self._choose_load_truck(trucks_with_space, one_parcel, verbose) else: if verbose: print("Parcel #{} was not loaded.".format( one_parcel.get_id())) unused_parcel.append(one_parcel) return unused_parcel
class TestPriorityQueue(unittest.TestCase): def setUp(self): self.queue = PriorityQueue(Helper.shorter) self.queue.add('fred') self.queue.add('arju') self.queue.add('monalisa') self.queue.add('hat') def test_pq_add(self): actual = self.queue._queue expected = ['monalisa', 'arju', 'fred', 'hat'] msg = "We expected {}, but found {}".format(str(expected), str(actual)) self.assertEqual(actual, expected, msg) def test_pq_remove(self): pq = self.queue._queue actual = self.queue.remove() expected = 'hat' msg = "Applied remove() to {}, expected {}, actual {}".format(pq, expected, actual) self.assertEqual(actual, expected, msg)
class GroceryStoreSimulation: """A Grocery Store simulation. This is the class which is responsible for setting up and running a simulation. The API is given to you: your main task is to implement the two methods according to their docstrings. Of course, you may add whatever private attributes and methods you want. But because you should not change the interface, you may not add any public attributes or methods. This is the entry point into your program, and in particular is used for auto testing purposes. This makes it ESSENTIAL that you do not change the interface in any way! """ # === Private Attributes === # @type _events: PriorityQueue[Event] # A sequence of events arranged in priority determined by the event # sorting order. # @type _store: GroceryStore # The grocery store associated with the simulation. def __init__(self, store_file): """Initialize a GroceryStoreSimulation from a file. @type store_file: str A file containing the configuration of the grocery store. @rtype: None """ self._events = PriorityQueue() self._store = GroceryStore(store_file) def run(self, event_file): """Run the simulation on the events stored in <event_file>. Return a dictionary containing statistics of the simulation, according to the specifications in the assignment handout. @type self: GroceryStoreSimulation @type event_file: str A filename referring to a raw list of events. Precondition: the event file is a valid list of events. @rtype: dict[str, int] """ # Initialize statistics stats = { 'num_customers': 0, 'total_time': 0, 'max_wait': -1 } initial_events = create_event_list(event_file) for i in range(len(initial_events)): self._events.add(initial_events[i]) if type(initial_events[i]) == JoinLine: stats['num_customers'] += 1 # THE FOLLOWING CODE MAY SHOW SOME WARNINGS. # (IF NOT, PLEASE IGNORE THIS COMMENT) # PROFESSOR LIU TOLD ME THAT THESE WARNINGS ARE PROBLEMS # WITH PyCharm ITSELF. SINCE WE ARE NOT ALLOWED TO CHANGE # THE INTERFACE, PROF SAID WE CAN JUST IGNORE THEM. THANK YOU. while not self._events.is_empty(): event = self._events.remove() spawned_events = event.do(self._store) stats['total_time'] = event.timestamp # Calculate max_wait if type(event) == FinishCheckOut: end_time = event.timestamp customer_name = event.name for u in range(len(initial_events)): if type(initial_events[u]) == JoinLine: temp = initial_events[u] if customer_name == temp.name: start_time = temp.timestamp waited_time = end_time - start_time if waited_time > stats['max_wait']: stats['max_wait'] = waited_time if spawned_events is not None: for j in range(len(spawned_events)): self._events.add(spawned_events[j]) return stats
class Dispatcher: """A dispatcher fulfills requests from riders and drivers for a ride-sharing service. When a rider requests a driver, the dispatcher assigns a driver to the rider. If no driver is available, the rider is placed on a waiting list for the next available driver. A rider that has not yet been picked up by a driver may cancel their request. When a driver requests a rider, the dispatcher assigns a rider from the waiting list to the driver. If there is no rider on the waiting list the dispatcher does nothing. Once a driver requests a rider, the driver is registered with the dispatcher, and will be used to fulfill future rider requests. """ def __init__(self): """Initialize a Dispatcher. @type self: Dispatcher @rtype: None """ self.driver_list = [] self.rider_queue = PriorityQueue() def __str__(self): """Return a string representation. @type self: Dispatcher @rtype: str """ print("Drivers: ",end="") print(self.driver_list) def request_driver(self, rider): """Return a driver for the rider, or None if no driver is available. Add the rider to the waiting list if there is no available driver. @type self: Dispatcher @type rider: Rider @rtype: Driver | None """ if len(self.driver_list) == 0: self.rider_queue.add(rider) return None else: shortest_time = self.driver_list[0] for name in self.driver_list: if name.get_travel_time(rider.destination) < shortest_time.get_travel_time(rider.destination): if name.is_idle: shortest_time = name return shortest_time def request_rider(self, driver): """Return a rider for the driver, or None if no rider is available. If this is a new driver, register the driver for future rider requests. @type self: Dispatcher @type driver: Driver @rtype: Rider | None """ if not self.rider_queue.is_empty(): return self.rider_queue.remove() else: self.driver_list.append(driver) return None def cancel_ride(self, rider): """Cancel the ride for rider. @type self: Dispatcher @type rider: Rider @rtype: None """ if self.rider_queue.__contains__(rider): self.rider_queue.delete(rider) rider.status = CANCELLED
class GroceryStoreSimulation: """A Grocery Store simulation. This is the class which is responsible for setting up and running a simulation. The API is given to you: your main task is to implement the two methods according to their docstrings. Of course, you may add whatever private attributes and methods you want. But because you should not change the interface, you may not add any public attributes or methods. This is the entry point into your program, and in particular is used for autotesting purposes. This makes it ESSENTIAL that you do not change the interface in any way! """ # === Private Attributes === # @type _events: PriorityQueue[Event] # A sequence of events arranged in priority determined by the event # sorting order. # @type _store: GroceryStore # The grocery store associated with the simulation. def __init__(self, store_file): """Initialize a GroceryStoreSimulation from a file. @type store_file: str A file containing the configuration of the grocery store. @rtype: None """ self._events = PriorityQueue() self._store = GroceryStore(store_file) def run(self, event_file): """Run the simulation on the events stored in <event_file>. Return a dictionary containing statistics of the simulation, according to the specifications in the assignment handout. @type self: GroceryStoreSimulation @type event_file: str A filename referring to a raw list of events. Precondition: the event file is a valid list of events. @rtype: dict[str, object] """ # Initialize statistics stats = { 'num_customers': 0, 'total_time': 0, 'max_wait': -1 } initial_events = create_event_list(event_file) # TODO: Process all of the events, collecting statistics along the way. for event in initial_events: self._events.add(event) while not self._events.is_empty(): current_event = self._events.remove() new_events = current_event.do(self._store) stats['total_time'] = current_event.timestamp # collects the total time if new_events is None: pass elif len(new_events) > 0: for x in new_events: self._events.add(x) # find out how many Customers have checked out # through store's finished_customers dict stats['num_customers'] = len(self._store.finished_customers) # find out max_wait from store's finished_customers for customer in self._store.finished_customers: if self._store.finished_customers[customer].get_wait_time() > \ stats['max_wait']: stats['max_wait'] = self._store.finished_customers[ customer].get_wait_time() return stats
class GroceryStoreSimulation: """A Grocery Store simulation. This is the class which is responsible for setting up and running a simulation. The interface is given to you: your main task is to implement the two methods according to their docstrings. Of course, you may add whatever private attributes you want to this class. Because you should not change the interface in any way, you may not add any public attributes. === Private Attributes === _events: A sequence of events arranged in priority determined by the event sorting order. _store: The store being simulated. """ _events: PriorityQueue _store: GroceryStore def __init__(self, store_file: TextIO) -> None: """Initialize a GroceryStoreSimulation using configuration <store_file>. """ self._events = PriorityQueue() self._store = GroceryStore(store_file) def run(self, file: TextIO) -> Dict[str, Any]: """Run the simulation on the events stored in <initial_events>. Return a dictionary containing statistics of the simulation, according to the specifications in the assignment handout. """ # This initializes statistics. stats = {'num_customers': 0, 'total_time': 0, 'max_wait': -1} # This fills self._events from file. event_list = create_event_list(file) while len(event_list) != 0: self._events.add(event_list.pop()) # This keeps track of customer start and end times. This is used to # calculate the maximum wait time. customers = {} while not self._events.is_empty(): event = self._events.remove() # This checks to see the event type. if isinstance(event, CustomerArrival): # This checks to see if the customer is in the customers # dictionary since the "max_wait" calculation is based on the # customer arriving at the wait area. if event.customer not in customers: customers[event.customer] = [event.timestamp, -1] stats['num_customers'] += 1 elif isinstance(event, CheckoutCompleted): customers[event.customer][1] = event.timestamp new_events = event.do(self._store) # This adds the new events. while not len(new_events) == 0: self._events.add(new_events.pop()) stats['total_time'] = event.timestamp # This calculates the maximum wait time. for key in customers: wait_time = customers[key][1] - customers[key][0] if wait_time > stats['max_wait']: stats['max_wait'] = wait_time return stats
def __init__(self, store_file: TextIO) -> None: """Initialize a GroceryStoreSimulation using configuration <store_file>. """ self._events = PriorityQueue() self._store = GroceryStore(store_file)
class GroceryStoreSimulation: """A Grocery Store simulation. This is the class which is responsible for setting up and running a simulation. The API is given to you: your main task is to implement the two methods according to their docstrings. Of course, you may add whatever private attributes and methods you want. But because you should not change the interface, you may not add any public attributes or methods. This is the entry point into your program, and in particular is used for autotesting purposes. This makes it ESSENTIAL that you do not change the interface in any way! """ # === Private Attributes === # @type _events: PriorityQueue[Event] # A sequence of events arranged in priority determined by the event # sorting order. # @type _store: GroceryStore # The grocery store associated with the simulation. def __init__(self, store_file): """Initialize a GroceryStoreSimulation from a file. @type store_file: str A file containing the configuration of the grocery store. @rtype: None """ self._events = PriorityQueue() self._store = GroceryStore(store_file) def run(self, event_file): """Run the simulation on the events stored in <event_file>. Return a dictionary containing statistics of the simulation, according to the specifications in the assignment handout. @type self: GroceryStoreSimulation @type event_file: str A filename referring to a raw list of events. Precondition: the event file is a valid list of events. @type initial_events: list[event] @rtype: dict[str, object] """ # Initialize statistics stats = { 'num_customers': 0, #check 'total_time': 0, 'max_wait': -1 } initial_events = create_event_list(event_file) #counted number of customers from file directly # TODO: Process all of the events, collecting statistics along the way. #first, add event from initial_events to pq then sort using sort method for index in range (len(initial_events)): self._events.add(initial_events[index]) #second, pass sorted events which is inside PQ to store while not self._events.is_empty(): #trigger the do function which checks if new events spawn in the store #new events are returned #setup simulation clock, advance clock to first event current_event = self._events.remove() #when there is only one event left, equate the time if self._events.is_empty(): stats['total_time'] = current_event.timestamp #the event is triggered returned_tuple = current_event.do(self._store) if returned_tuple[1] == 'int': stats['max_wait'] = returned_tuple[0] elif returned_tuple[1] == 'one event': self._events.add(returned_tuple[0]) elif returned_tuple[1] == 'event list': for item in returned_tuple[0]: self._events.add(item) return stats def handle_new_event(self, item): self._events.add(item)