C++中的严格弱排序运算符

Strict weak ordering operator in C++

本文关键字:排序 运算符 C++      更新时间:2023-10-16

我正在为TPS编写遗传算法。我有一个类染色体,它是从std::vector派生而来的,并且作为成员具有适合性。我想对染色体群体进行分类。IMO我的操作员<是"严格弱序"关系。然而,MVS却不以为然。这是操作员的代码:

bool Chromosome::operator<(const Chromosome & rhs) const
{
    const Chromosome& lhs = *this;
    if (lhs.fitness < rhs.fitness)
        return true;
    else
    {
        unsigned int size = lhs.size();
        unsigned int zeroCityIndexlhs = std::find(lhs.begin(), lhs.end(), 0) - lhs.begin();
        unsigned int zeroCityIndexrhs = std::find(rhs.begin(), rhs.end(), 0) - rhs.begin();
        for (unsigned int i = 1; i < size; i++)
        {
            if (lhs[(zeroCityIndexlhs + i) % size] < rhs[(zeroCityIndexrhs + i) % size])
                return true;
            else if (lhs[(zeroCityIndexlhs + i) % size] == rhs[(zeroCityIndexrhs + i) % size])
                continue;
            else
                return false;
        }
        return false;
    }
}

染色体A小于染色体B,当它具有较小的适应度或相同的适应度,并且从城市0开始的道路在字典上小于B中的道路时。程序编译,但当涉及排序时(使用std::sort()),运行时错误显示为"调试断言失败!…无效比较器"。

您错过了适合性检查的另一面:

bool Chromosome::operator<(const Chromosome & rhs) const
{
    const Chromosome& lhs = *this;
    if (lhs.fitness < rhs.fitness)
        return true;
    else if (rhs.fitness < lhs.fitness)
        return false; // <== this!

否则,如果是lhs.fitness > rhs.fitness,则在检查向量,而不应该检查向量。

使用std::tuple:

bool Chromosome::operator<(const Chromosome & rhs) const
{
    // Fill in the ... here.
    using base_type = std::vector<...>;
    return std::tie(fitness, static_cast<base_type const&>(*this)) <
        std::tie(rhs.fitness, static_cast<base_type const&>(rhs));
}

旁注:从std::vector<...>继承是非常可怕的。使用std::vector<...>数据成员并实现所需的转发功能。

rhs.size()<lhs.size()时,您的比较函数看起来严重错误。(不仅是一个糟糕的比较规则,还有未定义的行为)。

这可能是在你的operator[]内部修复的,我看不到。所以我不能肯定以上这些。但由于这符合所描述的症状,我假设你实际上没有在operator[] 中修复它

即使对于rhs.size()>lhs.size(),您的代码中也存在一些非常可疑的内容。所以你似乎在假设它们的大小是一样的。如果是这样的话,那么就加入一个assert,这样代码评审人员可能会相信这一点。