我想在稀疏图上实现最短路径搜索(这不是一个提升图,可能无法有效地转换为一个),因此我自然而然地坚持使用优先级队列来实现Dijkstras算法。由于我的图形是自定义的,我需要将距离比较作为函数对象实现并将其交给队列:
#include <boost/heap/fibonacci_heap.hpp>
#include <iostream>
#include <climits>
#define BIG (INT_MAX / 2)
struct node_compare {
std::vector<int> dist;
void set(int node, int d) {
dist[node] = d;
}
node_compare(int dim) : dist(dim, BIG) {};
/* this is a 'greater than' because boost implements max-heaps */
bool operator()(const int& n1, const int& n2) const {
std::cout << "Comparing " << n1 << " < " << n2 << " = " << dist[n1] << " > " << dist[n2] << std::endl;
return dist[n1] > dist[n2];
}
};
typedef boost::heap::fibonacci_heap<int, boost::heap::compare<node_compare>> priority_queue;
int main(int argc, char** argv) {
/* comparator implementation, based on distances */
node_compare cmp(5);
priority_queue pq(cmp);
cmp.set(3, 10);
for (int i = 0; i < 5; i++)
pq.push(i);
while(!pq.empty()) {
std::cout << pq.top() << std::endl;
pq.pop();
}
}
令我印象深刻的是,优先级队列似乎构建了自己的node_compare
实例,尽管我在构造函数中提供了一个实例。这甚至不可能,因为node_compare
没有默认构造函数......
我知道这看起来有点像“请为我找到那个错误” - 问题,但我真的不知道我是否错过了一些重要的C ++语义或提升逻辑。
答案 0 :(得分:1)
堆确实存储了它自己的node_compare
实例,但是没有默认构造它,但是copy会从你在构造函数中传递的对象构造它。
因此,在行priority_queue pq(cmp);
中,队列使用自动生成的cmp
类的复制构造函数来复制node_compare
对象。
如果在创建cmp.set(3, 10);
之前调用priority_queue
,则也应在队列的比较器中设置它。
我担心你在创建堆后无法更改比较器。堆对象具有value_comp()
成员函数,该函数返回对比较器的const
引用,因此您无法更改返回的比较器。我认为您无法更改比较器,因为这会使堆中的数据结构无效。
但是你可以存储比较器内距离向量的引用:
struct node_compare {
const std::vector<int> &dist_;
node_compare(const std::vector<int> &dist) : dist(dist) {};
bool operator()(const int& n1, const int& n2) const {
return dist_[n1] > dist_[n2];
}
};
您只需要小心,在向堆中添加元素后不要更改传递的距离向量。