queue.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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 s 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.nodes = set()
  59. self.entry_finder = {} # mapping of the item entries
  60. self.counter = itertools.count() # unique sequence count
  61. self.REMOVED = '<removed-item>'
  62. def put(self, item, priority):
  63. '''add a new task or update the priority of an existing item'''
  64. if item in self.entry_finder:
  65. self.check_remove(item)
  66. count = next(self.counter)
  67. entry = [priority, count, item]
  68. self.entry_finder[item] = entry
  69. heapq.heappush(self.pq, entry)
  70. self.nodes.add(item)
  71. def check_remove(self, item):
  72. if item not in self.entry_finder:
  73. return
  74. entry = self.entry_finder.pop(item)
  75. entry[-1] = self.REMOVED
  76. self.nodes.remove(item)
  77. def get(self):
  78. """Remove and return the lowest priority task. Raise KeyError if empty."""
  79. while self.pq:
  80. priority, count, item = heapq.heappop(self.pq)
  81. if item is not self.REMOVED:
  82. del self.entry_finder[item]
  83. self.nodes.remove(item)
  84. return item
  85. raise KeyError('pop from an empty priority queue')
  86. def top_key(self):
  87. return self.pq[0][0]
  88. def enumerate(self):
  89. return self.pq
  90. def allnodes(self):
  91. return self.nodes
  92. # class QueuePrior:
  93. # """
  94. # Class: QueuePrior
  95. # Description: QueuePrior reorders elements using value [priority]
  96. # """
  97. # def __init__(self):
  98. # self.queue = []
  99. # def empty(self):
  100. # return len(self.queue) == 0
  101. # def put(self, item, priority):
  102. # count = 0
  103. # for (p, s) in self.queue:
  104. # if s == item:
  105. # self.queue[count] = (priority, item)
  106. # break
  107. # count += 1
  108. # if count == len(self.queue):
  109. # heapq.heappush(self.queue, (priority, item)) # reorder s using priority
  110. # def get(self):
  111. # return heapq.heappop(self.queue)[1] # pop out the smallest item
  112. # def enumerate(self):
  113. # return self.queue
  114. # def check_remove(self, item):
  115. # for (p, s) in self.queue:
  116. # if item == s:
  117. # self.queue.remove((p, s))
  118. # def top_key(self):
  119. # return self.queue[0][0]