queue.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. import collections
  2. import heapq
  3. import itertools
  4. class QueueFIFO:
  5. """
  6. Class: QueueFIFO
  7. Description: QueueFIFO is designed for First-in-First-out rule.
  8. """
  9. def __init__(self):
  10. self.queue = collections.deque()
  11. def empty(self):
  12. return len(self.queue) == 0
  13. def put(self, node):
  14. self.queue.append(node) # enter from back
  15. def get(self):
  16. return self.queue.popleft() # leave from front
  17. class QueueLIFO:
  18. """
  19. Class: QueueLIFO
  20. Description: QueueLIFO is designed for Last-in-First-out rule.
  21. """
  22. def __init__(self):
  23. self.queue = collections.deque()
  24. def empty(self):
  25. return len(self.queue) == 0
  26. def put(self, node):
  27. self.queue.append(node) # enter from back
  28. def get(self):
  29. return self.queue.pop() # leave from back
  30. class QueuePrior:
  31. """
  32. Class: QueuePrior
  33. Description: QueuePrior reorders elements using value [priority]
  34. """
  35. def __init__(self):
  36. self.queue = []
  37. def empty(self):
  38. return len(self.queue) == 0
  39. def put(self, item, priority):
  40. heapq.heappush(self.queue, (priority, item)) # reorder x using priority
  41. def get(self):
  42. return heapq.heappop(self.queue)[1] # pop out the smallest item
  43. def enumerate(self):
  44. return self.queue
  45. def check_remove(self, item):
  46. for (p, x) in self.queue:
  47. if item == x:
  48. self.queue.remove((p, x))
  49. def top_key(self):
  50. return self.queue[0][0]
  51. class MinheapPQ:
  52. """
  53. A priority queue based on min heap, which takes O(logn) on element removal
  54. https://docs.python.org/3/library/heapq.html#priority-queue-implementation-notes
  55. """
  56. def __init__(self):
  57. self.pq = [] # lis of the entries arranged in a heap
  58. self.entry_finder = {} # mapping of the item entries
  59. self.counter = itertools.count() # unique sequence count
  60. self.REMOVED = '<removed-item>'
  61. def put(self, item, priority):
  62. '''add a new task or update the priority of an existing item'''
  63. if item in self.entry_finder:
  64. self.check_remove(item)
  65. count = next(self.counter)
  66. entry = [priority, count, item]
  67. self.entry_finder[item] = entry
  68. heapq.heappush(self.pq, entry)
  69. def check_remove(self, item):
  70. if item not in self.entry_finder:
  71. return
  72. entry = self.entry_finder.pop(item)
  73. entry[-1] = self.REMOVED
  74. def get(self):
  75. """Remove and return the lowest priority task. Raise KeyError if empty."""
  76. while self.pq:
  77. priority, count, item = heapq.heappop(self.pq)
  78. if item is not self.REMOVED:
  79. del self.entry_finder[item]
  80. return item
  81. raise KeyError('pop from an empty priority queue')
  82. def top_key(self):
  83. return self.pq[0][0]
  84. def enumerate(self):
  85. return self.pq
  86. # class QueuePrior:
  87. # """
  88. # Class: QueuePrior
  89. # Description: QueuePrior reorders elements using value [priority]
  90. # """
  91. # def __init__(self):
  92. # self.queue = []
  93. # def empty(self):
  94. # return len(self.queue) == 0
  95. # def put(self, item, priority):
  96. # count = 0
  97. # for (p, x) in self.queue:
  98. # if x == item:
  99. # self.queue[count] = (priority, item)
  100. # break
  101. # count += 1
  102. # if count == len(self.queue):
  103. # heapq.heappush(self.queue, (priority, item)) # reorder x using priority
  104. # def get(self):
  105. # return heapq.heappop(self.queue)[1] # pop out the smallest item
  106. # def enumerate(self):
  107. # return self.queue
  108. # def check_remove(self, item):
  109. # for (p, x) in self.queue:
  110. # if item == x:
  111. # self.queue.remove((p, x))
  112. # def top_key(self):
  113. # return self.queue[0][0]