Удаление произвольного элемента из очереди приоритетов - PullRequest
6 голосов
/ 15 февраля 2012

Как я могу удалить произвольный элемент из очереди приоритетов. Предположим, у меня есть PriorityQueue для работы. У меня есть работа, которую я хочу «отменить», поэтому мне нужно удалить ее из очереди, как я могу это сделать?

UPDATE

Чтобы добавить к ответу, связанный вопрос: https://stackoverflow.com/a/9288081/292291

Ответы [ 2 ]

6 голосов
/ 15 февраля 2012

Я предполагаю, что вы используете heapq. Документация говорит об этой проблеме, что кажется вполне разумным:

Оставшиеся проблемы вращаются вокруг нахождения ожидающей задачи и внесение изменений в его приоритет или удаление его полностью. Нахождение задачи может быть сделано с помощью словаря, указывающего на запись в очереди.

Удаление записи или изменение ее приоритета труднее, потому что это сломало бы инварианты структуры кучи. Итак, возможное решение пометить существующую запись как удаленную и добавить новую запись с пересмотренный приоритет.

В документации приведен базовый пример кода, демонстрирующий, как это можно сделать, который я дословно воспроизвожу здесь:

pq = []                         # list of entries arranged in a heap
entry_finder = {}               # mapping of tasks to entries
REMOVED = '<removed-task>'      # placeholder for a removed task
counter = itertools.count()     # unique sequence count

def add_task(task, priority=0):
    'Add a new task or update the priority of an existing task'
    if task in entry_finder:
        remove_task(task)
    count = next(counter)
    entry = [priority, count, task]
    entry_finder[task] = entry
    heappush(pq, entry)

def remove_task(task):
    'Mark an existing task as REMOVED.  Raise KeyError if not found.'
    entry = entry_finder.pop(task)
    entry[-1] = REMOVED

def pop_task():
    'Remove and return the lowest priority task. Raise KeyError if empty.'
    while pq:
        priority, count, task = heappop(pq)
        if task is not REMOVED:
            del entry_finder[task]
            return task
    raise KeyError('pop from an empty priority queue')
4 голосов
/ 15 февраля 2012

Встроенный в Python PriorityQueue не поддерживает удаление любого элемента, кроме верхнего.Если вам нужна поддержка удаления каких-либо элементов, вам нужно реализовать собственную очередь (или найти чью-либо реализацию).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...