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

C++ Priority Queue - Reorder based on updated priorities

本文关键字:优先级 新排序 排序 队列 -根 更新 C++      更新时间:2023-10-16

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

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

我想做的是这样的事情:

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

最好的办法是什么?我应该创建自己的自定义优先级队列类吗?或者可能从std::priority_queue扩展?

谢谢!

一个选项可以允许您的AsyncJob处于"已取消"状态,只需在取消旧的优先级后,每次修改优先级时向PQ添加一个新的(副本(AsyncJob即可。

和许多事情一样,我认为"最佳方式"是高度主观的,因为它取决于你的约束程度,以及你如何量化"最佳"。就我个人而言,如果可能的话,我喜欢避免从标准库类型派生和重新发明容器结构。

二进制搜索树似乎是一个不错的选择。

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

如果你不知道以前的优先级,当你想更改它时,你需要一种方法来查找它——也许是一个对象到优先级的哈希表。

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


对于C++:

如果优先级是唯一的,则对对象具有优先级的map可以工作,否则是set < pair >,其中对中的第一个元素是优先级,第二个元素是对象(是的,我知道,这些不一定是BST(。

对于哈希表,可以使用对象到优先级的unordered_map,或者简单地使用C++11之前的map

删除更改优先级的项,然后添加它(或者添加一个副本,如果新优先级在逻辑上意味着新项(可能是最简单的方法。毕竟,您不想从头开始对整个队列进行重新排序,只需对单个更改的项进行删除和插入即可。

编辑:然而,正如Paul Renton所提到的,std::priority_queue不允许在没有poppinh头部的情况下获得单个项目,所以我会从默认使用std::vectorstd::priority_queue中获得灵感,使用std::vector滚动我自己的优先级队列。我将公开我需要的内容,而不是std::priority_queue的整个API集合。我不允许使用整个列表,而是允许删除和插入按优先级正确排序的项目。