【问题标题】:Priority queue with two priority values具有两个优先级值的优先级队列
【发布时间】:2014-08-10 20:29:44
【问题描述】:

众所周知,插入到优先级队列中的元素有一个决定其优先级的值。例如,如果我有五个具有优先级的元素A,B,C,D,E(我们称其为优先级值priorityI): A = 10, B = 5, C = 1, D = 3, E = 2。 但是如何编写一个优先级队列,我可以在其中定义两个优先级值,我的意思是: 如果两个元素具有相同的 priorityI 值,则值 priorityII 决定应首先采用哪个元素,例如:

element A has priorityI = 3, and prioriotyII = 5
element B has priorityI = 3, and prioriotyII = 1

那么首先从队列中取出第一个元素B。

【问题讨论】:

  • 有什么问题吗?但是我可以编写一个可以定义两个优先级值的优先级队列吗?是的,粗略的为什么你不能...
  • @JoranBeasley 好吧,我想我错误地定义了这个问题,应该是:如果有人可以举个例子,我该如何定义这种优先级队列?

标签: python queue priority-queue


【解决方案1】:

从Python2.6开始,可以使用Queue.PriorityQueue

插入队列的项目是根据它们的__cmp__方法排序的,所以只需为要插入队列的对象的类实现一个。

请注意,如果您的项目由对象元组组成,则不需要为元组实现容器类,因为built in tuple comparison implementation 可能符合您的需求,如上所述(首先弹出较低值的项目)。不过,您可能需要为对象驻留在元组中的类实现 __cmp__ 方法。

>>> from Queue import PriorityQueue
>>> priority_queue = PriorityQueue()
>>> priority_queue.put((1, 2))
>>> priority_queue.put((1, 1))
>>> priority_queue.get()
(1, 1)
>>> priority_queue.get()
(1, 2)

编辑: 正如@Blckknght 所指出的,如果您的优先级队列仅由单个线程使用,则可从Python2.3 获得的heapq 模块是首选解决方案。如果有,请参考his answer

【讨论】:

  • Queue 模块(在 Python 3 中重命名为 queue)旨在用于多个线程之间的同步通信,而不是作为通用数据结构。如果您的优先级队列仅由单个线程使用,您应该改用heapq 模块(它使用list 来保存数据)。这是Queue.PriorityQueue 在内部使用的,所以你可以在没有同步相关开销的情况下得到它!
  • @Blcknght,我不熟悉heapq。我编辑了我的答案以反映您的评论,并为您的评论和您的答案投票。
【解决方案2】:

执行此操作的常用方法是将优先级值设为两个优先级的元组。 Python 按字典顺序对元组进行排序,因此它首先会比较每个优先级的第一个元组项,只有当它们相等时才会比较下一个项。

在 Python 中创建优先级队列的常用方法是使用 the heapq module 的函数来操作列表。由于比较了整个值,我们可以简单地将两个优先级与一个值放在一个元组中:

import heapq

q = []  # the queue is a regular list

A = (3, 5, "Element A")  # our first item, a three-tuple with two priorities and a value
B = (3, 1, "Element B")  # a second item

heapq.heappush(q, A)  # push the items into the queue
heapq.heappush(q, B)

print(heapq.heappop(q)[2])  # pop the highest priority item and print its value

这打印"Element B"

【讨论】:

    猜你喜欢
    • 2023-04-02
    • 2011-01-18
    • 2011-12-20
    • 1970-01-01
    • 1970-01-01
    • 2013-02-13
    • 1970-01-01
    • 2010-10-01
    相关资源
    最近更新 更多