import java.util.Random; public class GAIndividual { private static Random randg = new Random(); // Random Generator // What if we choose a static random generator? // A unique random generator for all individuals!? public int genome_size; public float[] genome; public float fitness; public GAIndividual(int gsize,float[] min_range,float[] max_range){ // Create a random individual of size gsize // i'th gene must be in range min_range[i] to max_range[i] genome_size = gsize; genome = new float[genome_size]; for(int i=0; i < genome_size; i++){ genome[i] = randg.nextFloat() * (max_range[i] - min_range[i]) + min_range[i]; } evalFitness(); // evaluate fitness of this new individual } public GAIndividual(float d[]){ // Create an individual that its genome is same as d[] // It is assumed min_range[i] <= d[i] <= max_range[i] genome_size = d.length; genome = new float[genome_size]; for(int i=0; i < genome_size; i++){ genome[i] = d[i]; } evalFitness(); // evaluate fitness of this new individual } public GAIndividual mutate(float[] min_range,float[] max_range){ // rate is the chance of each gene to be mutated // it is a good choice to set rate to 1/genome_size float rate = 1.0f / (float) genome_size; float[] result = new float[genome_size]; for(int i=0; i < genome_size; i++) result[i] = genome[i]; if( randg.nextBoolean() ){ // apply normal mutation for(int i=0; i < genome_size; i++) if( (float)Math.random() < rate) result[i] = randg.nextFloat() * (max_range[i] - min_range[i]) + min_range[i]; }else{ // apply creep mutation for(int i=0; i < genome_size; i++) if( (float)Math.random() < rate) result[i] = result[i] + randg.nextFloat() * .2f - .1f; } return new GAIndividual(result); } public GAIndividual xover1p(GAIndividual m){ // 1-point cross over int xpoint = 1 + randg.nextInt(genome_size - 1); float[] child = new float[genome_size]; for(int i=0; i < xpoint; i++){ child[i] = genome[i]; } for(int i=xpoint; i < genome_size; i++){ child[i] = m.genome[i]; } return new GAIndividual(child); } public static GAIndividual xover1p(GAIndividual f,GAIndividual m){ // 1-point cross over Random rng = new Random(); int xpoint = 1 + rng.nextInt(f.genome_size - 1); float[] child = new float[f.genome_size]; for(int i=0; i < xpoint; i++){ child[i] = f.genome[i]; } for(int i=xpoint; i < f.genome_size; i++){ child[i] = m.genome[i]; } return new GAIndividual(child); } public String toString(){ String s = "["; for(int i=0; i < genome_size - 1; i++){ s+= genome[i]+", "; } s+=genome[genome_size - 1] + "]"; s+=" fitness = "+fitness; s+=" function value = "+ (1.0f / fitness - 1.0); return s; } private void evalFitness(){ // greater fitness means better individual // De Jong's F1: // fitness = 1.0f / (1.0f + genome[0]*genome[0] + genome[1]*genome[1] + genome[2]*genome[2] ); // De Jong's F2: // fitness = 1.0f / (1.0f + 100.0f*(genome[0]*genome[0]-genome[1])*(genome[0]*genome[0]-genome[1]) + (1.0f - genome[0])*(1.0f - genome[0]) ); // Schaffer F6: // float tmp0 = genome[0]*genome[0] + genome[1]*genome[1]; // float tmp1 = (float) Math.sin(Math.sqrt(tmp0)); // float tmp2 = 1.0f + .001f*tmp0; // fitness = 1.0f / (1.0f + .5f + (tmp1*tmp1 -.5f) / (tmp2*tmp2)); // Ackey F1 (5 Dimentional): // float tmp0 = genome[0]*genome[0] + genome[1]*genome[1] + genome[2]*genome[2] + genome[3]*genome[3] + genome[4]*genome[4]; // float tmp1 = (float)(Math.cos(2*Math.PI*genome[0]) + Math.cos(2*Math.PI*genome[1]) + Math.cos(2*Math.PI*genome[2]) + Math.cos(2*Math.PI*genome[3]) + Math.cos(2*Math.PI*genome[4]) ); // fitness = 1.0f / (1.0f + 20.0f + (float)(Math.exp(1) - 20*Math.exp(-.2*Math.sqrt(tmp0/5.0f)) - Math.exp(tmp1/5.0f))); // Rastrigin F1 (10 Dimentional) float sum = 100; for(int i=0; i < genome_size; i++) sum = sum + genome[i]*genome[i] - (float)(10.0*Math.cos(2*Math.PI*genome[i])); fitness = 1.0f / (1.0f + sum); } public static void main(String[] args) { } }