From 5b213e34140e4992c036f273430ae232eff99faf Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 14 Oct 2026 22:01:15 +0200 Subject: [PATCH] Finish refactor --- assignement.md | 3 +- src/main/java/Main.java | 6 +- src/main/java/domain/binary/Population.java | 4 +- .../algorithm/AbstractGeneticAlgorithm.java | 42 ++++++++++ .../algorithm/CustomGeneticAlgorithm.java | 21 +++-- .../algorithm/SimpleGeneticAlgorithm.java | 78 +++++-------------- 6 files changed, 78 insertions(+), 76 deletions(-) create mode 100644 src/main/java/domain/binary/algorithm/AbstractGeneticAlgorithm.java diff --git a/assignement.md b/assignement.md index 3e70280..c9967a7 100644 --- a/assignement.md +++ b/assignement.md @@ -12,8 +12,9 @@ static classes. ### Prepare support for class inheritance -## Limit number of generations +--- +## Limit number of generations ## Roulette selection diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 365e72f..c1917f5 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -1,5 +1,6 @@ import domain.annealing.SimulatedAnnealing; import domain.ant_colony.AntColonyOptimization; +import domain.binary.algorithm.CustomGeneticAlgorithm; import domain.binary.algorithm.SimpleGeneticAlgorithm; import java.util.Scanner; @@ -19,13 +20,14 @@ public class Main { break; case 2: SimpleGeneticAlgorithm ga = new SimpleGeneticAlgorithm( + 50, 0.5, 0.025, 5, true, - new byte[64] + "1011000100000100010000100000100111001000000100000100000000001111" ); - ga.runAlgorithm(50, "1011000100000100010000100000100111001000000100000100000000001111"); + ga.launch(); break; case 3: AntColonyOptimization antColony = new AntColonyOptimization(21); diff --git a/src/main/java/domain/binary/Population.java b/src/main/java/domain/binary/Population.java index d9c5540..e13c0e6 100644 --- a/src/main/java/domain/binary/Population.java +++ b/src/main/java/domain/binary/Population.java @@ -42,8 +42,8 @@ public class Population { return individuals[index]; } - public Individual setIndividual(int index, Individual individual) { - return individuals[index] = individual; + public void setIndividual(int index, Individual individual) { + individuals[index] = individual; } public Individual getFittest() { diff --git a/src/main/java/domain/binary/algorithm/AbstractGeneticAlgorithm.java b/src/main/java/domain/binary/algorithm/AbstractGeneticAlgorithm.java new file mode 100644 index 0000000..06a4f02 --- /dev/null +++ b/src/main/java/domain/binary/algorithm/AbstractGeneticAlgorithm.java @@ -0,0 +1,42 @@ +package domain.binary.algorithm; + +import lombok.Data; + +@Data +public abstract class AbstractGeneticAlgorithm { + + private byte[] solution; + private int generationCount; + + public AbstractGeneticAlgorithm(String solution) { + generationCount = 0; + this.solution = mapSolution(solution); + } + + public void launch(){ + while(!stopCriterion()){ + run(); + generationCount++; + } + } + + protected abstract void run(); + protected abstract boolean stopCriterion(); + + protected int getMaxFitness() { + return solution.length; + } + + private byte[] mapSolution(String newSolution) { + solution = new byte[newSolution.length()]; + for (int i = 0; i < newSolution.length(); i++) { + String character = newSolution.substring(i, i + 1); + if (character.contains("0") || character.contains("1")) { + solution[i] = Byte.parseByte(character); + } else { + solution[i] = 0; + } + } + return solution; + } +} diff --git a/src/main/java/domain/binary/algorithm/CustomGeneticAlgorithm.java b/src/main/java/domain/binary/algorithm/CustomGeneticAlgorithm.java index a744aea..af8e8a6 100644 --- a/src/main/java/domain/binary/algorithm/CustomGeneticAlgorithm.java +++ b/src/main/java/domain/binary/algorithm/CustomGeneticAlgorithm.java @@ -1,27 +1,24 @@ package domain.binary.algorithm; -import domain.binary.Population; - public class CustomGeneticAlgorithm extends SimpleGeneticAlgorithm { + private final int maxGenerationCount; + public CustomGeneticAlgorithm( + int popSize, + int maxGenerationCount, double uniformRate, double mutationRate, int tournamentSize, boolean elitism, - byte[] solution + String solution ) { - super(uniformRate, mutationRate, tournamentSize, elitism, solution); + super(popSize, uniformRate, mutationRate, tournamentSize, elitism, solution); + this.maxGenerationCount = maxGenerationCount; } @Override - public boolean runAlgorithm(int populationSize, String solution){ - return false; + protected boolean stopCriterion() { + return getGenerationCount() == maxGenerationCount; } - - @Override - public boolean checkStopCriteria(Population pop) { - return false; - } - } diff --git a/src/main/java/domain/binary/algorithm/SimpleGeneticAlgorithm.java b/src/main/java/domain/binary/algorithm/SimpleGeneticAlgorithm.java index c7515fe..c00eed9 100644 --- a/src/main/java/domain/binary/algorithm/SimpleGeneticAlgorithm.java +++ b/src/main/java/domain/binary/algorithm/SimpleGeneticAlgorithm.java @@ -1,81 +1,41 @@ package domain.binary.algorithm; -import domain.binary.Individual; import domain.binary.Population; import lombok.Data; -@Data -public class SimpleGeneticAlgorithm { +public class SimpleGeneticAlgorithm extends AbstractGeneticAlgorithm{ - private final double uniformRate; - private final double mutationRate; - private final int tournamentSize; + private Population population; private final boolean elitism; - private byte[] solution; public SimpleGeneticAlgorithm( + int popSize, double uniformRate, double mutationRate, int tournamentSize, boolean elitism, - byte[] solution + String solution ){ - this.uniformRate = uniformRate; - this.mutationRate = mutationRate; - this.tournamentSize = tournamentSize; - this.elitism = elitism; - this.solution = solution; - } - - public boolean runAlgorithm(int populationSize, String solution) { - setSolution(solution); - Population myPop = new Population( - populationSize, + super(solution); + this.population = new Population( + popSize, uniformRate, mutationRate, tournamentSize, - this.solution); - - int generationCount = 1; - - while (checkStopCriteria(myPop)) { - System.out.println("Generation: " + generationCount + " Correct genes found: " + myPop.getFittest().getFitness()); - myPop = myPop.evolve(elitism, this.solution); - generationCount++; - } - - System.out.println("Solution found!"); - System.out.println("Generation: " + generationCount); - System.out.println("Genes: "); - System.out.println(myPop.getFittest()); - return true; + getSolution()); + this.elitism = elitism; } - public boolean checkStopCriteria(Population pop) { - int fitness = pop.getFittest().getFitness(); + @Override + protected void run() { + System.out.println("Generation: " + getGenerationCount() + " Correct genes found: " + population.getFittest().getFitness()); + population = population.evolve(elitism, getSolution()); + } + + @Override + protected boolean stopCriterion() { + int fitness = population.getFittest().getFitness(); int maxFitness = getMaxFitness(); - return fitness < maxFitness; + return fitness >= maxFitness; } - - protected int getMaxFitness() { - int maxFitness = solution.length; - return maxFitness; - } - - protected void setSolution(String newSolution) { - if (newSolution.length() != this.solution.length) { - throw new RuntimeException("The solution needs to have " + this.solution.length + " bytes"); - } - - solution = new byte[newSolution.length()]; - for (int i = 0; i < newSolution.length(); i++) { - String character = newSolution.substring(i, i + 1); - if (character.contains("0") || character.contains("1")) { - solution[i] = Byte.parseByte(character); - } else { - solution[i] = 0; - } - } - } - }