C++ STL make_heap 和priority_queue 给出不同的输出

标签 c++ stl floating-point priority-queue

这是我的代码:

std::priority_queue<SimpleCycle,
                    std::vector<SimpleCycle>,
                    SimpleCycle> pq;
pq.push(cycle1);
pq.push(cycle2);
pq.push(cycle4);
std::cout << pq.top().to_string() << std::endl;

std::vector<SimpleCycle> pq2{ cycle1, cycle2, cycle4 };
std::make_heap(pq2.begin(), pq2.end(), SimpleCycle());
std::cout << pq2.front().to_string() << std::endl;

SimpleCycle 的比较器如下:

const bool SimpleCycle::operator()(SimpleCycle& L, SimpleCycle& R) const
{
    float a = L.avg_latency();
    float b = R.avg_latency();
    //Allow an error rate of 0.0000000001
    //Ref. The Art of Computer Programming: Seminumerical algorithms(Page 128)
    return (b - a) > ((fabs(a) < fabs(b) 
                    ? fabs(b) : fabs(a)) * (0.0000000001));
}

函数avg_latency()返回一个float。但对于相同的输入情况,我得到不同的输出。可能出了什么问题?

最佳答案

由于您的比较运算符“允许错误率为 0.0000000001”,因此它不是 C++ 概念定义的严格弱排序(例如 http://en.cppreference.com/w/cpp/concept/Compare )。

特别是,不满足严格弱序的对称性要求。例如。如果我们将 e 称为错误阈值(在您的情况下为 0.0000000001),我们会看到:

  • SimpleCycle()(1/e, 1/e + 1) 返回 false
  • SimpleCycle()(1/e + 1, 1/e) 返回 false

Igor Tandenik 在评论中指出的另一个问题是,它引发的等价关系不是传递性的:有可能 a 足够接近 b,b 足够接近 c,但 a 不够接近到 c。

根据 cycle 变量中的数据,这可能会导致 priority_queuemake_heap 方法返回的最大元素略有不同

游戏中也可能存在舍入错误...

关于C++ STL make_heap 和priority_queue 给出不同的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39474631/

相关文章:

c++ - 对于采用可复制和可移动类的访问者,应该有多少重载?

c++ - 有关简单C++函数的逻辑的问题(is_palindrome)

c++ - OpenGL 谷歌地图样式 2D 相机/缩放到鼠标光标

c++ - 在 vector 中查找 NULL

c++ - 为什么 C++ lower_bound() 允许返回等于 val 的指针而 upper_bound() 不允许

c++ - 1.5后 float 显示0号

python - 提取 float 的小数部分

c++ - 添加具有运算符重载的 2x2 矩阵

c++ - STL::sets的STL::map的效率

math - float 学坏了吗?