В любом языке . 1003 *.
не существует такого понятия, как «наиболее эффективная реализация очереди с приоритетами». Очередь приоритетов - это все компромиссы.См. http://en.wikipedia.org/wiki/Priority_queue
Вы должны выбрать один из этих двух, в зависимости от того, как вы планируете его использовать:
O(log(N))
время вставки и O(1)
время поиска мин + время удаления,или O(1)
время вставки и O(log(N))
findMin + время удаления delete
В последнем случае вы можете выбрать реализацию очереди приоритетов с кучей Фибоначчи: http://en.wikipedia.org/wiki/Heap_(data_structure)#Comparison_of_theoretic_bounds_for_variants (как вы можете видеть, heapq
, который является в основном двоичным деревом, обязательно должен иметь O(log(N))
для вставки и findMin + deleteMin)
Если вы имеете дело с данными со специальными свойствами (такими каккак ограниченные данные), тогда вы можете достичь O(1)
вставки и O(1)
findMin + deleteMin времени.Вы можете делать это только с определенными типами данных, потому что в противном случае вы могли бы злоупотребить своей приоритетной очередью, чтобы нарушить ограничение O(N log(N))
для сортировки.
Чтобы реализовать любую очередь на любом языке, все, что вам нужно, это определить insert(value)
и extractMin() -> value
операций.Как правило, это просто включает в себя минимальное обертывание основной кучи;см. http://en.wikipedia.org/wiki/Fibonacci_heap, чтобы реализовать свою собственную, или использовать готовую библиотеку аналогичной кучи, например, «Куча сопряжения» (поиск Google показал http://svn.python.org/projects/sandbox/trunk/collections/pairing_heap.py)
Если вас волнует только то, какие из двух упомянутых вами ссылок более эффективны (код на основе heapq
из http://docs.python.org/library/heapq.html#priority-queue-implementation-notes, который вы включили выше, по сравнению с Queue.PriorityQueue
), то:
Кажется, что в интернете легко найти дискуссию о том, что на самом деле делает Queue.PriorityQueue
;Вы должны были бы погрузиться в код, который связан с справочной документацией: http://hg.python.org/cpython/file/2.7/Lib/Queue.py
224 def _put(self, item, heappush=heapq.heappush):
225 heappush(self.queue, item)
226
227 def _get(self, heappop=heapq.heappop):
228 return heappop(self.queue)
Как мы видим, Queue.PriorityQueue
также использует heapq
в качестве основного механизма.Поэтому они одинаково плохи (асимптотически говоря).Queue.PriorityQueue
может допускать параллельные запросы, поэтому я хотел бы поспорить, что это может иметь очень немного постоянный коэффициент, увеличивающий накладные расходы.Но поскольку вы знаете, что базовая реализация (и асимптотическое поведение) должны быть одинаковыми, самый простой способ - просто запустить их в одном большом наборе данных.
(обратите внимание, что Queue.PriorityQueue
, похоже, не имеетспособ удалить записи, в то время как heapq
это делает. Однако это обоюдоострый меч: реализация очередей с хорошим приоритетом может позволить вам удалять элементы за O (1) или O (log (N)), но если выиспользуйте функцию remove_task
, которую вы упомянули, и пусть эти задачи-зомби накапливаются в вашей очереди, потому что вы не извлекаете их из минимума, тогда вы увидите асимптотическое замедление, которое иначе вы бы не увидели. Конечно, вы не моглисделайте это с Queue.PriorityQueue
во-первых, чтобы сравнение здесь не проводилось.)