Population becomes obsolete - Genetic Algorithm

I am building a simple "Hello, World!" genetic algorithm for learning. My population is a bunch of random strings. Through mutation and crossover, the strings become "Hello, World!" For some reason, my population will sit at a fitness score and never seem to develop. In other cases, my population will reach the target genes "Hello World". I am using random selection and single point crossover. Although, this also happens when I use the tournament and roulette selection.

Q:
Why is my population becoming obsolete and not reaching the target genes, even though I am diversifying the population through mutation? Is it due to the random nature of the genetic algorithm or a bug in my code?

For example
Each chromosome in a population will have the "HellV, Wor`dL" genes. Even after 10,000 generations, the genes are the same. In other cases, the genes reach the target genes "Hello world!" after ~ 33 generations.

  • Note: The code below works as expected when using Java. When using Java, the population always reaches the target genes. Also, I just started learning C ++ today, so it is very possible that there is a flaw in my code that I simply cannot see.

Population Size: 333
Elitism: True
Elitism Percentage: 25%
Probability of mutation: 20%
Probability of crossover: 95%
Type of allocation: Random
Type of crossover: one point

EDIT: I removed the code from this post and added a link to my github instead due to the fact that it is a few hundred lines of code.

Genetic Algorithm - C ++

+3


source to share


1 answer


Thanks to @molbdnilo's comment I was able to solve my problem.

It turns out that it is precisely because of the way C ++ copies objects, which explains why this code worked in Java and not C ++.

As @molbdnilo pointed out:

One of the most common problems when moving from Java to C ++ is how C ++ copies objects at the places where Java passes a reference.

To fix my problem, I change the following method declarations:



1. int calculateFitness(GAChromosome chromosome);

---> int calculateFitness(GAChromosome const &chromosome);


In this method declaration I tell the compiler that I want to pass the chromosome by reference, not by value using &, and make it a constant using const. This prevents the chromosome from being copied and changed.

2. void mutate(GAChromosome chromosome);

---> void mutate(GAChromosome &chromosome);


In this method declaration, I tell the compiler that I want to pass the chromosome by reference, not by value, using &. This prevents the chromosome from being copied. Since the previous method declaration did not indicate that the chromosome was passed by reference, a copy was made, modified, and then discarded after the method reached the end of the region. Ultimately, no changes were made.

3. std::pair<GAChromosome, GAChromosome> onePointCrossover(GAChromosome chromosomeA, GAChromosome chromosomeB);

---> std::pair<GAChromosome, GAChromosome> onePointCrossover(GAChromosome const &chromosomeA, GAChromosome const &chromosomeB);


In this method declaration, I tell the compiler that I want to pass the chromosome by reference, not by value, using &, and make it a constant using const. This prevents the chromosome from being copied and changed.

In conclusion, the problem relates to how the chromosome was passed on to the mutant method. The chromosome was passed on by value, not by reference, causing the chromosome to be copied and changes thrown out when the mutant's method reached the end of the region.

+1


source







All Articles