/** * Mutates the classifier. It mutates the action and the condition. * * @param envState is the current environtment state. It is necessary for the niched mutation. * @return a boolean indicating if the action has been mutated. */ public boolean mutate(double[] envState) { int i; // First, the condition is mutated for (i = 0; i < rep.length; i++) { rep[i].mutate(envState[i]); } // Second, the action is mutated int act = 0; if (Config.rand() < Config.pM) { do { act = (int) (Config.rand() * (double) Config.numberOfActions); } while (action == act); action = act; return true; } return false; } // end mutate
/** * Applies crossover. It generates two children. * * @param parent1 is the first parent. * @param parent2 is the second parent * @param child1 is the first child * @param child2 is the second child. */ public void makeCrossover( Classifier parent1, Classifier parent2, Classifier child1, Classifier child2) { int i = 0; // cross1 is a number between [0.. clLength-1] int cross1 = (int) (Config.rand() * (double) Config.clLength); // cross2 is a number between [1..clLenght]. int cross2 = (int) (Config.rand() * (double) Config.clLength) + 1; if (cross1 > cross2) { int aux = cross2; cross2 = cross1; cross1 = aux; // In the else-if condition is not necessary to check if (cross2<clLength) // to increment the point, because cross1 [0..length-1] } else if (cross1 == cross2) cross2++; // All the intervals (real representation) or genes (ternary representation) that // are not in the cross point are crossed. if (!Config.ternaryRep) { for (i = cross1 + 1; i < cross2 - 1; i++) { child2.setAllele(i, parent1); child1.setAllele(i, parent2); } // Now we have to cross the border allele child1.crossAllele(cross1, parent1, parent2); child1.crossAllele(cross2 - 1, parent2, parent1); child2.crossAllele(cross1, parent2, parent1); child2.crossAllele(cross2 - 1, parent1, parent2); } else { for (i = cross1; i < cross2 - 1; i++) { child2.setAllele(i, parent1); child1.setAllele(i, parent2); } } } // end makeCrossover
/** * It crosses a real allele within two parents. If the representation is a ternary representation, * a crossover within intervals is not possible because there is only one gene in each position. * So, in this case, the gene of the second parent will be copied. In case of being a real * representation, a random number is generated to decide where to cross the interval. It it's * crossed within the inteval, the crossAllele method will do it. * * @param parent1 is the first parent classifier. * @param parent2 is the second parent classifier. */ public void crossAllele(int i, Classifier parent1, Classifier parent2) { if (Config.ternaryRep) { rep[i].setAllele(parent2.rep[i]); } else { if (Config.typeOfAttributes[i].equals("ternary")) { rep[i].setAllele(parent2.rep[i]); } else { if (Config.rand() < 0.5) rep[i].setAllele(parent2.rep[i]); else { // The alleles has to be crossed rep[i].setAllele(parent1.rep[i].getLowerAllele(), parent2.rep[i].getUpperAllele()); rep[i].verifyInterval(); } } } } // end crossAllele
/** * It constructs a classifier with the condition and the action specified. It's used by the * covering operator. * * <p> * * @param condition is the environtment state * @param action is the action chosen * @param size is the size of the set. * @param tStamp is the time */ public Classifier(double[] envState, int classOfExample, int size, int tStamp) { int i = 0; rep = new Attribute[Config.clLength]; if (Config.ternaryRep) { for (i = 0; i < rep.length; i++) rep[i] = new TernaryRep(envState[i]); } else { for (i = 0; i < rep.length; i++) { if (Config.typeOfAttributes[i].equals("ternary")) rep[i] = new TernaryRep(envState[i]); else { if (envState[i] == Config.unknownValue) rep[i] = new RealRep(Config.rand()); else rep[i] = new RealRep(envState[i]); } } } action = classOfExample; parameters = new Parameters(tStamp, size, getGenerality()); } // end Classifier