Documente Academic
Documente Profesional
Documente Cultură
Elaborăm codul în Java. Vom utiliza Eclipse. Putem descărca Eclipse IDE dând
căutare în motoarele de căutare.
În alte limbaje de programare procedăm în mod similar. Evident că avem nevoie
cel puțin de următoarele clase:
- GeneticAlgorithm,
face abstracție de algoritmul genetic și ne asigură metode
specifice implementate legate de problemă;
- Individual, candidatul soluție;
- Population, operații cu cromozomii la nivel de populație;
- Main, care conține metoda main(), i.e. aici se inițializează și pornește
algoritmul.
Primele 3 clase vor fi modificate/adaptate în dependență de problema care este
rezolvată.
Problema
Se consideră o problemă banală în esență. Să se determine un șir din 0 și 1 cu cel
multe valori de 1. Fie lungimea șirului este 50.
Clasa GeneticAlgorithm
Să începem cu clasa GeneticAlgorithm, care va conține parametrii algoritmului
genetic.
public class GeneticAlgorithm {
private int populationSize;
private double mutationRate;
private double crossoverRate;
private int elitismCount;
public GeneticAlgorithm(int populationSize, double mutationRate, double crossover
Rate, int elitismCount) {
this.populationSize = populationSize;
this.mutationRate = mutationRate;
this.crossoverRate = crossoverRate;
this.elitismCount = elitismCount;
}
/**
* Implementam mai multe metode mai tarziu...
*/
}
Clasa Main
Clasa Main va conține metoda main() în care vom rula algoritmul nostru.
public class AllGA {
public static void main(String[] args) {
// Cream obiectul GA
GeneticAlgorithm ga = new GeneticAlgorithm(100, 0.01, 0.95, 0);
// Aici vom adauga mai multe ...
}
}
Inițializarea populației
Pentru inițializarea populației inițiale de cromozomi avem nevoie de cel puțin 2
clase, o clasă pentru crearea și managementul populației, și o altă clasă pentru
crearea și managementul individului din populație:
- Individual,
- Population.
Clasa Individual
Clasa individual conține date și metode ce țin de fiecare individ din populație.
public class Individual {
private int[] chromosome;
private double fitness = -1;
public Individual(int[] chromosome) {
// Create individual chromosome
this.chromosome = chromosome;
}
public Individual(int chromosomeLength) {
this.chromosome = new int[chromosomeLength];
for (int gene = 0; gene < chromosomeLength; gene++) {
if (0.5 < Math.random()) {
this.setGene(gene, 1);
} else {
this.setGene(gene, 0);
}
}
}
public int[] getChromosome() {
return this.chromosome;
}
public int getChromosomeLength() {
return this.chromosome.length;
}
public void setGene(int offset, int gene) {
this.chromosome[offset] = gene;
}
public int getGene(int offset) {
return this.chromosome[offset];
}
public void setFitness(double fitness) {
this.fitness = fitness;
}
public double getFitness() {
return this.fitness;
}
public String toString() {
String output = "";
for (int gene = 0; gene < this.chromosome.length; gene++) {
output += this.chromosome[gene];
}
return output;
}
}
Clasa Population
Clasa Population este destinată managementului populației de cromozomi.
import java.util.Arrays;
import java.util.Comparator;
/**
* Many more methods implemented later...
*/
}
// Create GA object
GeneticAlgorithm ga = new GeneticAlgorithm(100, 0.01, 0.95, 0);
// Initialize population
Population population = ga.initPopulation(50);
}
}
Evaluarea populației
Evaluarea cromozomilor din populație este una dintre etape ale algoritmului
genetic. În continuare, vom implementa o funcție de fitness pentru cromozomii
binari.
Adăugăm funcția calcFitness() în clasa GeneticAlgorithm:
public double calcFitness(Individual individual) {
// Track number of correct genes
int correctGenes = 0;
// Loop over individual's genes
for (int geneIndex = 0; geneIndex < individual.getChromosomeLength(); geneInd
ex++) {
// Add one fitness point for each "1" found
if (individual.getGene(geneIndex) == 1) {
correctGenes += 1;
}
}
// Calculează fitness-ul
double fitness = (double) correctGenes / individual.
getChromosomeLength();
// Stochează fitness-ul
individual.setFitness(fitness);
return fitness;
}
Implementarea încrucișării
În clasa GeneticAlgorithm implementăm metoda:
public Individual selectParent(Population population) {
// Get individuals
Individual individuals[] = population.getIndividuals();
// Spin roulette wheel
double populationFitness = population.getPopulationFitness();
double rouletteWheelPosition = Math.random() * populationFitness;
// Find parent
double spinWheel = 0;
for (Individual individual: individuals) {
spinWheel += individual.getFitness();
if (spinWheel >= rouletteWheelPosition) {
return individual;
}
}
return individuals[population.size() - 1];
}
// Initialize offspring
Individual offspring = new Individual(parent1.getChromosomeLength());
// Create GA object
GeneticAlgorithm ga = new GeneticAlgorithm(100, 0.001, 0.95, 0);
// Initialize population
Population population = ga.initPopulation(50);
// Evaluate population
ga.evalPopulation(population);
// Apply crossover
population = ga.crossoverPopulation(population);
// Apply mutation
// TODO
// Evaluate population
ga.evalPopulation(population);
Mutația
Ne rămâne doar să mai implementăm mutația. Adăugăm la clasa
GeneticAlgorithm următoarea metodă:
public Population mutatePopulation(Population population) {
// Mutate gene
individual.setGene(geneIndex, newGene);
}
}
}
// Create GA object
GeneticAlgorithm ga = new GeneticAlgorithm(100, 0.001, 0.95, 0);
// Initialize population
Population population = ga.initPopulation(50);
// Evaluate population
ga.evalPopulation(population);
// Apply crossover
population = ga.crossoverPopulation(population);
// Apply mutation
population = ga.mutatePopulation(population);
// Evaluate population
ga.evalPopulation(population);
Execuția programului
Urmează să vedem ce iese
�
Ce lipsește?
Nu am implementat elitismul.