import java.util.Random; public class ESIndividual implements Comparable{ public int num_obj_vars; // number of object variables public float[] obj_var; // object variables array public float[] std_dev; // standard deviations array public float[] theta; // angles corresponding to covariances public float fitness; // fitness of this individual private static Random randg = new Random(); // Random Generator public ESIndividual(int size,float[] min_range,float[] max_range){ // Creates a random individual // i'th obj_var must be in range min_range[i] to max_range[i] num_obj_vars = size; obj_var = new float[num_obj_vars]; std_dev = new float[num_obj_vars]; theta = new float[num_obj_vars*(num_obj_vars+1)/2]; for(int i=0; i < num_obj_vars; i++){ obj_var[i] = randg.nextFloat() * (max_range[i] - min_range[i]) + min_range[i]; std_dev[i] = randg.nextFloat(); } for(int i=0; i < theta.length; i++) theta[i] = randg.nextFloat() * .2f - .1f; evalFitness(); // evaluate fitness of this new individual } public ESIndividual(float[] obj_var,float[] std_dev,float[] theta){ // Create an individual that its obj_var is exactly a copy of d[] // It is assumed min_range[i] <= obj_var[i] <= max_range[i] num_obj_vars = obj_var.length; this.obj_var = new float[num_obj_vars]; this.std_dev = new float[num_obj_vars]; this.theta = new float[num_obj_vars*(num_obj_vars+1)/2]; for(int i=0; i < num_obj_vars; i++){ this.obj_var[i] = obj_var[i]; this.std_dev[i] = std_dev[i]; } for(int i=0; i < theta.length; i++) this.theta[i] = theta[i]; evalFitness(); // evaluate fitness of this new individual } public ESIndividual mutate(float[] min_range,float[] max_range){ float beta = 0.0873f; float tau = 1.0f/ (float)(Math.sqrt(2*Math.sqrt(num_obj_vars))); float taup = 1.0f / (float)(Math.sqrt(2*num_obj_vars)); float[] new_obj_var = new float[num_obj_vars]; float[] delta_obj_var = new float[num_obj_vars]; float[] new_std_dev = new float[num_obj_vars]; float[] new_theta = new float[num_obj_vars*(num_obj_vars+1)/2]; for(int i=0; i < num_obj_vars; i++) new_obj_var[i] = obj_var[i]; float r = (float) randg.nextGaussian(); for(int i=0; i < num_obj_vars; i++){ float s = (float) randg.nextGaussian(); new_std_dev[i] = std_dev[i] * (float) Math.exp(taup*r + tau*s); } for(int i=0; i < new_theta.length; i++){ float s = (float) randg.nextGaussian(); new_theta[i] = theta[i] + beta*s; } for(int i=0; i < num_obj_vars; i++) delta_obj_var[i] = new_std_dev[i] * (float) randg.nextGaussian(); int k = num_obj_vars*(num_obj_vars+1)/2 - 1; for(int i = num_obj_vars - 1; i >= 0; i--){ for(int j = num_obj_vars - 1; j >= i; j--){ delta_obj_var[i] = delta_obj_var[i] * (float) Math.cos(theta[k]) - delta_obj_var[j] * (float) Math.sin(theta[k]); delta_obj_var[j] = delta_obj_var[i] * (float) Math.sin(theta[k]) + delta_obj_var[j] * (float) Math.cos(theta[k]); k--; } } for(int i=0; i < num_obj_vars; i++){ new_obj_var[i] = delta_obj_var[i] + obj_var[i]; new_obj_var[i] = Math.max(min_range[i],Math.min(new_obj_var[i],max_range[i])); } return new ESIndividual(new_obj_var,new_std_dev,new_theta); } public static ESIndividual xover(ESIndividual p1,ESIndividual p2){ if( p1.num_obj_vars != p2.num_obj_vars ){ System.err.println("error: for cross over the two parent must be of the same size"); return null; } float[] new_obj_var = new float[p1.num_obj_vars]; float[] new_std_dev = new float[p1.num_obj_vars]; float[] new_theta = new float[p1.num_obj_vars*(p1.num_obj_vars+1)/2]; for(int i=0; i < p1.num_obj_vars; i++) new_obj_var[i] = p1.obj_var[i] + randg.nextFloat() * (p2.obj_var[i] - p1.obj_var[i]); for(int i=0; i < p1.num_obj_vars; i++) new_std_dev[i] = p1.std_dev[i] + randg.nextFloat() * (p2.std_dev[i] - p1.std_dev[i]); for(int i=0; i < new_theta.length; i++) new_theta[i] = p1.theta[i] + randg.nextFloat() * (p2.theta[i] - p1.theta[i]); return new ESIndividual(new_obj_var,new_std_dev,new_theta); } private void evalFitness(){ // De Jong's F1: // fitness = 1.0f / (1.0f + obj_var[0]*obj_var[0] + obj_var[1]*obj_var[1] + obj_var[2]*obj_var[2] ); // De Jong's F2: // fitness = 1.0f / (1.0f + 100.0f*(obj_var[0]*obj_var[0]-obj_var[1])*(obj_var[0]*obj_var[0]-obj_var[1]) + (1.0f - obj_var[0])*(1.0f - obj_var[0]) ); // Schaffer F6: // float tmp0 = obj_var[0]*obj_var[0] + obj_var[1]*obj_var[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 = obj_var[0]*obj_var[0] + obj_var[1]*obj_var[1] + obj_var[2]*obj_var[2] + obj_var[3]*obj_var[3] + obj_var[4]*obj_var[4]; float tmp1 = (float)(Math.cos(2*Math.PI*obj_var[0]) + Math.cos(2*Math.PI*obj_var[1]) + Math.cos(2*Math.PI*obj_var[2]) + Math.cos(2*Math.PI*obj_var[3]) + Math.cos(2*Math.PI*obj_var[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 < num_obj_vars; i++) // sum = sum + obj_var[i]*obj_var[i] - (float)(10.0*Math.cos(2*Math.PI*obj_var[i])); // fitness = 1.0f / (1.0f + sum); } public int compareTo(Object o){ ESIndividual esi = (ESIndividual) o; int result; if( fitness > esi.fitness ) result = 1; else if( fitness == esi.fitness ) result = 0; else result = -1; return result; } public String toString(){ String s = "["; for(int i=0; i < num_obj_vars - 1; i++){ s+= obj_var[i]+", "; } s+=obj_var[num_obj_vars - 1] + "]"; s+=" fitness = "+fitness; s+=" function value = "+ (1.0f / fitness - 1.0); return s; } public static void main(String[] args) { } }