Project 4 - Genetic Algorithms
The program should accept the following as input:
1. Initialize the population. Generate N-bit strings
each of size l. It is easier to
represent the individuals as character arrays rather than integers.
- Number of genes (bits) in the genetic string l
- Population size N
- Number of generations G
- Mutation probability pm
- Crossover probability pc
For each generation, do the following:
2. Calculate the fitness of each individual.
This can be done in several steps:
Repeat all of the above for several different runs. Do not average
over them as this will either result in loss of data for individual
runs or the average will just be a straight line. Plot all of these
runs on the same graph and/or choose one of the runs as a "typical"
run and plot it.
a. Find the integer that the individual's bit string represents.
Iterate through each bit, and if the bit is a 1, then add the
corresponding power of 2 to a running sum. For example, if l=20, and if the leftmost bit of the
string is 1, then add 219 to the sum. Use the loop
index to help you figure out which power of 2 you are on for each
iteration. After looping through all the bits, this running sum
will be the integer value of the bit string.
b. Plug the integer value from step a into the fitness function F(s)=(x/2l)10 to get that
individual's fitness value.
c. When you are looping through each individual finding the
fitness value, keep a running sum of the total fitness, which is
the sum of fitness values for all N individuals.
d. For each individual, normalize its fitness value by dividing
its fitness value by the total fitness from step c. It's best to
store these normalized values in a separate array than the actual
fitness values since you will need to keep the original fitness
values for finding the statistics in a later step.
e. For each individual, compute a number which is the sum of that
individual's normalized fitness value, and the normalized fitness
values for each of the individuals before it. Thus, a running
total is kept of the normalized fitness values. This will be
helpful later when probabilistically selecting parents.
The following example should make steps d and e more clear. Note
that the total fitness value is 1.95. Also note that the sum of
all the normalized fitness values is 1.
Individual Fitness value Normalized fitness value Running total
0 0.05 0.0256 0.0256
1 0.2 0.1026 0.1282
2 0.6 0.3077 0.4359
3 0.3 0.1538 0.5897
4 0.8 0.4103 1.0000
Now you are set up to select parents and produce the next
Perform N/2 iterations doing the following:
3. Select two individuals to be parents.
First get two random numbers between 0 and 1. Then see which
range the random numbers fall into based on the running total
numbers computed in step 2e above. The random number will be
between two of those numbers. The individual associated with the
second of those numbers will be the individual selected to be a
parent. For example, suppose your two random numbers are 0.4147
and 0.7395. In the example above, the number 0.4147 is between
0.1282 and 0.4359, so individual 2 is one of the parents. In the
above example, the number 0.7395 is between 0.5897 and 1.0000,
so individual 4 is the other parent. Be sure that you get two
distinct parents when you do this step, so that you do not
result in an individual mating with itself. Keep selecting a
second parent until you get one that is different from the first
6. Update the population. Copy all of the offspring bit
string arrays into the bit string arrays of the current
population. The new offspring will replace the current population.
In other words, the current population arrays will be overwritten
by the offspring arrays.
4. Mate parents and perform any crossover to get offspring.
a. First generate a random number to determine whether crossover
will be done.
b. If no crossover is done, then simply copy the bit strings of
the parents into new bit strings which will represent the
c. If crossover is done, then first randomly select a bit to be
the crossover point. Then copy the bit strings of the parents
into the bit strings of the offspring up to the crossover point.
After the crossover point, reverse which offspring gets the bits
from which parent.
5. Perform any mutations on the offspring. For each of
the two offspring, go through all the bits in their strings. For
each bit, generate a random number to indicate whether that bit
will be mutated. If the bit will be mutated, then simply flip
7. Find the statistics of the population. Find the average
fitness of the population, the fitness of the best individual, and
the number of correct bits in the best individual. Find these
three measures for each generation. You will use this data to make
the required graphs. You might want to store all this data in
arrays which you can then dump into a file later on.
Also repeat all of the above for several different combinations of
the five parameters given at the beginning of this document. For
each combination of parameters, do several runs as explained in the