Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 对于我的用例,有比最小堆更快的东西吗?_C++_Performance_Data Structures - Fatal编程技术网

C++ 对于我的用例,有比最小堆更快的东西吗?

C++ 对于我的用例,有比最小堆更快的东西吗?,c++,performance,data-structures,C++,Performance,Data Structures,我的用例如下所示: 我需要得到一组增长元素的最小值;我只需要任何迭代的最小值 我将更新最小值,之后它将保证不再是最小值,但其在顺序中的新位置通常不可直接计算 我将这个新值推回到集合中,并转到下一个迭代,在那里我查看新的min元素 现在,我以以下方式使用std::vector和std::pop_堆std::push_堆。我在向量上调用std::pop_堆,它将min元素推到向量的后面,我得到最后一个元素的引用并更新它,然后调用std::push_堆,它将最后一个元素移动到它的新位置。所以我不必从s

我的用例如下所示:

  • 我需要得到一组增长元素的最小值;我只需要任何迭代的最小值
  • 我将更新最小值,之后它将保证不再是最小值,但其在顺序中的新位置通常不可直接计算
  • 我将这个新值推回到集合中,并转到下一个迭代,在那里我查看新的min元素
  • 现在,我以以下方式使用std::vector和std::pop_堆std::push_堆。我在向量上调用std::pop_堆,它将min元素推到向量的后面,我得到最后一个元素的引用并更新它,然后调用std::push_堆,它将最后一个元素移动到它的新位置。所以我不必从std::vector中复制结构来更新它。所讨论的结构是16个字节,可构造性很低,它非常基本,完全由整数类型组成

    根据我的分析器和一系列问题大小,我看到的是,我在std::pop_堆中花费了超过75%的cpu时间,在std::push_堆中花费了约10%的cpu时间。现在,在每个被检查的最小元素上执行的逻辑非常简单,主要由加法和一些与固定输入的比较组成,所以我认为这是可能的。但是,如果有一个不同的或随机的奇怪数据结构,它可能比我目前使用的min_堆更快,那么尝试一下会很有趣

    我尝试了std::min\u元素、std::nth\u元素、std::sort元素,对于1000000或更少的问题,每个元素的当前解决方案时间都不到1秒,并将运行时间增加了几个数量级(许多10秒)。考虑到它们的复杂性都比std::push_堆和std::pop_堆差,我会想到这一点

    我也尝试过使用树结构,比如std::map和std::set,但它们也会降低性能(我现在手头没有数字)

    那么,对于这个用例,有人知道比min_堆更好的东西吗

    (不幸的是,我不能提供源代码,但考虑到85%的cpu时间都花在pop_堆/push_堆上,我认为这无论如何都不会非常有用)


    编辑:比较运算符是两个整数类型之间的单个比较。因此,堆中使用的比较运算符并不是在做大量的工作。

    与其删除最小元素并重新插入更新的值,不如就地更改该值并从根开始向下调整。删除最小值元素通常会用最差的元素之一替换根元素,通常会导致较长的向下气泡,然后重新插入相对较小的值也会导致较长的向上气泡。在适当的位置更改关键点会用一个向下的气泡来替换这两个气泡,只要新值平均保持相对接近根,气泡通常也会较短


    遗憾的是,
    (可能是4,可能是8)中没有用于此的函数。当您更新最小值时,它的新位置通常是更靠近根还是更靠近“端点”您是否尝试过不包含已删除元素但存储所有已删除元素的最小值的排序向量,并在最小值较小时再次插入它们?您的代码每次迭代调用
    push_heap()
    pop_heap()
    ?理想情况下,每次迭代(当您从堆中弹出最小值,对其进行更新,然后将其推回)中的一个加上一个
    push_heap()
    调用,用于同时将每个新项推入元素集中。如果不止这些,请检查以确保您没有做一些低效的事情(例如在每次迭代中清除堆并从头开始重新填充)@harold通常它更接近最小值而不是最大值,但这对于任何给定的迭代都不能保证。@henk元素不会被删除,它们会被修改并推回,最小元素的值在算法的生命周期内缓慢增长,更新到位,编写我自己的下推方法是我还没有尝试过的事情,所以我肯定会研究这个问题,不确定增加算术数会对这个例子产生什么影响,但也值得一看;谢谢所以我检查了如何为堆实现我自己的siftdown算法,并在适当的位置修改了min元素,这使我得到了30-60%的收益,这取决于问题的大小。现在,我的分析器指向单个比较运算符,因此我认为要进一步改进,我需要在继续操作时存储较少的状态:)