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
Beispiel #2
0
 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)
Beispiel #3
0
 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
Beispiel #4
0
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
Beispiel #5
0
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
Beispiel #6
0
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)
Beispiel #7
0
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)
Beispiel #8
0
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)
Beispiel #9
0
    def __init__(self) -> None:
        """Initialize a Simulation.

        """
        self._events = PriorityQueue()
        self._dispatcher = Dispatcher()
        self._monitor = Monitor()
Beispiel #10
0
 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()
Beispiel #13
0
    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)
Beispiel #15
0
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
Beispiel #16
0
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'
Beispiel #17
0
    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
Beispiel #18
0
    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
Beispiel #19
0
    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
Beispiel #20
0
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]
Beispiel #21
0
    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))
Beispiel #22
0
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
Beispiel #23
0
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
Beispiel #24
0
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
Beispiel #25
0
    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)