I am attempting to write a Genetic Algorithm based on techniques I had picked up from the book \"AI Techniques for Game Programmers\" that uses a binary encoding and fitness
The following is a complete outline of the GA. I made sure to be very detailed so it can be easily coded to C/Java/Python/..
/* 1. Init population */
POP_SIZE = number of individuals in the population
pop = newPop = []
for i=1 to POP_SIZE {
pop.add( getRandomIndividual() )
}
/* 2. evaluate current population */
totalFitness = 0
for i=1 to POP_SIZE {
fitness = pop[i].evaluate()
totalFitness += fitness
}
while not end_condition (best fitness, #iterations, no improvement...)
{
// build new population
// optional: Elitism: copy best K from current pop to newPop
while newPop.size()0; idx++) {
rnd -= pop[idx].fitness
}
indiv1 = pop[idx-1]
// select 2nd individual
rnd = getRandomDouble([0,1]) * totalFitness
for(idx=0; idx0; idx++) {
rnd -= pop[idx].fitness
}
indiv2 = pop[idx-1]
/* 4. crossover */
indiv1, indiv2 = crossover(indiv1, indiv2)
/* 5. mutation */
indiv1.mutate()
indiv2.mutate()
// add to new population
newPop.add(indiv1)
newPop.add(indiv2)
}
pop = newPop
newPop = []
/* re-evaluate current population */
totalFitness = 0
for i=1 to POP_SIZE {
fitness = pop[i].evaluate()
totalFitness += fitness
}
}
// return best genome
bestIndividual = pop.bestIndiv() // max/min fitness indiv
Note that currently you're missing a fitness function (depends on the domain). The crossover would be a simple one point crossover (since you are using a binary representation). Mutation could be a simple flip of a bit at random.
EDIT: I have implemented the above pseudocode in Java taking into consideration your current code structure and notations (keep in mind i am more of a c/c++ guy than java). Note this is in no way the most efficient or complete implementation, I admit I wrote it rather quickly:
Individual.java
import java.util.Random;
public class Individual
{
public static final int SIZE = 500;
private int[] genes = new int[SIZE];
private int fitnessValue;
public Individual() {}
public int getFitnessValue() {
return fitnessValue;
}
public void setFitnessValue(int fitnessValue) {
this.fitnessValue = fitnessValue;
}
public int getGene(int index) {
return genes[index];
}
public void setGene(int index, int gene) {
this.genes[index] = gene;
}
public void randGenes() {
Random rand = new Random();
for(int i=0; i
Population.java
import java.util.Random;
public class Population
{
final static int ELITISM_K = 5;
final static int POP_SIZE = 200 + ELITISM_K; // population size
final static int MAX_ITER = 2000; // max number of iterations
final static double MUTATION_RATE = 0.05; // probability of mutation
final static double CROSSOVER_RATE = 0.7; // probability of crossover
private static Random m_rand = new Random(); // random-number generator
private Individual[] m_population;
private double totalFitness;
public Population() {
m_population = new Individual[POP_SIZE];
// init population
for (int i = 0; i < POP_SIZE; i++) {
m_population[i] = new Individual();
m_population[i].randGenes();
}
// evaluate current population
this.evaluate();
}
public void setPopulation(Individual[] newPop) {
// this.m_population = newPop;
System.arraycopy(newPop, 0, this.m_population, 0, POP_SIZE);
}
public Individual[] getPopulation() {
return this.m_population;
}
public double evaluate() {
this.totalFitness = 0.0;
for (int i = 0; i < POP_SIZE; i++) {
this.totalFitness += m_population[i].evaluate();
}
return this.totalFitness;
}
public Individual rouletteWheelSelection() {
double randNum = m_rand.nextDouble() * this.totalFitness;
int idx;
for (idx=0; idx0; ++idx) {
randNum -= m_population[idx].getFitnessValue();
}
return m_population[idx-1];
}
public Individual findBestIndividual() {
int idxMax = 0, idxMin = 0;
double currentMax = 0.0;
double currentMin = 1.0;
double currentVal;
for (int idx=0; idx currentMax) {
currentMax = currentVal;
idxMax = idx;
}
if (currentVal < currentMin) {
currentMin = currentVal;
idxMin = idx;
}
}
//return m_population[idxMin]; // minimization
return m_population[idxMax]; // maximization
}
public static Individual[] crossover(Individual indiv1,Individual indiv2) {
Individual[] newIndiv = new Individual[2];
newIndiv[0] = new Individual();
newIndiv[1] = new Individual();
int randPoint = m_rand.nextInt(Individual.SIZE);
int i;
for (i=0; i