c++ - 使用自定义值比较器 boost 最小队列

标签 c++ boost heap

我想在稀疏图上实现最短路径搜索(它不是 boost 图,可能无法有效地转换成 boost 图),所以我很自然地坚持使用优先级队列实现 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 没有默认构造函数...

我知道这看起来有点像“请帮我找出那个 bug”之类的问题,但我真的不知道我是否错过了一些重要的 C++ 语义或 boost 逻辑。

最佳答案

堆确实存储了它自己的 node_compare 实例,但不会默认构造它,而是从您在构造函数中传递的对象复制构造它。

因此在 priority_queue pq(cmp); 行中,队列使用 node_compare 类的自动生成的复制构造函数复制 cmp 对象.

如果您在创建 priority_queue 之前调用 cmp.set(3, 10);,它也应该设置在队列的比较器中。

恐怕一旦创建堆就无法更改比较器。堆对象有一个 value_comp() 成员函数,它返回对比较器的 const 引用,因此您不能更改返回的比较器。我认为您不能更改比较器,因为这会使堆中的数据结构无效。

但是您可以在比较器中存储对距离 vector 的引用:

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];
    }
};

您只需要小心,不要在向堆中添加元素后更改传递的距离 vector 。

关于c++ - 使用自定义值比较器 boost 最小队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21455984/

相关文章:

c++ - 用实际元素初始化 boost::multi_array 的干净方法

c++ - 在 boost::heap::priority_queue 中推送结构对象时出错

algorithm - 堆排序运行时间

c++ - 如何将句柄添加为类成员,其中类用于堆模板?

c++ - 输出 cout 是感叹号。 C++

c++ - 无法理解 Qt 中的撤消重做框架

c++ - boost 线程移动分配与移动构造函数

c++ - 对 Boost::uBLAS vector 执行 STL 操作

c++ - 从编译的可执行文件中执行函数

c++ - 计算 VST 的三角波表