python中的prim算法

时间:2015-04-15 05:56:40

标签: python algorithm data-structures

我已经查看了这方面的问题,但仍然遇到了一些麻烦。我试图实现Prim算法究竟出了什么问题?我觉得这与它有关,只有当它是树中的最小权重时才将其添加到生成树中,但我没有看到如何实现它。这是我到目前为止所尝试的内容,我将在顶部包含优先级队列入队方法。它似乎将所有顶点添加到树中。从顶点0开始的输出是以下..

(0, 5), (1, 5), (2, 5), (3, 5), (4, 5), (5, 5), (0, 1), (1, 1), (2, 1), (3, 1) (4, 1), (0, 2), (2, 2), (3, 2), (4, 2), (0, 4), (3, 4), (4, 4)

 def dequeue(self):
    weight, data = self.queue.pop(0)
    self.size -= 1
    return data

 def enqueue(self, data, weight):
    curr_index = 0

    while (curr_index < self.size and
           self.queue[curr_index][WEIGHT] < weight):
        curr_index += 1

    self.queue.insert(curr_index, (weight, data))
    self.size += 1

def add_edges(self, p_queue, vertex, vertices):
    for i in range(len(self.adjacency_matrix)):
        weight = self.adjacency_matrix[vertex][i]
        if weight != 0:
            p_queue.enqueue(vertex, weight)
            if (i, vertex) not in vertices:
                vertices.append((i, vertex))
    return vertices 


def init_pqu(self, p_queue, start_vertex):
    for i in range(len(self.adjacency_matrix)):
        weight = self.adjacency_matrix[start_vertex][i]
        if weight != 0:
            p_queue.enqueue(start_vertex, weight)


def prim(self, start_vertex):
    vertices = []
    priority_queue = pq.priority_queue()
    self.init_pqu(priority_queue, start_vertex)
    while len(priority_queue.queue) > 0:
        source = priority_queue.dequeue()
        vertices = self.add_edges(priority_queue, source, vertices)
    return vertices

1 个答案:

答案 0 :(得分:1)

您的代码存在多个问题,我可以立即发现:

1)目前尚不清楚您提供的入队方法是否与您呼叫的pq.enqueue相同。如果它是相同的,那么你的enqueue有两个参数(顶点和权重),但你只传递它的顶点,所以权重总是作为None传递,使得优先级队列每次都返回你的随机顶点。

如果它不相同,那么首先你永远不会调用你的队列,你总是打电话给pq.enqueue,其次,你将顶点id 插入你的优先级队列,所以它按顶点id 排序,而不是按边缘权重排序。对于Prima算法而言,权重排序的优先级队列至关重要。

2)此代码也不正确:

    if (vertex, i) not in vertices:
        vertices.append((i, vertex))

因为您检查(vertex, i),但追加(i, vertex),所以您的情况要么永远不会触发,要么以错误的方式触发。

3)您的add_edges例程有一个参数p_queue,但使用的是pq。您有pq某种全局优先级队列吗?

更新:在修复了所有这些之后,现在也只是在之前没有添加顶点时添加一个顶点,换句话说,而不是这样做:

        p_queue.enqueue(vertex, weight)
        if (i, vertex) not in vertices:
            vertices.append((i, vertex))

这样做:

        if (i, vertex) not in vertices:
            p_queue.enqueue(vertex, weight)
            vertices.append((i, vertex))