I'm writing a decryption algorithm using GA with crossover and mutation. My performance is (very) poor, often stagnating early or converging to the incorrect solution. I just want some other people to look at my crossover and mutation methods to see if something is amiss.
Note: crossRate
and mutatRate
are the crossover and mutation rates respectively and are within the range of [0.00, 1.00]
. options
is a string of valid genes.
/**
* method to perform crossover on chromosome
* @param m - the first parent
* @param f - the second parent
* @return - a crossovered chromosome string
*/
private String crossChromosome(String m, String f) {
StringBuilder chrString = new StringBuilder();
// if crossover procs
if (rnd.nextInt(100) < crossRate*100) {
/**
* to avoid full reduplication of chromosome
* set the bound to 2..len-2 otherwise you could
* get duplication of parent, bypassing crossover entirely
*/
int crossPoint = rnd.nextInt(m.length()-2)+2;
// when 2P is used, need a second pivot
int nextCrossPoint = rnd.nextInt(m.length()-crossPoint)+crossPoint;
boolean condition;
for (int i = 0; i < f.length(); i++) { // for each gene
if (crType == 1) {
/**
* if one point crossover, find one point
* in the chromosome where genes before that
* point are from parent1 and after, from parent2
*/
condition = (i < crossPoint);
} else {
/**
* if two point, however, find two pivot points
* and go F,M,F based on the pivot points
*/
condition = (i < crossPoint || i >= nextCrossPoint);
}
if (condition) {
chrString.append(f.charAt(i));
} else {
chrString.append(m.charAt(i));
}
}
} else {
// if no crossover is happening, random parent is used
return (rnd.nextInt(2) == 1) ? f : m;
}
// return the crossovered chromosome
return chrString.toString();
}
/**
* method to mutate a chromosome with random genes
* @param k - the input chromosome
* @return - the mutated chromosome
*/
private String mutateChromosome(String k) {
StringBuilder chrString = new StringBuilder();
for (int i = 0; i < k.length(); i++) { // for each gene
// if mutation procs
if (rnd.nextInt(100) < mutatRate*100) {
// assign a random gene as mutation
chrString.append(options.charAt(rnd.nextInt(27)));
} else {
// otherwise, use verbatim
chrString.append(k.charAt(i));
}
}
return chrString.toString();
}
There's option of 1-point and 2-point crossover in there.