def schedule(self, parcels: List[Parcel], trucks: List[Truck], verbose: bool = False) -> List[Parcel]: rejects = [] parcels2 = PriorityQueue(self._func) for p in parcels: parcels2.add(p) while not parcels2.is_empty(): parcel = parcels2.remove() truckos = _greedy_capable_trucks(parcel, trucks) if self._t_priority == 'non-increasing': ordereds = PriorityQueue(_more_truck_space) else: ordereds = PriorityQueue(_less_truck_space) for i in truckos: ordereds.add(trucks[i]) if ordereds.is_empty(): rejects.append(parcel) continue picked = ordereds.remove() for t in trucks: if picked.id == t.id: t.pack(parcel) return rejects
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 schedule(self, parcels: List[Parcel], trucks: List[Truck], verbose: bool = False) -> List[Parcel]: """Returns a list of parcels that were not allocated to a truck due to lack of volume available""" # defining left over parcels and priority list for parcels leftovers = [] parcel_lst = self._parcel_lst_generator() # adding parcels to priority list for parcel in parcels: parcel_lst.add(parcel) # assigning parcels to trucks while not parcel_lst.is_empty(): # removing parcels from the remaining parcels to be # allocated parcel = parcel_lst.remove() # defining truck priority list with two separate lists indicating # routes that match-up vs not if self._truck_order == "non-decreasing": truck_lst = PriorityQueue(_truck_vol_least) truck_lst_high = PriorityQueue(_truck_vol_least) else: # self._truck_order == "non-increasing": truck_lst = PriorityQueue(_truck_vol_most) truck_lst_high = PriorityQueue(_truck_vol_most) # making available truck lists for current parcel for truck in trucks: # check if parcel will fit current_vol = truck.unused_space() valid = current_vol >= parcel.volume # if parcel fits and the truck's last current stop is the # parcel's destination prioritize this truck over any others if truck.route[-1] == parcel.destination and valid: truck_lst_high.add(truck) # if parcel fits add this truck to list elif valid: truck_lst.add(truck) # if the high_prio list not is empty (i.e. there is a truck # with the last route as its destination) add the parcel # to the most prioritized truck if not truck_lst_high.is_empty(): truck_lst_high.remove().pack(parcel) # if not same route but eligibble trucks add it to # the most prioritzed truck elif not truck_lst.is_empty(): truck_lst.remove().pack(parcel) # otherwise append to leftover parcels else: leftovers.append(parcel) return leftovers
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
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 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 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 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 __init__(self) -> None: """Initialize a Simulation. """ self._events = PriorityQueue() self._dispatcher = Dispatcher() self._monitor = Monitor()
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 schedule(self, parcels, trucks, verbose=False): """Mutate the trucks so that they store information about which parcels they will deliver and what route they will take. The parcels will not be mutated. Return the parcels that do not get scheduled onto any truck, due to lack of capacity. @type self: Scheduler @type parcels: list[Parcel] The parcels to be scheduled for delivery. @type trucks: list[Truck] The trucks that can carry parcels for delivery. @type verbose: bool Whether or not to run in verbose mode. @rtype: list[Parcel] The parcels that did not get scheduled onto any truck, due to lack of capacity. """ parcel_queue = PriorityQueue(self._fun1) for each in parcels: parcel_queue.add(each) while not parcel_queue.is_empty(): target_parcel = parcel_queue.remove() parcel_data = target_parcel.get_parcel() truck_1st = [] truck_2nd = [] for each in trucks: if each.get_volume() >= parcel_data[-1]: truck_1st.append(each) for i in truck_1st: if parcel_data[-2] in i.get_destination(): truck_2nd.append(i) if not len(truck_2nd): truck_2nd = truck_1st truck_queue = PriorityQueue(self._fun2) for j in truck_2nd: truck_queue.add(j) if not truck_queue.is_empty(): truck_choice = truck_queue.remove() indx = trucks.index(truck_choice) trucks.remove(truck_choice) truck_choice.load_parcel(parcel_data[0], parcel_data[-2], parcel_data[-1]) parcels.remove(target_parcel) trucks.insert(indx, truck_choice) return parcels
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 _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_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 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 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
def schedule(self, parcels: List[Parcel], trucks: List[Truck], verbose: bool = False) -> List[Parcel]: rejects = [] parcels1 = PriorityQueue(_smaller_volume) parcels2 = PriorityQueue(_larger_volume) parcels3 = PriorityQueue(_smaller_city) parcels4 = PriorityQueue(_larger_city) for p in parcels: parcels1.add(p) parcels2.add(p) parcels3.add(p) parcels4.add(p) print("-----------------------") while not parcels1.is_empty(): p = parcels1.remove() print(p.id) print("-----------------------") while not parcels2.is_empty(): p = parcels2.remove() print(p.id) print("-----------------------") while not parcels3.is_empty(): p = parcels3.remove() print(p.id) print("-----------------------") while not parcels4.is_empty(): p = parcels4.remove() print(p.id) print("-----------------------") while not parcels2.is_empty(): parcel = parcels2.remove() truckos = _greedy_capable_trucks(parcel, trucks) if self._t_priority == 'non-increasing': ordereds = PriorityQueue(_more_truck_space) else: ordereds = PriorityQueue(_less_truck_space) for i in truckos: ordereds.add(trucks[i]) if ordereds.is_empty(): rejects.append(parcel) continue picked = ordereds.remove() for t in trucks: if picked.id == t.id: t.pack(parcel) pr return rejects
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 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_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_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 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 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 __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)
def __init__(self, store_file: TextIO) -> None: """Initialize a GroceryStoreSimulation using configuration <store_file>. """ self._events = PriorityQueue() self._store = GroceryStore(store_file)
def find_path(self, start_node, target_node): """ Implement the A-star path search algorithm If you will add a new node to the path, don't forget to set the parent. You can find an example in the docstring of Node class Please note the shortest path between two nodes may not be unique. However all of them have same length! @type self: Grid @type start_node: Node The starting node of the path @type target_node: Node The target node of the path @rtype: None """ #create a copy of the original map g = copy.copy(self.map) #make an open PriorityQueue to store children opens = PriorityQueue(Node.__lt__) #set the starting node's g and h costs to be 0 or else it starts around infinity start_node.gcost = 0 start_node.hcost = 0 #add the starting node to the open Queue opens.add(start_node) #loop while the open set is not empty while not opens.is_empty(): #remove the value with the lowest fcost built into the PriorityQueue class q = opens.remove() #create a list of successors suc = [] #add each new successor node in the 8 surrounding points to the list if the index is in range and the point is navigable if q.grid_y-1 >= 0 and q.grid_y - 1 < self.height and q.grid_x-1 >= 0 and q.grid_x - 1 < self.width and g[q.grid_x-1][q.grid_y-1].navigable == True: suc.append(Node(g[q.grid_x-1][q.grid_y-1].navigable,q.grid_x-1,q.grid_y-1)) if q.grid_y-1 >= 0 and q.grid_y - 1 < self.height and q.grid_x >= 0 and q.grid_x < self.width and g[q.grid_x][q.grid_y-1].navigable == True: suc.append(Node(g[q.grid_x][q.grid_y-1].navigable,q.grid_x,q.grid_y-1)) if q.grid_y-1 >= 0 and q.grid_y - 1 < self.height and q.grid_x + 1 >= 0 and q.grid_x + 1 < self.width and g[q.grid_x+1][q.grid_y-1].navigable == True: suc.append(Node(g[q.grid_x+1][q.grid_y-1].navigable,q.grid_x+1,q.grid_y-1)) if q.grid_y >= 0 and q.grid_y < self.height and q.grid_x-1 >= 0 and q.grid_x - 1 < self.width and g[q.grid_x-1][q.grid_y].navigable == True: suc.append(Node(g[q.grid_x-1][q.grid_y].navigable,q.grid_x-1,q.grid_y)) if q.grid_y >= 0 and q.grid_y < self.height and q.grid_x+1 >= 0 and q.grid_x + 1 < self.width and g[q.grid_x+1][q.grid_y].navigable == True: suc.append(Node(g[q.grid_x+1][q.grid_y].navigable,q.grid_x+1,q.grid_y)) if q.grid_y+1 >= 0 and q.grid_y + 1 < self.height and q.grid_x-1 >= 0 and q.grid_x - 1 < self.width and g[q.grid_x-1][q.grid_y+1].navigable == True: suc.append(Node(g[q.grid_x-1][q.grid_y+1].navigable,q.grid_x-1,q.grid_y+1)) if q.grid_y+1 >= 0 and q.grid_y + 1 < self.height and q.grid_x >= 0 and q.grid_x < self.width and g[q.grid_x][q.grid_y+1].navigable == True: suc.append(Node(g[q.grid_x][q.grid_y+1].navigable,q.grid_x,q.grid_y+1)) if q.grid_y+1 >= 0 and q.grid_y + 1 < self.height and q.grid_x+1 >= 0 and q.grid_x + 1 < self.width and g[q.grid_x+1][q.grid_y+1].navigable == True: suc.append(Node(g[q.grid_x+1][q.grid_y+1].navigable,q.grid_x+1,q.grid_y+1)) #for each successor for i in range(len(suc)): #set the parent to be the one that was just removed suc[i].set_parent(q) #stop the search if the target node is found if suc[i] == target_node: #also add the successor to the closed set self.path.add(suc[i]) return None #set the target's g, h, and f costs suc[i].set_gcost(q.gcost + q.distance(suc[i])) suc[i].set_hcost(target_node.distance(suc[i])) suc[i].fcost() #if the successor is in the open set and is lower f than the value in the successor then skip the successsor if opens.is_less_than(suc[i]): pass #if the successor is in the closed set and is lower f than the value in the successor then skip the successsor if self.path.is_less_than(suc[i]): pass #otherwise add the successor to the open set else: opens.add(suc[i]) #add the q value to the closed set self.path.add(q)
def find_path(self, start_node, target_node): """ Implement the A-star path search algorithm If you will add a new node to the path, don't forget to set the parent. You can find an example in the docstring of Node class Please note the shortest path between two nodes may not be unique. However all of them have same length! @type self: Grid @type start_node: Node The starting node of the path @type target_node: Node The target node of the path @rtype: None >>> g = Grid("", ["B.++", ".+..", "...T"]) >>> g.find_path(g.boat, g.treasure) >>> n = g.treasure >>> print(n.grid_x, n.grid_y, ... n.gcost, n.hcost, n.fcost(), ... n.parent.grid_x, n.parent.grid_y) 3 2 38 0 38 2 1 >>> n = g.treasure.parent >>> print(n.grid_x, n.grid_y, ... n.gcost, n.hcost, n.fcost(), ... n.parent.grid_x, n.parent.grid_y) 2 1 24 14 38 1 0 >>> n = g.map[1][0] >>> print(n.grid_x, n.grid_y, ... n.gcost, n.hcost, n.fcost(), ... n.parent.grid_x, n.parent.grid_y) 1 0 10 28 38 0 0 >>> n = g.map[0][1].parent >>> n == g.boat True """ # TODO def less_than(x_node, y_node): """ Compare the priority of x over y @type x_node: Node @type y_node: Node @rtype: bool True if x has higher priority over y otherwise False """ return x_node < y_node # create an empty list as open set open_set = [] # loop the row on the map for row in self.map: # extend the row in the list open_set.extend(row) # remove the start node from the list open_set.remove(start_node) # define a closed set as the priority queue in less_than closed_set = PriorityQueue(less_than) # add the start node to the list of closed set closed_set.add(start_node) # set the gcost for start node start_node.set_gcost(0) # loop the closed set if it is not empty while not closed_set.is_empty(): # get the current node from the closed set curr_node = closed_set.remove() # if the current node is the target node if curr_node is target_node: # done break # loop the next node in the neighours for current node for next_node in self.get_neighours(curr_node): # if the next node is in the open set if next_node in open_set: # remove the next node open_set.remove(next_node) # add it to the closed set closed_set.add(next_node) # set the gcost for the next node next_node.set_gcost(curr_node.gcost + curr_node.distance(next_node)) # set the hcost for the next_node next_node.set_hcost(next_node.distance(target_node)) # set the parent for the next node next_node.set_parent(curr_node)
rounds = 20 total_cost_df_online, total_cost_alg_online = 0.0, 0.0 total_num_df_online, total_num_alg_online = 0.0, 0.0 total_cost_df_offline, total_cost_alg_offline, total_cost_opt = 0.0, 0.0, 0.0 total_num_df_offline, total_num_alg_offline, total_num_opt = 0.0, 0.0, 0.0 for round_id in range(0, rounds): # Generate the input [job_set, pm_set, ele_price] = load_data(num_jobs, num_slots) # real-trace input # Put all the jobs into a priority queue with start time of the job as the priority pq = PriorityQueue() for i in job_set: job = job_set[i] pq.put(job, job.start_time) # Init the online algorithms num_pms = len(job_set) online_alg = OnlineSolver(num_pms, num_slots, ele_price) online_df = OnlineDemandFirst(num_pms, num_slots, ele_price) opt_lb = ILPSolver(job_set, pm_set, ele_price) # Init the offline algorithms and run solver = OfflineSolver() solver.solve_offline_demand_first(copy.deepcopy(job_set), pm_set, ele_price) cost_df_offline = solver.evaluate(pm_set, ele_price)