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

时间:2015-11-05 14:47:38

标签: c++

我为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 ()),运行时错误显示&#34; Debug Assertion Failed!...无效的比较器&#34;。

3 个答案:

答案 0 :(得分:4)

您错过了健身检查的另一面:

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,则您不应该检查向量。

答案 1 :(得分:1)

使用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<...>数据成员并实现您需要的功能作为转发功能。

答案 2 :(得分:0)

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

这可能会在operator[]内修复,我看不到。所以我无法确定上述情况。但由于这符合描述的症状,我假设您实际上没有在operator[]

中修复它

即使对于rhs.size()>lhs.size(),代码中也存在一些问题。所以看来你假设它们的大小相同。如果是这样,请抛出assert,因此代码审核人员可能会相信。