根据元素更改更新优先级队列顺序

时间:2019-04-29 19:50:44

标签: c++ priority-queue

我在这个问题上也发现了一些类似的问题,但我想再问一次,以获得更明确的答案。我正在编写一种图匹配算法,其中图上的每个节点都根据其邻居的匹配分配给优先级集。详细信息并不是很重要,但是我正在使用 std :: priority_queue 以便首先匹配最高优先级的节点。这是一个棘手的问题:每次引入新的匹配项时,都要更新匹配节点的邻居的优先级。

此算法引用自一篇论文,尽管我实现了完全相同的算法,但我无法达到相同的匹配百分比。我自然地怀疑 std :: priority_queue 可能无法按我希望的顺序在优先级更新时重新排序,因此我进行了一些测试,然后发现了其他问题,问同样的事情:

How to tell a std::priority_queue to refresh its ordering?

Does changing a priority queue element result in resorting the queue?

我的问题自然是,如何更新新匹配项的订单?我可以执行吗?还是可以使用其他任何数据结构(例如最大堆)?请注意,将新元素放入队列对我来说不是有效的解决方案。这是我正在使用的代码段(matchFace()函数更新元素优先级):

while (priorityQueue.size() != 0) {

    // Take the face at the top of the queue and check if it is already matched
    FaceData* currentFace = priorityQueue.top();

    // Pop the face at the top in any case
    priorityQueue.pop();

    // If the face is not already matched, try to find a matching
    if (!currentFace->matched) {

        // Try to match the face with one of its neighbors, add it to the unmatched faces list if it fails
        int neighborId = matchFace(currentFace);
        if (neighborId == -1) {
            unmatchedFaces.push_back(currentFace);
        } else {
            matchingMap[currentFace->id] = neighborId;
        }
    }
}

1 个答案:

答案 0 :(得分:0)

使用对这个问题的评论,我决定自己回答。我发现有三种可能的方法可以解决此问题:

  • 实施您自己的可更新优先级队列或使用外部库。为此,Boost可能具有一些其他数据结构。我还在这里找到了Updatable Priority Queue源代码。
  • 使用向量存储值,并在每次收到更新时使用算法库中提供的std::make_heap函数。这是最简单的方法,但是工作非常缓慢。
  • 删除并重新插入元素。如果这不是有效的方法,请使用地图存储元素ID,而不是删除元素,而在地图上标记元素,这样,如果您多次遇到它们,则可以忽略它们。另一种策略是通过添加标记并通过打开标记来标记元素来更改项目。
相关问题