【发布时间】:2019-09-18 11:10:25
【问题描述】:
我发现了一些关于这个主题的类似问题,但我想再次询问以获得更明确的答案。我正在编写一个图匹配算法,其中图上的每个节点根据其邻居的匹配分配给一个优先级集。细节并不重要,但我使用 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;
}
}
}
【问题讨论】:
-
能否从队列中移除受影响的元素,更改它们,然后重新添加?
-
好吧,没关系,使用 std::priority_queue 是不可能的。你可能不得不自己写这个。在这种情况下,priority_queue 可能不是该工作的正确工具。您能解释一下您要解决的更广泛的问题吗?
-
也许我可以使用节点 ID 进行迭代搜索,但效率非常低。我试图在对偶图上找到最大匹配,其中每个节点都分配给从 0 到 3 的优先级。当节点匹配时,应更新其邻居的优先级,以便具有最高优先级的节点将是首先匹配。这样,空闲邻居数量较少的节点将优先匹配。
-
Boost 的
binomial_heap允许您更新元素并在队列中重新排序。 -
我最近遇到了类似的问题,我最终做的是从 priority_queue 继承(这里通常是“没有用户可维修的部件”警告)。我在基础集合上添加了一个名为 std::make_heap() 的公共方法(在我的例子中是一个 std::vector )。当其他元素的优先级发生变化时,我调用了这个方法。它不漂亮,但它适用于我的情况。
标签: c++ priority-queue