利用python的heapq实现prim算法以及优先级队列

1. python heapq是一个最小堆,堆顶元素为最小值,最小(大)堆的逻辑结构是一颗二叉树,其中父节点的小(大于)于左右子节点,物理结构为一个数组。

   heapq模块支持heappush(入堆)、heappop(出堆)、heapify(创建堆)等操作,详细请参考python官方文档(https://docs.python.org/2/library/heapq.html)。


2. 利用heapq实现prim算法
   prim算法是指在一个加权连通图中寻找一颗最小子树,使得该连通子树权重和最小。

from collections import defaultdict
from heapq import heapify, heappop, heappush
 
def prim( nodes, edges ):
    conn = defaultdict( list )
    for n1,n2,c in edges:
        conn[ n1 ].append( (c, n1, n2) )
        conn[ n2 ].append( (c, n2, n1) )
     
    mst = []
    used = set( nodes[ 0 ] )
    usable_edges = conn[ nodes[0] ][:]
    heapify( usable_edges )

    while usable_edges:
        cost, n1, n2 = heappop( usable_edges )
        if n2 not in used:
            used.add( n2 )
            mst.append( ( n1, n2, cost ) )
 
            for e in conn[ n2 ]:
                if e[ 2 ] not in used:
                    heappush( usable_edges, e )
    return mst
 
nodes = list("ABCDEFG")
edges = [ ("A", "B", 7), ("A", "D", 5),
               ("B", "C", 8), ("B", "D", 9), 
               ("B", "E", 7), ("C", "E", 5),
               ("D", "E", 15), ("D", "F", 6),
               ("E", "F", 8), ("E", "G", 9),
               ("F", "G", 11)]
 
print "prim:", prim( nodes, edges )


3. 利用heapq实现优先级队列

import heapq
 
class Item:
    def __init__(self, name):
        self.name = name
 
    def __repr__(self):
        return 'Item({!r})'.format(self.name)
 
class PriorityQueue:
    def __init__(self):
        self._queue = []
        self._index = 0
 
    def push(self, item, priority):
        heapq.heappush(self._queue, (-priority, self._index, item))
        self._index += 1
 
    def pop(self):
        return heapq.heappop(self._queue)[-1]

    def __repr__(self):
        print __repr__(self._queue)

q = PriorityQueue()
q.push(Item('foo'), 1)
q.push(Item('bar'), 5)
q.push(Item('spam'), 4)
print q.pop() # Item('bar')


猜你喜欢

转载自blog.csdn.net/wh_springer/article/details/52771813