C ++优先级队列 - 根据更新的优先级重新排序

时间:2014-06-14 17:16:17

标签: c++ multithreading asynchronous data-structures priority-queue

一些背景知识:我正在构建一个C++线程管理器,它允许用户创建一个AsyncJob对象并分配执行的优先级。我有一个JobManager单例类,它管理这些AsyncJobs的优先级队列,并在可用时将它们分配给一个线程。

问题:用户需要能够修改优先级AFTER的创建。例如,基于某些运行时事件,可能需要比其他文件更紧急地加载文件。我面临的问题是优先级队列只在调用push()pop()时重新排序内部堆上的元素。据我所知,没有暴露的界面允许人们根据不断变化的优先级请求重新排序。

我想做的是这样的事情:

  • 在我的hashmap类中创建一个JobManager,其中包含指向优先级队列中对象的指针
  • 用户可以通过其密钥访问请求的作业,并通过哈希映射更新优先级
  • 然后JobManager向优先级队列发出优先级已更改的信号
  • 优先级队列在内部重新排序

最好的解决方法是什么?我应该期望创建自己的自定义优先级队列类吗?或者可以从std::priority_queue

延伸

谢谢!

3 个答案:

答案 0 :(得分:3)

一个选项可能是允许您的AsyncJob取消'取消'在取消旧的优先级后,每次修改优先级时,只需将AsyncJob的新(副本)添加到PQ。

与许多事情一样,我建议采用“最好的方式”。是非常主观的,因为它取决于你是多么受限制,以及你如何量化最好的'。就个人而言,我希望避免从标准库类型派生并尽可能重新发明容器结构。

答案 1 :(得分:2)

binary search tree似乎是一个不错的选择。

二进制搜索树应按优先级排序,其次,如果优先级不是唯一的,则对象中的唯一标识符/标识符集。

如果您想要更改以前的优先级,那么您需要一种方法来查找 - 可能是hash table优先级的对象。

这允许您删除并重新插入O(log n)中的特定项目,而不会失去其他操作的O(log n)性能(并O(1)获得第一个)。


对于C ++:

如果优先级是唯一的,则对象的map优先级可以有效,否则set < pair >其中第一个元素是优先事项,第二个是对象(是的,我知道,那些不一定是BST&#39;)。

对于哈希表,您可以使用unordered_map对象作为优先级,或者只使用map预C ++ 11。

答案 2 :(得分:1)

删除更改其优先级然后添加它的项目(或副本,如果新优先级在逻辑上意味着新项目)可能是最简单的方法。毕竟,您不想从头开始重新排序整个队列,只需更改单个项目 - 删除它并插入它就可以了。

编辑:但是,正如Paul Renton所提到的那样,std::priority_queue不允许在没有poppinh的情况下获取单个项目,因此我使用std::vector滚动我自己的优先级队列来自std::priority_queue的灵感,默认使用std::vector。我公开我需要的内容,而不是std::priority_queue的整个API集。我不是使用整个列表,而是允许删除和插入按优先级正确排序的项目。