package nl.nuggit.evolution;
import nl.nuggit.evolution.sudoku.SudokuFitness;
public class Evolution {
private static final String puzzle1 = "080402060034000910960000084000216000000000000000357000840000075026000130090701040";
private static final String puzzle2 = "080904500000000180560300947293100004000702000400003612839005061046000000002601030";
private static final String puzzle3 = "000200063300005401001003980000000090000538000030000000026300500503700008470001000";
private Pool pool;
private Fitness fitness;
public Evolution(String dna, int poolSize, Fitness fitness) {
this.pool = new Pool(poolSize, fitness);
this.pool.add(new Individual(dna));
this.pool.add(new Individual(dna));
this.fitness = fitness;
}
public static void main(String[] args) {
Evolution evolution = new Evolution(puzzle1, 10, new SudokuFitness());
evolution.evolve(10);
System.out.println(evolution.pool);
}
private void evolve(int generations) {
for (int g = 1; g < generations; g++) {
breed(pool, fitness);
}
}
private void breed(Pool pool, Fitness fitness) {
Individual individual1 = pickRandomIndividualButNot(pool, null);
Individual individual2 = pickRandomIndividualButNot(pool, individual1);
crossover(individual1, individual2);
}
private void crossover(Individual individual1, Individual individual2) {
int startIndex = (int) (Math.random() * individual1.getDna().length() - 1);
int endIndex = startIndex + (int) (Math.random() * (individual1.getDna().length() - startIndex - 1)) + 1;
System.out.println(String.format("startIndex=%s, endIndex=%s", startIndex, endIndex));
String dna1 = individual1.getDna();
String dna2 = individual2.getDna();
String a1 = dna1.substring(0, startIndex);
String b1 = dna1.substring(startIndex, endIndex);
String c1 = dna1.substring(endIndex);
String a2 = dna2.substring(0, startIndex);
String b2 = dna2.substring(startIndex, endIndex);
String c2 = dna2.substring(endIndex);
dna1 = a1 + b2 + c1;
dna2 = a2 + b1 + c2;
pool.add(new Individual(dna1));
pool.add(new Individual(dna2));
}
private Individual pickRandomIndividualButNot(Pool pool, Individual toBeSkipped) {
int index = (int) (Math.random() * pool.getIndividuals().size());
if (toBeSkipped != null && pool.getIndividuals().contains(toBeSkipped)) {
index--;
}
for (Individual individual : pool.getIndividuals()) {
if (individual == toBeSkipped) {
continue;
}
index--;
if (index <= 0) {
return individual;
}
}
return toBeSkipped;
}
}