标签: priority-queue

我如何使用PriorityQueue?

我如何得到一个PriorityQueue排序我希望它排序的东西?

另外,offeradd方法之间有区别吗?

java priority-queue

357
推荐指数
8
解决办法
55万
查看次数

.Net中的优先级队列

我正在寻找优先级队列或堆数据结构的.NET实现

优先级队列是比简单排序提供更多灵活性的数据结构,因为它们允许新元素以任意间隔进入系统.将新作业插入优先级队列比在每次到达时重新排序所有内容更具成本效益.

基本优先级队列支持三种主要操作:

  • 插入(Q,X).给定具有密钥k的项x,将其插入优先级队列Q.
  • 查找-最小(Q).返回指向其键值小于优先级队列Q中任何其他键的项的指针.
  • 删除 - 最小(Q).从密钥最小的优先级队列Q中删除该项

除非我在错误的地方寻找,否则框架中没有一个.有人知道一个好的,或者我应该自己动手?

.net c# heap priority-queue data-structures

211
推荐指数
9
解决办法
17万
查看次数

如何创建Min stl priority_queue?

默认的stl优先级队列是Max 1(Top函数返回最大的元素).

为简单起见,它说它是int值的优先级队列.

c++ stl priority-queue

101
推荐指数
6
解决办法
12万
查看次数

将priorityQueue更改为max priorityqueue

我在整数Java中有优先级队列:

 PriorityQueue<Integer> pq= new PriorityQueue<Integer>();
Run Code Online (Sandbox Code Playgroud)

当我打电话时,pq.poll()我得到最小元素.

问题:如何更改代码以获取最大元素?

java collections priority-queue

97
推荐指数
9
解决办法
15万
查看次数

为什么Dijkstra的算法使用减少键?

Dijkstra的算法教给我如下

while pqueue is not empty:
    distance, node = pqueue.delete_min()
    if node has been visited:
        continue
    else:
        mark node as visited
    if node == target:
        break
    for each neighbor of node:
         pqueue.insert(distance + distance_to_neighbor, neighbor)
Run Code Online (Sandbox Code Playgroud)

但是我一直在阅读关于算法的一些阅读,我看到的很多版本都使用了reduce-key而不是insert.

为什么会这样,这两种方法之间有什么区别?

algorithm dijkstra priority-queue graph-algorithm data-structures

88
推荐指数
2
解决办法
2万
查看次数

Microsoft内部PriorityQueue <T>中的错误?

在PresentationCore.dll的.NET Framework中,有一个泛型PriorityQueue<T>类,其代码可以在这里找到.

我写了一个简短的程序来测试排序,结果不是很好:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using MS.Internal;

namespace ConsoleTest {
    public static class ConsoleTest {
        public static void Main() {
            PriorityQueue<int> values = new PriorityQueue<int>(6, Comparer<int>.Default);
            Random random = new Random(88);
            for (int i = 0; i < 6; i++)
                values.Push(random.Next(0, 10000000));
            int lastValue = int.MinValue;
            int temp;
            while (values.Count != 0) {
                temp = values.Top;
                values.Pop();
                if (temp >= lastValue)
                    lastValue = temp;
                else
                    Console.WriteLine("found sorting error");
                Console.WriteLine(temp);
            }
            Console.ReadLine();
        } …
Run Code Online (Sandbox Code Playgroud)

.net c# priority-queue

77
推荐指数
2
解决办法
3539
查看次数

使用自定义比较器在c ++中声明priority_queue

我试图声明一个priority_queue of nodes,bool Compare(Node a, Node b)用作比较器函数(在节点类之外).

我现在拥有的是:

priority_queue<Node, vector<Node>, Compare> openSet;
Run Code Online (Sandbox Code Playgroud)

出于某种原因,我得到了 Error: "Compare" is not a type name

将声明更改为 priority_queue <Node, vector<Node>, bool Compare>

给我 Error: expected a '>'

我也尝试过:

priority_queue<Node, vector<Node>, Compare()> openSet;
priority_queue<Node, vector<Node>, bool Compare()> openSet;
priority_queue<Node, vector<Node>, Compare<Node, Node>> openSet; 
Run Code Online (Sandbox Code Playgroud)

我应该如何正确地宣布我的priority_queue

c++ std priority-queue

61
推荐指数
7
解决办法
11万
查看次数

在其元素更改优先级时更新Java PriorityQueue

我正在尝试使用a PriorityQueue来命令对象Comparator.

这可以很容易地实现,但是对象类变量(比较器计算优先级)可能在初始插入后发生变化.大多数人都提出了删除对象,更新值并再次重新插入的简单解决方案,因为这是优先级队列的比较器付诸行动的时候.

除了在PriorityQueue周围创建一个包装类之外,还有更好的方法吗?

java priority-queue

54
推荐指数
5
解决办法
5万
查看次数

std :: set和std :: priority_queue之间的区别

由于两者std::priority_queuestd::set(和std::multiset)都是存储元素的数据容器,并允许您以有序的方式访问它们,并且具有相同的插入复杂性O(log n),因此使用一个优于另一个(或者,什么样的情况需要一个)或者其他?)?

虽然我知道底层结构是不同的,但我对它们的实现差异并不那么感兴趣,因为我在比较它们的性能适用于各种用途.

注意:我知道集合中没有重复.这就是我之所以提到的原因,std::multiset因为它具有与之完全相同的行为,std::set但可以在允许存储的数据作为相等元素进行比较的情况下使用.所以,请不要评论单/多键问题.

c++ sorting algorithm priority-queue

51
推荐指数
4
解决办法
2万
查看次数

二进制堆的有效实现

我正在寻找有关如何有效实现二进制堆的信息.我觉得应该有一篇关于有效实现堆的好文章,但我还没找到.事实上,我已经无法找到任何有关超出基础知识的有效实现的资源,例如将堆存储在数组中.我正在寻找制作快速二进制堆的技术,超出我在下面描述的那些.

我已经编写了一个比Microsoft Visual C++和GCC的std :: priority_queue或使用std :: make_heap,std :: push_heap和std :: pop_heap更快的C++实现.以下是我在实现中已经涵盖的技术.我自己只想出了最后两个,尽管我怀疑这些是新想法:

(编辑:添加了关于内存优化的部分)

  • 从1开始索引
    查看维基百科的二进制堆实现说明.如果堆的根位于索引0处,则索引n处的节点的父,左子和右子的公式分别为(n-1)/ 2,2n + 1和2n + 2.如果使用基于1的数组,则公式变为更简单的n/2,2n和2n + 1.因此,使用基于1的数组时,父项和左子项更有效.如果p指向基于0的数组并且q = p-1,那么我们可以将p [0]作为q [1]来访问,因此使用基于1的数组没有开销.

  • 在使用leaf替换之前,将pop/remove移动元素设置到堆的底部
    经常通过将最顶部元素替换为最左边的底部叶子然后将其向下移动直到堆属性恢复来描述.这需要我们经历的每个级别的2次比较,并且由于我们将叶子移动到堆的顶部,因此我们可能会在堆中走得很远.所以我们应该期望比较少于2 log n.

    相反,我们可以在顶部元素所在的堆中留一个洞.然后我们通过迭代地移动较大的孩子来将那个洞向下移动.这需要我们经过的每个级别只有1个比较.通过这种方式,洞将成为一片叶子.此时,我们可以将最右下方的叶子移动到孔的位置,并将该值向上移动,直到堆属性恢复为止.由于我们移动的值是一片叶子,我们不希望它在树上移动很远.所以我们应该期待比log n更多的比较,这比以前更好.

  • 支持replace-top
    假设您要删除max元素并插入新元素.然后,您可以执行上述任何一个删除/弹出实现,但不是移动最右侧的底部叶子,而是使用您希望插入/推送的新值.(当大多数操作属于这种类型时,我发现锦标赛树比堆更好,但是堆更好一点.)

  • 使sizeof(T)的幂为2
    父,子和子子公式适用于索引,并且不能使它们直接在指针值上工作.所以我们将使用索引,这意味着从索引i中查找数组p中的值p [i].如果p是T*且i是整数,那么

    &(p[i]) == static_cast<char*>(p) + sizeof(T) * i
    
    Run Code Online (Sandbox Code Playgroud)

    并且编译器必须执行此计算以获得p [i].sizeof(T)是编译时常量,如果sizeof(T)是2的幂,则可以更有效地进行乘法.通过添加8个填充字节以将sizeof(T)从24增加到32,我的实现变得更快.降低缓存效率可能意味着这对于足够大的数据集来说并不是一个胜利.

  • 预乘法索引
    我的数据集性能提升了23%.除了查找父级,左子级和右子级之外,我们对索引执行的唯一操作是在数组中查找索引.因此,如果我们跟踪j = sizeof(T)*i而不是索引i,那么我们可以进行查找p [i]而不需要在评估p [i]时隐含的乘法,因为

    &(p[i]) == static_cast<char*>(p) + sizeof(T) * i == static_cast<char*>(p) + j
    
    Run Code Online (Sandbox Code Playgroud)

    然后,j值的左子和右子公式分别变为2*j和2*j + sizeof(T).父公式有点棘手,除了将j值转换为i值之外,我还没有找到方法做到这一点,如下所示:

    parentOnJ(j) = parent(j/sizeof(T))*sizeof(T) == (j/(2*sizeof(T))*sizeof(T)
    
    Run Code Online (Sandbox Code Playgroud)

    如果sizeof(T)是2的幂,那么这将编译为2个移位.这比使用索引i的普通父亲多1次操作.然而,我们然后在查找上保存1个操作.因此,净效应是找到父母用这种方式花费相同的时间,而左子和右子的查找变得更快. …

  • c++ performance computer-science priority-queue data-structures

    50
    推荐指数
    1
    解决办法
    9996
    查看次数