2012-04-18 3 views
6

Я использую очередь кучи для реализации алгоритма, когда я добавляю новые узлы в свою очередь, они сортируются с помощью эвристической функции: например, heappush (queue, (score (node)), который является фантастическим, кроме того, что, когда я пришел, чтобы вытащить следующий узел из очереди, я хочу, чтобы последний добавленный узел, в отличие от первого добавленного узла, возвращался к тому, что возвращается. как я могу получить последние узлы, добавленные в очередь, не нарушая их?Перерыв в очереди приоритетов с использованием python

Я думаю, что я мог бы просто начать итерацию в первом элементе, и в то время как следующий элемент имеет тот же балл, продолжайте. Затем, когда я нахожу последний элемент с этим счетом, я выбираю его и удаляю из списка. Это, очевидно, не очень эффективно, и разбивает временную сложность очереди приоритетов?

Я застрял на этом, и я не могу понять, как это сделать.

Спасибо.

изменить; Используя счетчик, как это было предложено не будет работать (возможно, я неправильно понял)

>>> queue = [] 
>>> heappush(queue, (2, 0, 'a')) 
>>> heappush(queue, (3, -1, 'b')) 
>>> queue 
[(2, 0, 'a'), (3, -1, 'b')] 
>>> heappush(queue, (2, -2, 'c')) 
>>> queue 
[(2, -2, 'c'), (3, -1, 'b'), (2, 0, 'a')] 

Теперь очередь заказан неправильно, и «б», которая является хуже, чем вариант «а» стоит перед ним.

EDIT 2:

Какого черта?

>>> heappop(queue) 
(2, -2, 'c') 
>>> queue 
[(2, 0, 'a'), (3, -1, 'b')] 
>>> 

ответ

7

Один очень простой способ - добавить средний термин, содержащий метку времени или значение счетчика. Так, например:

>>> heap = [] 
>>> counter = itertools.count() 
>>> for i in range(10): 
...  heapq.heappush(heap, (i, -next(counter), str(i) + ' oldest')) 
...  heapq.heappush(heap, (i, -next(counter), str(i) + ' newest')) 
... 
>>> heapq.heappop(heap) 
(0, -1, '0 newest') 
>>> heapq.heappop(heap) 
(0, 0, '0 oldest') 
>>> heapq.heappop(heap) 
(1, -3, '1 newest') 
>>> heapq.heappop(heap) 
(1, -2, '1 oldest') 

Как отмечает AGF, это подход, используемый в heapq документы, используя только отрицательные индексы. (Реализация там также включает в себя прекрасную процедуру удаления задачи и смены приоритета).

+2

Это конкретно упоминается как решение в разделе [Приоритетная реализация очередей] (http://docs.python.org/library/heapq.html # priority-queue-implementation-notes) в документах 'heapq'. – agf

+0

Я отредактировал свое оригинальное сообщение, чтобы продемонстрировать пример того, почему я думаю, что это может не сработать, возможно, я неправильно понял, что вы предлагаете? – user1291204

+4

@ user1291204 Очередь кучи не является отсортированным списком. Он частично отсортирован, так что '(heap [k] <= heap [2 * k + 1]) и (heap [k] <= heap [2 * k + 2])', инвариант кучи, всегда 'True '. Так что 'heap [1]' не должен быть меньше или равен 'heap [2]', просто 'heap [3]' и выше. 'heap [0]' всегда будет наименьшим. – agf

Смежные вопросы