c ++交叉遗传算法push_back向量覆盖旧的

时间:2015-04-19 20:34:53

标签: c++ vector push-back

我的代码有问题。我正试图做4个父母的交叉。问题是如果向量中存在相同的值,则push_back向量会覆盖高位向量。

例如,

parent 1 = 101
parent 2 = 200
parent 3 = 101
parent 4 = 302

假设交叉点为1,

1|01
2|00
1|01
3|02

孩子会

1|00
2|01
1|02
3|01

而不是让孩子上面,我得到一个不同的输出,被push_back矢量覆盖。

我得到的孩子

1|02
2|01
1|02
3|01

正如您所看到的,在完成交叉之后,父3的交叉值将被覆盖到父级1。任何帮助都非常感谢。对不起,如果我违反任何规则,我是这个论坛的新手。

代码如下:

void GA::Crossover()
{
    int i=0;
    int po=0;
    int po1=1;
    do
    {
        int point1 = 0;
        while (point1==0)
            point1=rand() % 3;

        std::ofstream log("log.txt", std::ios_base::app);
        log<<"---------------------------------"<<"\n";
        log<<"cross point: "<<point1<<std::endl;
        log.close();


        Chromosome* child1=parent.at(po);
        Chromosome* child2=parent.at(po1);

        for(int c1=0;c1<point1;c1++)
        {
            int one=parent.at(po1)->GetGene(c1);
            int two=parent.at(po)->GetGene(c1);

            child1->SetGene(c1,one);
            child2->SetAnonGene(c1,two);
        }

        /*for(int c1=2;c1>=point1;c1--)
        {
            int one=parent.at(po1)->GetGene(c1);
            int two=parent.at(po)->GetGene(c1);

            child1->SetGene(c1,one);
            child2->SetGene(c1,two);
        }*/

        Evaluate(child1);
        child.push_back(child1);
        Evaluate(child2);
        child.push_back(child2);

        po=2;
        po1=3;
        i++;
    }while(i<2);
    std::cout<<"child size:"<<child.size()<<std::endl;
    std::ofstream log("log.txt", std::ios_base::app);
    log<<"---------------------------------"<<"\n";
    log<<"Child:"<<std::endl;
    log.close();

    for(int p=0;p<(int)child.size();p++)
    {
        child.at(p)->Print();
    }
    log.open("log.txt", std::ios_base::app);
    log<<"---------------------------------"<<"\n";
    log.close();

    parent.clear();
    parent.shrink_to_fit();
}

2 个答案:

答案 0 :(得分:2)

你有一个指向对象的向量。从你给出的代码中不清楚,但是你可能会发生多个指向同一个对象的指针(使用shallow copy完成)并更新一个指针所指向的对象的值你最终会更新另一个指向的值。

建议使用vector<Chromosome>而不是vector<Chromosome*>,但这会改变您的代码在其他地方的工作方式。

旁注:可以优化以下几行:

    while (point1==0)
        point1=rand() % 3;

写作

    point1=1+(rand()%2);

答案 1 :(得分:2)

在你的代码中,孩子是指针:

Chromosome* child1=parent.at(po);

这些不是您可以随后自由修改的染色体的副本,但这些指向原始父母。所以,当你改变基因时:

child1->SetGene(c1,one);
你改变了父母!然后第二个do-while迭代适用于变异父项。这就是为什么你没有得到你期望的。

解决方案是复制孩子。有几种可能性。我没有您的类的定义,但是例如,如果Chromosome有一个复制构造函数,您可以这样做:

Chromosome* child1=new Chromosome(*parent.at(po));