python中堆元素的比较顺序

时间:2016-09-10 08:02:59

标签: python algorithm python-3.x sorting heap

我正在使用堆来使用heapq创建优先级队列。

我使用

将一个项目插入队列

heapq.heappush(h, (cost, node))

其中h是堆对象,cost是我订购堆的项目,node是自定义类的对象。

当我运行代码时,当我在h中使用相同的cost

插入两个不同的项时,会出现以下错误
  

TypeError:unorderable类型:SearchNode()< SearchNode()

其中SearchNode()node

的类

错误表明Python正在比较第二项。

是否存在堆元素的比较顺序?如果是,我如何解决算法中的关系,使其无法开始比较第二项。我想到的一个可能的解决方案是重载SearchNode()类的比较运算符。

我是python的新手,所以请随意指出我是否遗漏了一些非常明显的东西。

3 个答案:

答案 0 :(得分:3)

介绍一个在比较中不包含节点的小类:

class CostAndNode:
    def __init__(self, cost, node):
        self.cost = cost
        self.node = node

    # do not compare nodes
    def __lt__(self, other):
        return self.cost < other.cost

h = []

heapq.heappush(h, CostAndNode(1, node1))
heapq.heappush(h, CostAndNode(1, node2))

答案 1 :(得分:3)

如果你能明智地决定比较节点的方法,你可以用它来打破关系。例如,可以为每个节点分配一个&#34;标签&#34;,您可以保证它是唯一的。您可以通过按字典顺序比较标签来打破关系。#

class SearchNode:
    def __init__(self, label):
        self.label = label
        #etc

    def __lt__(self, other):
        return self.label < other.label

这将确保(cost, node)的比较具有确定性。

答案 2 :(得分:-1)

PQ包含列表和bisect,字符串作为存储对象。无需更改存储对象。只需构造item = (cost, object)并将其插入PQ。

import bisect
# PQ of items
PQ = [
    (10, 'aaa'),
    (30, 'cccc'),
    (40, 'dddd'),
]

def pq_insert(pq, item):
    keys = [e[0] for e in pq]
    i = bisect.bisect(keys, item[0])
    pq.insert(i, item)

e = (20, 'bbbb')
pq_insert(PQ, e)

一些REPL输出

>>> print PQ
[(10, 'aaa'), (30, 'cccc'), (40, 'dddd')]
>>> e = (20, 'bbbb')
>>> pq_insert(PQ, e)
>>> print PQ
[(10, 'aaa'), (20, 'bbbb'), (30, 'cccc'), (40, 'dddd')]
>>>