Created
March 17, 2014 18:38
-
-
Save jirkapenzes/9605522 to your computer and use it in GitHub Desktop.
Genetic algorithm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package core; | |
import java.util.ArrayList; | |
import java.util.Random; | |
public class GeneticAlgorithm { | |
private Random random; | |
public GeneticAlgorithm() { | |
random = new Random(0); | |
} | |
public Subject start(int populationSize, int geneCount, int numberOfGenerations, int numberOfSurvived, double probabilityOfMutation, IFitnessFunction fitnessFunction) { | |
Subject result = null; | |
ArrayList<Subject> population = createInitialPopulation(populationSize, geneCount); | |
for (int i = 0; i < numberOfGenerations; i++) { | |
ArrayList<Subject> newPopulation = new ArrayList<>(population); | |
for (int pairIndex = numberOfSurvived; pairIndex < populationSize - 2; pairIndex = pairIndex + 2) { | |
Subject parent1 = findBestSubject(population, fitnessFunction); | |
Subject parent2 = findBestSubject(population, fitnessFunction); | |
double crossingPoint = random.nextInt(geneCount - 2); | |
for (int j = 0; j < geneCount; j++) { | |
if (j < crossingPoint) { | |
newPopulation.get(pairIndex).setGene(j, parent1.getGene(j)); | |
newPopulation.get(pairIndex + 1).setGene(j, parent2.getGene(j)); | |
} else { | |
newPopulation.get(pairIndex).setGene(j, parent2.getGene(j)); | |
newPopulation.get(pairIndex + 1).setGene(j, parent1.getGene(j)); | |
} | |
} | |
double mutated = random.nextDouble(); | |
if (mutated > probabilityOfMutation) { | |
population.set(pairIndex, performMutation(population.get(pairIndex), probabilityOfMutation)); | |
} | |
} | |
result = findMinimum(population, fitnessFunction); | |
double bestSubjectFitnessFunction = fitnessFunction.Calculate(result); | |
if (bestSubjectFitnessFunction == 0) { | |
break; | |
} | |
} | |
return result; | |
} | |
private ArrayList<Subject> createInitialPopulation(int populationSize, int genesCount) { | |
ArrayList<Subject> population = new ArrayList<>(populationSize); | |
for (int i = 0; i < populationSize; i++) { | |
population.add(i, new Subject(genesCount)); | |
for (int j = 0; j < genesCount; j++) { | |
population.get(i).setGene(j, random.nextDouble() * 10 - 5); | |
} | |
} | |
return population; | |
} | |
private Subject findRandomSubject(ArrayList<Subject> population) { | |
return population.get(random.nextInt(population.size())); | |
} | |
private Subject findBestSubject(ArrayList<Subject> population, IFitnessFunction fitnessFunction) { | |
Subject subject1 = findRandomSubject(population); | |
Subject subject2 = findRandomSubject(population); | |
if (fitnessFunction.calculate(subject1) < fitnessFunction.calculate(subject2)) { | |
return subject1; | |
} else { | |
return subject2; | |
} | |
} | |
private Subject performMutation(Subject subject, double probabilityOfMutation) { | |
int geneIndex = random.nextInt(subject.getGenesCount()); | |
double newGene = subject.getGene(geneIndex) * (1 + (random.nextDouble() - 0.5) * probabilityOfMutation); | |
subject.setGene(geneIndex, 0); | |
geneIndex = random.nextInt(subject.getGenesCount()); | |
newGene = subject.getGene(geneIndex) * (1 + (random.nextDouble() - 0.5) * probabilityOfMutation); | |
subject.setGene(geneIndex, newGene); | |
geneIndex = random.nextInt(subject.getGenesCount()); | |
newGene = subject.getGene(geneIndex) * (1 + (random.nextDouble() - 0.5) * probabilityOfMutation); | |
subject.setGene(geneIndex, newGene); | |
return subject; | |
} | |
public Subject selectParents(ArrayList<Subject> population, int populationSize, int countGene) { | |
return population.get(random.nextInt(populationSize)); | |
} | |
public Subject findMinimum(ArrayList<Subject> population, IFitnessFunction fitnesFunkce) { | |
Subject bestSubject = population.get(0); | |
double bestFitness = fitnesFunkce.calculate(bestSubject); | |
for (Subject subject : population) { | |
double fitness = fitnesFunkce.calculate(subject); | |
if (fitness < bestFitness) { | |
bestFitness = fitness; | |
bestSubject = subject; | |
} | |
} | |
return bestSubject; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package core; | |
public interface IFitnessFunction { | |
public double calculate(Subject subject); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package core; | |
import java.util.ArrayList; | |
import java.util.List; | |
public class Subject { | |
private ArrayList<Double> genes; | |
private int genesCount; | |
public Subject(int genesCount) { | |
genes = new ArrayList<>(); | |
this.genesCount = genesCount; | |
initializeGenes(); | |
} | |
private void initializeGenes() { | |
for (int i = 0; i < getGenesCount(); i++) { | |
genes.add(new Double(0)); | |
} | |
} | |
public int getGenesCount() { | |
return genesCount; | |
} | |
public void setGene(int index, double value) { | |
if (index < 0 || index > genesCount) { | |
throw new IllegalArgumentException("index"); | |
} | |
genes.set(index, value); | |
} | |
public double getGene(int index) { | |
if (index < 0 || index > genesCount) { | |
throw new IllegalArgumentException("index"); | |
} | |
return genes.get(index); | |
} | |
public List<Double> getGenes(int fromIndex, int toIndex) { | |
return genes.subList(fromIndex, toIndex); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment