Prim MST算法优化

时间:2017-06-30 11:21:08

标签: python algorithm optimization minimum-spanning-tree

我正在实现最小生成树的Prim算法。 算法正常工作。 但是如果我有一个10000个节点的图表需要花费太多时间。 这是我在代码中存储图形的示例:

graph = {0: {1: 6, 5: 3}, 
1: {0: 6 , 6: 3 , 2: 9}, 
2: {1: 9, 7: 3 , 3: 5}}

以下是我如何度过青春期:

def adjacent(graph, u): # adjacencies of vertex u
    return graph[u].keys()

以下是我如何计算两个节点之间边缘的权重:

def w(u,v):
    L = cartesian_product[u].keys()
    if v in L:
        return cartesian_product[u].get(v)
    return 999999

这是我使用Prim算法计算最小生成树的密度的算法:

def prim(graph):
    total_mst_cost=0
    # put all nodes in a heap
    h=[(0,0)] 
    for i in range(1,n*k):
        heappush(h, (999999,i))
    while len(h)!=0 : #till there is a node left in the heap
        (key,u) = heappop(h)
        total_mst_cost += key
        # check hte adjacences of node-->
        adj = adjacent(graph,u)

        f = operator.itemgetter(1)
        ff = map(f, h)
        for v in adj:
            # update the labels:
            _ww = w(u,v)
            try: i = ff.index(v)
            except: continue
            if v==h[i][1] and _ww < h[i][0]:
                h[i]=(_ww, h[i][1])
        heapify(h)
            # for i in range(len(h)):
            #     if v==h[i][1] and _ww < h[i][0]:
            #         h[i]=(_ww, h[i][1])
            #         heapify(h)
    return total_mst_cost

1 个答案:

答案 0 :(得分:0)

想法1

堆的初始化:

for i in range(1,n*k):
    heappush(h, (999999,i))

是不必要的。如果所有节点都可以访问,您只需删除这两行。

创意2

体重提取:

L = cartesian_product[u].keys()

似乎很慢。我不太清楚cartesian_product是什么类型的,但如果它是一个字典,那么测试包含u in cartesian_product的速度应该比通过提取密钥列表并搜索它们更快。

创意3

每次迭代后调用heapify。我相信这是因为您希望能够调整堆队列中的权重。

此处的Python文档(https://docs.python.org/2/library/heapq.html#priority-queue-implementation-notes)中记录了另一种更快的方法,并将某些值标记为使用字典删除。

创意4

如果由于教育原因这不是,我建议使用带有图算法的Python库Networkx。在此库中,您可以使用minimum_spanning_tree

的函数调用替换所有代码