当前位置: 首页 > 知识库问答 >
问题:

使用优先级队列的Prims算法的复杂度?

韶兴德
2023-03-14

我用的是邻接矩阵,优先队列是数据结构。

根据我的计算,复杂度为V^3 log V

  • 同时循环V
  • 检查相邻顶点:V
  • 检查队列是否条目已经存在,并更新相同的:V log v

但是,我到处都读到复杂性是V^2

请解释。

共有3个答案

斜成济
2023-03-14

在优先级队列的情况下,如果不使用二进制堆,它包括两个基本步骤:1 .插入使用插入排序算法的插入时间复杂度是O(E^2)。删除删除对每个出列取O(1 ),并且出列等于顶点的数量,如果使用映射,否则将几乎相同,所以,这里的总时间复杂度是O(V E^2)

翟修永
2023-03-14

使用基于最小堆的优先级队列,时间复杂度为O(ElogV)。

正如您所说,外部while循环是O(V),因为它循环通过每个顶点,因为每个顶点都需要添加到MST一次。

对于 while 循环中考虑的每个顶点,需要执行以下两个步骤:

>

  • 选择下一条边添加到MST。根据基于最小堆的优先级队列的属性,根元素始终是最小的元素。因此,选择下一条边,即成本最低的边,将是根元素的O(1)提取。在提取之后,需要以保持优先级队列的方式移动剩余值。由于队列表示一个平衡的二叉树,在最坏的情况下,这种移位可能发生在O(logV)中。

    优先级队列已更新。入射到新顶点的边可能需要在队列中更新其成本,因为我们现在将考虑与新添加的顶点与其相邻点之间的边相关的成本(但是,如果它们通过成本低于新引入的边的边与以前添加的顶点相邻,则成本不会更新,因为我们正在寻找最低成本)。同样,这将是O(logV),因为在最坏的情况下,顶点将需要在表示队列的平衡二叉树的整个长度上移动。

    步骤 1 发生 V 次,因为它在 while 循环中发生一次,所以它是 O(VlogV) 总计,步骤 2 发生在最坏的情况下 E 次,其中每个边都连接到当前顶点,因此它们都需要更新,这意味着它是 O(ElogV) 总计。设置为 O(E),因为它要求将优先级队列中的每个边缘成本初始化为无穷大。

    使用基于最小堆的Priroty队列的总时间复杂度=O(E VlogV ElogV)=O(ElogV)

    当您阅读复杂度为O(V^2)时,您可能会看到不使用堆的实现。在这种情况下,外部while循环仍然是O(V)。瓶颈在于选择下一个要添加到MST的顶点的步骤,即O(V),因为您需要检查与每个相邻节点相关的成本以找到最低成本,这在最坏的情况下意味着检查所有其他节点。因此复杂性为O(V*V)=O(V^2)。

    此外,在非常密集的图中,O(ElogV)变为O(V^2),因为在任何图中,总边数最多可以有E = V^2。

  • 潘翊歌
    2023-03-14

    如果使用斐波纳契堆,则提取min是< code>O(lg V)摊销成本,更新其中的条目是< code>O(1)摊销成本。

    如果我们用这个伪代码

    while priorityQueue not empty
        u = priorityQueue.exractMin()
        for each v in u.adjacencies
            if priorityQueue.contains(v) and needsWeightReduction(u, v)
                priorityQueue.updateKeyWeight(u, v)
    

    假设实现对于< code > priority queue . contains(v)和< code > needsweightcreduction(u,v)都具有恒定的时间。

    需要注意的是,为了检查邻接,可以稍微收紧绑定。虽然外循环运行<code>V

    所以,你有外循环V次,内循环E次。提取最小运行次数<code>V

      V*lgV + E*1
    = O(V lgV + E)
    

    同样,由于E

      O(V lgV + V^2)
    = O(V^2)
    

    但是,在考虑稀疏图时,这是一个较宽松的界限(尽管是正确的)。

     类似资料:
    • 我正在为Dikjstra算法做一个优先级队列。我目前在插入方法上有麻烦。我包含了整个类的代码,以防你需要更好地了解我想完成的事情。我将堆索引放在一个数组列表(heapIndex)中,堆放在另一个数组列表中。 那是我运行程序后的输出(值,优先级,堆索引)。*(-1)表示heapIndex中的空单元格。

    • 我试图实现Prim的算法Java优先级队列。 我找不到我的错误我只是认识到队列没有正确地排列节点。 图表示例: 它始终将节点 4 作为第二个节点。因此,它对队列进行排序,如 [node1, node4, node2, node3],而不是 [node1,node2, node3, node4]。我对优先级队列执行了哪些操作? 问候语

    • 这是我写的Dijkstra算法的代码: 在这方面我不能理解的工作 这涉及到: < code>()运算符在这里有什么用?我是说它在这段代码中是如何运作的? 还有为什么我们使用

    • 在我实现Dijkstra算法的过程中,我有1个数组(包含所有节点)和1个优先级队列(包含所有节点)。每当一个节点排队时,我都会用新的距离和它来自哪里来更新所有相邻的节点,这样我就可以回溯路径。 优先级队列中的节点更新为新距离,数组中的节点更新为它来自的位置和新距离。当节点出列时,数组中的最终距离会更新: 用前一个节点的信息更新数组和用距离更新优先级队列是否可以接受? 只要找到更好的距离,就会发生这

    • 我需要使用Java中的优先级队列实现Dijkstra的算法。这是我到目前为止的代码: 我需要填写最短路径方法并返回节点数组。但是,我不确定如何做到这一点。我知道我需要在某个时候进行优先排队,但有人可以向我解释一下如何吗?我已经制作了startNode,我知道我需要为它分配一个距离值0,其余节点的距离值为无穷大。另外,可比性从何而来?

    • 我正在使用优先级队列实现Dijkstra的算法,我想要一个函数从堆中删除一个元素,但我只能从Dijkstra的主节点索引中向它发送顶点索引,我找不到它在堆上的位置,我负担不起进行二进制搜索。有什么想法吗?