在STL优先队列c++中实现了reducekey

Implement decreaseKey in STL Priority Queue C++

本文关键字:实现 reducekey c++ STL 优先队列      更新时间:2023-10-16

我试图实现Prim的算法,为此我需要有一个用于优先级队列的reducekey方法(更新优先级队列中的键值)。我可以在STL优先队列中实现这一点吗?

如果它有帮助,这是我遵循的算法:

    图G中每个顶点u的
    • 设置u键为INFINITY
    • 设置u的父元素为NIL
  • 设置源顶点键为0
  • 排队到优先队列Q图中所有顶点的键值如下
  • ,而Q不为空
    • u的每个相邻顶点v的
      • if (v仍在Q) and (key(u) + weight-function(u, v) <键(v))>
        • 设置u为v的父级
        • 更新v的键等于key(u) + weight-function(u, v) //这部分给了我问题,因为我不知道如何实现在优先队列

    我不认为你可以在STL容器中实现它。请记住,您总是可以基于vector编写自己的堆(优先级队列),但有一种解决方法:

    保持你的距离数组,比如d。在你的优先级队列中,你把距离对和这个距离的顶点索引放在一起。当您需要从队列中删除某个值时,不需要删除它,只需在d数组中更新您的值并将新对放入队列即可。

    每次你从队列中获取新值时,检查pair中的距离是否真的那么好,就像你的数组d一样。

    时间相同O(MlogM)。内存为0 (MlogM),其中M为边数。

    还有另一种方法:使用RB-Tree,它可以在O(logN)内插入和删除键,并且得到最小值。您可以在std::set容器中找到RB-Tree的STL实现。

    但是,尽管时间复杂度相同,RB-Tree的工作速度更慢,隐藏常数更大,所以它可能会稍微慢一点,appx。慢5倍。当然,这取决于数据。

    对于另一种方法:优于使用std::set。您可以使用btree::btree_set(或btree::safe_btree_set)。这是一个与std::set相同的实现,由google使用B-Tree,而stl使用RB-Tree。这比std::set和O(logN)要好得多。查看性能对比:http://code.google.com/p/cpp-btree/wiki/UsageInstructions而且它占用的内存也少得多。

    我不是专家,所以希望这不是太愚蠢,但是向量与lower_bound结合会很好地工作吗?

    如果使用lower_bound找到插入新值的正确位置,则在构建vector时,vector总是被排序,不需要排序。当你的向量排序时,lower_bound不是一个具有对数类性能的二分搜索吗?

    因为它是排序的,所以找到最小值(或最大值)是很容易的。

    对于reduce key,您将执行lower_bound搜索,删除,并再次执行lower_bound以插入简化的键,这= 2个对数类操作。还不错。

    或者,您可以更新键并对向量进行排序。我猜对于随机访问,它应该仍然在对数类中,但我不知道它到底是做什么的。

    对于已排序的向量,如果你知道候选键小于里面的那个键,那么也许你甚至可以对向量中包含所有较小值的部分进行排序以获得更好的性能。

    另一个考虑是我认为集合/映射有相当多的内存开销比向量做?

    我认为大多数排序都局限于NLogN,所以2 LogN用于重新插入而不是排序可能对reduce键操作更好。

    另一件事是插入向量不是那么热门,但总的来说,向量w的想法是否值得考虑?

    谢谢