Search code examples
c++algorithmvectorpush-back

c++ Crossover genetic algorithm push_back vector overwrites the old one


I have problem with my code. I'm trying to do a crossover of 4 parents. The problem is the push_back vector keeps overwriting the upper one if there is the same value in the vector.

For example,

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

lets say the crossover point is 1,

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

child would be

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

instead of getting the child above, I get a different output which is overwritten by the push_back vector.

child that i get

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

As you can see the value of crossover from parent 3 is overwritten to parent 1 after the crossover is done. Any help is really appreciated. Sorry if I violate any rules, I am new to this forum.

The code is below:

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();
}

Solution

  • In your code the childs are pointers:

    Chromosome* child1=parent.at(po);
    

    These are not copies of the chromosome that you can freely modify afterwards, but these point to the original parent. So when you mutate the gene:

    child1->SetGene(c1,one);
    

    you mutate the parents ! The second do-while iteration then works on mutated parents. This is why you don't get what you expect.

    The solution is to copy the childs. There are several possibilities. I don't have the definitions of your classes, but for example if Chromosome had a copy constructor you could do:

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