1

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();
}
Christophe
  • 68,716
  • 7
  • 72
  • 138

2 Answers2

2

You have a vector of pointers to objects. It is not clear from the code you've given but it might be happening that you have multiple pointers to the same object (done using a shallow copy) and by updating the value of an object pointed to by one pointer you end up updating the value pointed to by another.

A suggestion would be to use a vector<Chromosome> rather than vector<Chromosome*> but that would change how your code works at other places as well.

On a side note: the following lines can be optimized:

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

by writing

    point1=1+(rand()%2);
Community
  • 1
  • 1
Jay Bosamiya
  • 3,011
  • 2
  • 14
  • 33
  • Thanks man for this comment. I have read through, understand it and manage to sort out the problem. Much appreciate. Really helpful – Alphs Alphonse Apr 20 '15 at 08:09
2

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));
Christophe
  • 68,716
  • 7
  • 72
  • 138
  • Thanks for this information. By reading yours and @JayBosamiya comment I have fully understand what my problem is about. I'm currently writing code for my final year school project thesis which is about procedural content generation on RPG maps. The idea is to use the Genetic Algorithm to tune out the Cellular Automata parameters then will generate the cave like layout. Really appreciate on both of your comments. Although I'm not very good with programming and the styles. – Alphs Alphonse Apr 20 '15 at 08:08