コード例 #1
0
 def __init__(self, event_file):
     """
     This function initialises the simulator.
     :param event_file: the file containing the "events" received by flight control
     """
     self._queue = AdaptableHeapPriorityQueue()
     self._locator = {}
     self._event_file = event_file
コード例 #2
0
def MST_PrimJarnik(g):
    """Compute a minimum spanning tree of weighted graph g.

    Return a list of edges that comprise the MST (in arbitrary order).
    """
    d = {}                                                      # d[v] is bound on distance to tree
    tree = []                                                   # list of edges in spanning tree
    pq = AdaptableHeapPriorityQueue()      # d[v] maps to value (v, e=(u,v))
    pqlocator = {}                                         # map from vertex to its pq locator

    # for each vertex v of the graph, add an entry to the priority queue, with
    # the source having distance 0 and all others having infinite distance
    for v in g.vertices():
        if len(d) == 0:                                                      # this is the first node
            d[v] = 0                                                            # make it the root
        else:
            d[v] = float('inf')                                               # positive infinity
        pqlocator[v] = pq.add(d[v], (v, None))

    while not pq.is_empty():
        key, value = pq.remove_min()
        u, edge = value                                                      # unpack tuple from pq
        del pqlocator[u]                                                     # u is no longer in pq
        if edge is not None:
            tree.append(edge)                                              # add edge to tree
        for link in g.incident_edges(u):
            v = link.opposite(u)
            if v in pqlocator:                                                 # thus v not yet in tree
                # see if edge (u, v) better connects v to the growing tree
                wgt = link.element()
                if wgt < d[v]:                                                  # better edge to v?
                    d[v] = wgt                                                   # update the distance
                    pq.update(pqlocator[v], d[v], (v, link))       # update the pq entry
    return tree
コード例 #3
0
def shortest_path_lengths(g, src):
  """Compute shortest-path distances from src to reachable vertices of g.
  Graph g can be undirected or directed, but must be weighted such that
  e.element() returns a numeric weight for each edge e.
  Return dictionary mapping each reachable vertex to its distance from src.
  """
  d = {}                                        # d[v] is upper bound from s to v
  cloud = {}                                    # map reachable v to its d[v] value
  pq = AdaptableHeapPriorityQueue()             # vertex v will have key d[v]
  pqlocator = {}                                # map from vertex to its pq locator

  # for each vertex v of the graph, add an entry to the priority queue, with
  # the source having distance 0 and all others having infinite distance
  for v in g.vertices():
    if v is src:
      d[v] = 0
    else:
      d[v] = float('inf')                       # syntax for positive infinity
    pqlocator[v] = pq.add(d[v], v)              # save locator for future updates

  while not pq.is_empty():
    key, u = pq.remove_min()
    cloud[u] = key                              # its correct d[u] value
    print(pqlocator[u])                                                                   # print distance from origin point and current point
    del pqlocator[u]                            # u is no longer in pq
    for e in g.incident_edges(u):               # outgoing edges (u,v)
      v = e.opposite(u)
      if v not in cloud:
        # perform relaxation step on edge (u,v)
        wgt = e.element()
        if d[u] + wgt < d[v]:                   # better path to v?
          d[v] = d[u] + wgt                     # update the distance
          pq.update(pqlocator[v], d[v], v)      # update the pq entry

  return cloud                                  # only includes reachable vertices
コード例 #4
0
def dijkstra(g, s):
    q = AdaptableHeapPriorityQueue()
    dist = {}
    locators = {}
    for v in g.vertices():
        if v == s:
            v.dist = 0
        else:
            v.dist = infinity
        l = q.add(v.dist, v)
        v.locator = l

    while q.__len__() > 0:
        (key, u) = q.remove_min()
        print("***", key, u)
        for e in g.incident_edges(u):
            w = g.opposite(u, e)

            print(u.__dict__)

            if w.dist > u.dist + e.element():
                w.dist = u.dist + e.element()
                q.update(w.locator, w.dist, w)
コード例 #5
0
def shortest_path_lengths(g, src):
    """Compute shortest-path distances from src to reachable vertices of g.

    Graph g can be undirected or directed, but must be weighted such that
    e.element() returns a numeric weight for each edge e.

    Return dictionary mapping each reachable vertex to its distance from src.
    """
    d = {
    }                                        # d[v] is upper bound from s to v
    # map reachable v to its d[v] value
    cloud = {}
    pq = AdaptableHeapPriorityQueue()             # vertex v will have key d[v]
    pqlocator = {}                                # map from vertex to its pq locator

    # for each vertex v of the graph, add an entry to the priority queue, with
    # the source having distance 0 and all others having infinite distance
    for v in g.vertices():
        if v is src:
            d[v] = 0
        else:
            # syntax for positive infinity
            d[v] = float('inf')
        # save locator for future updates
        pqlocator[v] = pq.add(d[v], v)

    while not pq.is_empty():
        key, u = pq.remove_min()
        cloud[u] = key                              # its correct d[u] value
        del pqlocator[u]                            # u is no longer in pq
        for e in g.incident_edges(u):               # outgoing edges (u,v)
            v = e.opposite(u)
            if v not in cloud:
                # perform relaxation step on edge (u,v)
                wgt = e.element()
                if d[u] + wgt < d[v]:                   # better path to v?
                    d[v] = d[u] + wgt                     # update the distance
                    pq.update(pqlocator[v], d[v], v)      # update the pq entry

    return cloud                                  # only includes reachable vertices
コード例 #6
0
"""
This is a simple example that demonstrates how to use the heap-based priority queue
"""

from adaptable_heap_priority_queue import AdaptableHeapPriorityQueue

if __name__ == '__main__':
    """ Note: it is a min-heap: highest priority means lowest priority key"""

    AH = AdaptableHeapPriorityQueue()  # create new queue

    loc1 = AH.add(3, "event 1")  # add some events in the queue
    loc2 = AH.add(1, "event 2")
    loc3 = AH.add(5, "event 3")
    loc4 = AH.add(4, "event 4")

    print("This is the current highest priority event: {0}".format(
        AH.min()))  # only check, does not return the value
    print(AH.__len__())  # check length of queue
    print("Dequeue next event: {0}".format(
        AH.remove_min()))  # removes and returns the highest priority event
    print(AH.__len__())  # check length of queue
    print("This is the current highest priority event: {0}".format(
        AH.min()))  # only check, does not return the value
    AH.update(loc3, 0, "event 3")  # updates the priority of one event
    print("This is the current highest priority event: {0}".format(
        AH.min()))  # only check, does not return the value
    print("Dequeue next event: {0}".format(AH.remove_min()))
    print("Dequeue next event: {0}".format(AH.remove_min()))
    print("Dequeue next event: {0}".format(AH.remove_min()))
    print(AH.__len__())  # check length of queue
コード例 #7
0
class FlightLandingControl():
    def __init__(self, event_file):
        """
        This function initialises the simulator.
        :param event_file: the file containing the "events" received by flight control
        """
        self._queue = AdaptableHeapPriorityQueue()
        self._locator = {}
        self._event_file = event_file

    def _add_flight(self, priority, flight_no):
        """
        This function adds a flight to the queue.
        :param priority: the priority level of the flight
        :param flight_no: the flight
        :return:
        """
        loc = self._queue.add(priority, flight_no)
        self._locator[flight_no] = [loc, priority]

    def _update(self, new_priority, flight_no):
        """
        This function updates the level of priority of a flight in the queue
        :param new_priority: the new level of priority
        :param flight_no: the flight
        """
        loc = self._locator[flight_no]
        self._queue.update(loc[0], new_priority, flight_no)

    def _land(self):
        """
        This function simulates the landing of a flight by printing a message e.g.:
        "Flight AZ1100 landed!"
        """
        print("Flight {0} landed!".format(self._queue.remove_min()))

    def _process_event(self, line):
        """
        This function should process one event contained in one "line" of the events file.
        :param line: a string representing the event, e.g. KK8989,sick passenger; flight,land; AZ1012,national etc.
        """
        values = list(line.split(','))
        flight_no = values[0]
        event = values[1]

        if event == "short":
            self._add_flight(2, flight_no)
        elif event == "long":
            self._add_flight(4, flight_no)
        elif event == "national":
            self._add_flight(6, flight_no)
        elif event == "land":
            self._land()
        elif event == "sick passenger":
            self._update(1, flight_no)
        elif event == "fuel low":
            self._update(1, flight_no)
        elif len(values) == 3:
            if values[2] == 'start':
                for loc in self._locator:
                    if loc[0] == 'A' and loc[1] == 'Z':
                        dat = self._locator[loc]
                        self._queue.update(dat[0], dat[1] - 2, flight_no)
            if values[2] == 'stop':
                for loc in self._locator:
                    if loc[0] == 'A' and loc[1] == 'Z':
                        dat = self._locator[loc]
                        self._queue.update(dat[0], dat[1] + 2, flight_no)

    def process_event_file(self):
        # open event file for reading
        file = open(self._event_file, "r")
        # each line is a new event
        for line in file.readlines():
            print(
                "******************** Processing new event: {0}".format(line))
            self._process_event(line)
            time.sleep(0.5)
コード例 #8
0
class Scheduler:
    '''This class is a batch job scheduler that implements heap priority queue.''' 
    def __init__(self):
        self.__jobHeap = AdaptableHeapPriorityQueue()
    
    def load_jobs(self, filename):
        '''Loads jobs from input file.'''
        with open(filename, 'r') as file:
            for line in file:
                if not line.startswith('JOB,PRIORITY,LENGTH'):
                    data = line.rstrip().split(',')
                    job = Job(data[0], int(data[1]), int(data[2]))
                    self.__jobHeap.add((job.get_priority(), job.get_length()), job)
        file.close()
        
    def run(self):
        try:
            # Print current status
            current_key, current_job = self.__jobHeap.min()
            current_job.prnt_job()
            # Update
            if current_job.get_length() > 1:
                new_length = current_job.get_length() - 1
                current_job.set_length(new_length)
            else:
                self.__jobHeap.remove_min()
            return True
        except Empty:
            return False
    
    def halt(self):
        print("\nScheduler has been halted:")
        # Update the min with the remaining length
        current_key, current_job = self.__jobHeap.remove_min()
        self.__jobHeap.add((current_key[0], current_job.get_length()), current_job)
        
        # tmpHeap stores the job that is removed from the jobHeap
        tmpHeap = AdaptableHeapPriorityQueue()
        # nameDict is a dictionary that stores job names as keys and locators as values
        nameDict = {}
        # listJobs is a python list used to sort jobs
        listJobs = []        
        # prompt the user for how the table should be sorted
        srt = input("Sort by (j/p/l/h): ")
        print(self)
        try:
            while True:
                # Remove from jobHeap and print the job data if heap order is selected
                tmpKey, tmpJob = self.__jobHeap.remove_min()
                name = tmpJob.get_name()
                priority = tmpJob.get_priority()
                length = tmpJob.get_length()
                if(srt == 'h'):
                    print(tmpJob)
                # Add the job from the jobHeap to the tmpHeap
                nameDict[name] = tmpHeap.add(tmpKey, tmpJob)
                # Add the job to the listJobs
                listJobs.append((name, priority, length))
        except Empty:
            pass
        
        # Print the jobs based on the user input if other than heap order
        if srt == 'j':
            for j in sorted(listJobs, key=lambda jobs: jobs[0]):
                output = '{0:<20} '.format(j[0])
                output += '{0:>10} '.format(j[1])
                output += '{0:>10} '.format(j[2])
                print(output)
        elif srt == 'p':
            for j in sorted(listJobs, key=lambda jobs: jobs[1]):
                output = '{0:<20} '.format(j[0])
                output += '{0:>10} '.format(j[1])
                output += '{0:>10} '.format(j[2])
                print(output)
        elif srt == 'l':
            for j in sorted(listJobs, key=lambda jobs: jobs[2]):
                output = '{0:<20} '.format(j[0])
                output += '{0:>10} '.format(j[1])
                output += '{0:>10} '.format(j[2])
                print(output)
        
        # Add new job
        newJob = input("New job? (y/n): ")
        if newJob == 'y':
            name = input("New job name: ")
            priority = int(input("New job priority: "))
            length = int(input("New job length: "))
            newJob = Job(name, priority, length)
            tmpHeap.add((priority, length), newJob)
        # Alter a job
        alter = input("Alter priority? (y/n): ")
        if alter == 'y':
            name = input("Job name: ")
            priority = int(input("New priority: "))
            tmpKey, tmpJob = tmpHeap.remove(nameDict[name])
            tmpJob.set_priority(priority)
            tmpHeap.add((priority, tmpKey[1]), tmpJob)
        # Restart the scheduler
        print("Restarting scheduler...")
        self.__jobHeap = tmpHeap
            
    def __repr__(self):
        output = '{0:<20}  {1:>10}  {2:>10}'.format('Name', 'Priority', 'Length')
        output += '\n' + '-'*45 + '\n'
        return output
コード例 #9
0
 def halt(self):
     print("\nScheduler has been halted:")
     # Update the min with the remaining length
     current_key, current_job = self.__jobHeap.remove_min()
     self.__jobHeap.add((current_key[0], current_job.get_length()), current_job)
     
     # tmpHeap stores the job that is removed from the jobHeap
     tmpHeap = AdaptableHeapPriorityQueue()
     # nameDict is a dictionary that stores job names as keys and locators as values
     nameDict = {}
     # listJobs is a python list used to sort jobs
     listJobs = []        
     # prompt the user for how the table should be sorted
     srt = input("Sort by (j/p/l/h): ")
     print(self)
     try:
         while True:
             # Remove from jobHeap and print the job data if heap order is selected
             tmpKey, tmpJob = self.__jobHeap.remove_min()
             name = tmpJob.get_name()
             priority = tmpJob.get_priority()
             length = tmpJob.get_length()
             if(srt == 'h'):
                 print(tmpJob)
             # Add the job from the jobHeap to the tmpHeap
             nameDict[name] = tmpHeap.add(tmpKey, tmpJob)
             # Add the job to the listJobs
             listJobs.append((name, priority, length))
     except Empty:
         pass
     
     # Print the jobs based on the user input if other than heap order
     if srt == 'j':
         for j in sorted(listJobs, key=lambda jobs: jobs[0]):
             output = '{0:<20} '.format(j[0])
             output += '{0:>10} '.format(j[1])
             output += '{0:>10} '.format(j[2])
             print(output)
     elif srt == 'p':
         for j in sorted(listJobs, key=lambda jobs: jobs[1]):
             output = '{0:<20} '.format(j[0])
             output += '{0:>10} '.format(j[1])
             output += '{0:>10} '.format(j[2])
             print(output)
     elif srt == 'l':
         for j in sorted(listJobs, key=lambda jobs: jobs[2]):
             output = '{0:<20} '.format(j[0])
             output += '{0:>10} '.format(j[1])
             output += '{0:>10} '.format(j[2])
             print(output)
     
     # Add new job
     newJob = input("New job? (y/n): ")
     if newJob == 'y':
         name = input("New job name: ")
         priority = int(input("New job priority: "))
         length = int(input("New job length: "))
         newJob = Job(name, priority, length)
         tmpHeap.add((priority, length), newJob)
     # Alter a job
     alter = input("Alter priority? (y/n): ")
     if alter == 'y':
         name = input("Job name: ")
         priority = int(input("New priority: "))
         tmpKey, tmpJob = tmpHeap.remove(nameDict[name])
         tmpJob.set_priority(priority)
         tmpHeap.add((priority, tmpKey[1]), tmpJob)
     # Restart the scheduler
     print("Restarting scheduler...")
     self.__jobHeap = tmpHeap
コード例 #10
0
 def __init__(self):
     self.__jobHeap = AdaptableHeapPriorityQueue()