diff --git a/commons-math-examples/examples-ga/examples-ga-math-functions-adaptive/src/main/java/org/apache/commons/math4/examples/ga/mathfunctions/adaptive/AdaptiveMathFunctionOptimizer.java b/commons-math-examples/examples-ga/examples-ga-math-functions-adaptive/src/main/java/org/apache/commons/math4/examples/ga/mathfunctions/adaptive/AdaptiveMathFunctionOptimizer.java index cd41f98f15..f0bf814881 100644 --- a/commons-math-examples/examples-ga/examples-ga-math-functions-adaptive/src/main/java/org/apache/commons/math4/examples/ga/mathfunctions/adaptive/AdaptiveMathFunctionOptimizer.java +++ b/commons-math-examples/examples-ga/examples-ga-math-functions-adaptive/src/main/java/org/apache/commons/math4/examples/ga/mathfunctions/adaptive/AdaptiveMathFunctionOptimizer.java @@ -42,13 +42,29 @@ * genetic algorithm. */ public final class AdaptiveMathFunctionOptimizer { + /** length of chromosome. **/ private static final int CHROMOSOME_LENGTH_PER_DIMENSION = 12; - /** instance of logger. **/ private final Logger logger = LoggerFactory.getLogger(AdaptiveMathFunctionOptimizer.class); - public void optimize(int dimension, + /** + * Optimizes the population. + * @param dimension problem dimension + * @param minCrossoverRate minimum crossover rate + * @param maxCrossoverRate maximum crossover rate + * @param minMutationRate minimum mutation rate + * @param maxMutationRate maximum mutation rate + * @param elitismRate elitism rate + * @param tournamentSize tournament size for tournament + * selection + * @param generationCountWithUnchangedBestFitness number of generation to be + * evolved with best unchanged + * fitness for convergence + * @param populationSize size of population + * @return returns best chromosome + */ + public Chromosome optimize(int dimension, double minCrossoverRate, double maxCrossoverRate, double minMutationRate, @@ -75,7 +91,7 @@ public void optimize(int dimension, // best chromosome from the final population final Chromosome bestFinal = finalPopulation.getFittestChromosome(); - logger.info(bestFinal.toString()); + return bestFinal; } private static Population getInitialPopulation(int dimension, int populationSize) { diff --git a/commons-math-examples/examples-ga/examples-ga-math-functions-adaptive/src/main/java/org/apache/commons/math4/examples/ga/mathfunctions/adaptive/StandAlone.java b/commons-math-examples/examples-ga/examples-ga-math-functions-adaptive/src/main/java/org/apache/commons/math4/examples/ga/mathfunctions/adaptive/StandAlone.java index 0c59729ddf..330e783997 100644 --- a/commons-math-examples/examples-ga/examples-ga-math-functions-adaptive/src/main/java/org/apache/commons/math4/examples/ga/mathfunctions/adaptive/StandAlone.java +++ b/commons-math-examples/examples-ga/examples-ga-math-functions-adaptive/src/main/java/org/apache/commons/math4/examples/ga/mathfunctions/adaptive/StandAlone.java @@ -16,6 +16,15 @@ */ package org.apache.commons.math4.examples.ga.mathfunctions.adaptive; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import picocli.CommandLine; import picocli.CommandLine.Command; import picocli.CommandLine.Option; @@ -27,43 +36,40 @@ public class StandAlone implements Runnable { /** number of dimension. **/ @Option(names = "-d", paramLabel = "DIMENSION", required = true, description = "Dimension of problem domain.") private int dimension; - /** size of tournament. **/ @Option(names = "-t", paramLabel = "TOURNAMENT_SIZE", required = true, description = "Tournament size.") private int tournamentSize; - /** size of population. **/ @Option(names = "-p", paramLabel = "POPULATION_SIZE", required = true, description = "Size of population.") private int populationSize; - /** minimum rate of crossover. **/ @Option(names = "-c", paramLabel = "MIN_CROSSOVER_RATE", description = "Crossover rate (default: ${DEFAULT-VALUE}).") private double minCrossoverRate = 0; - /** maximum rate of crossover. **/ @Option(names = "-C", paramLabel = "MAX_CROSSOVER_RATE", description = "Crossover rate (default: ${DEFAULT-VALUE}).") private double maxCrossoverRate = 1.0; - /** minimum rate of mutation. **/ @Option(names = "-m", paramLabel = "MIN_MUTATION_RATE", description = "Minimum Mutation rate (default: ${DEFAULT-VALUE}).") private double minMutationRate = 0; - /** maximum rate of mutation. **/ @Option(names = "-M", paramLabel = "MAX_MUTATION_RATE", description = "Maximum Mutation rate (default: ${DEFAULT-VALUE}).") private double maxMutationRate = 0.1; - /** rate of elitism. **/ @Option(names = "-e", paramLabel = "ELITISM_RATE", description = "Elitism rate (default: ${DEFAULT-VALUE}).") private double elitismRate = 0.25; - /** number of generations with unchanged best fitness. **/ @Option(names = "-g", paramLabel = "GENERATIONS_EVOLVED_WITH_UNCHANGED_BEST_FITNESS", description = "No of generations evolved with unchanged best fitness (default: ${DEFAULT-VALUE}).") private int generationsEvolvedWithUnchangedBestFitness = 50; + /** indicates the absolute file path where output would be stored. **/ + @Option(names = {"-o", "--output"}, required = true, paramLabel = "OUTPUT_FILE_PATH", arity = "1") + private String output; + /** instance of logger. **/ + private final Logger logger = LoggerFactory.getLogger(StandAlone.class); public static void main(String[] args) { CommandLine.run(new StandAlone(), args); @@ -79,10 +85,18 @@ public void run() { // validate all input options. validateInput(); - final AdaptiveMathFunctionOptimizer optimizer = new AdaptiveMathFunctionOptimizer(); - - optimizer.optimize(dimension, minCrossoverRate, maxCrossoverRate, minMutationRate, maxMutationRate, elitismRate, - tournamentSize, generationsEvolvedWithUnchangedBestFitness, populationSize); + try (PrintWriter writer = new PrintWriter(new File(output), Charset.defaultCharset().name())) { + writer.println("Optimization Result:"); + final AdaptiveMathFunctionOptimizer optimizer = new AdaptiveMathFunctionOptimizer(); + writer.println(optimizer + .optimize(dimension, minCrossoverRate, maxCrossoverRate, minMutationRate, maxMutationRate, + elitismRate, tournamentSize, generationsEvolvedWithUnchangedBestFitness, populationSize) + .toString()); + } catch (FileNotFoundException e) { + logger.error("Error while writing to file", e); + } catch (UnsupportedEncodingException e) { + logger.error("Encoding not supported for writing to output file", e); + } } @@ -121,5 +135,9 @@ private void validateInput() { throw new IllegalArgumentException( "Number of generations evolved with unchanged best fitness should be >= 1."); } + File outFile = new File(output); + if (outFile.exists() && !outFile.delete()) { + throw new IllegalArgumentException("Existing output file could not be deleted."); + } } } diff --git a/commons-math-examples/examples-ga/examples-ga-math-functions/src/main/java/org/apache/commons/math4/examples/ga/mathfunctions/MathFunctionOptimizer.java b/commons-math-examples/examples-ga/examples-ga-math-functions/src/main/java/org/apache/commons/math4/examples/ga/mathfunctions/MathFunctionOptimizer.java index 73b00a08ef..2f72bdf4a8 100644 --- a/commons-math-examples/examples-ga/examples-ga-math-functions/src/main/java/org/apache/commons/math4/examples/ga/mathfunctions/MathFunctionOptimizer.java +++ b/commons-math-examples/examples-ga/examples-ga-math-functions/src/main/java/org/apache/commons/math4/examples/ga/mathfunctions/MathFunctionOptimizer.java @@ -40,6 +40,7 @@ */ public final class MathFunctionOptimizer { + /** length of chromosome. **/ private static final int CHROMOSOME_LENGTH_PER_DIMENSION = 12; /** instance of logger. **/ @@ -55,8 +56,9 @@ public final class MathFunctionOptimizer { * @param generationCountWithUnchangedBestFitness no of generation evolved with * unchanged best fitness * @param populationSize size of population + * @return returns best chromosome */ - public void optimize(int dimension, + public Chromosome optimize(int dimension, double crossoverRate, double mutationRate, double elitismRate, @@ -81,7 +83,7 @@ public void optimize(int dimension, // best chromosome from the final population final Chromosome bestFinal = finalPopulation.getFittestChromosome(); - logger.info(bestFinal.toString()); + return bestFinal; } private static Population getInitialPopulation(int dimension, int populationSize) { @@ -101,14 +103,14 @@ private static Population getInitialPopulation(int dimension, int po final BinaryChromosome binaryChromosome = (BinaryChromosome) chromosome; final long length = binaryChromosome.getLength(); - final List coordinates = new ArrayList<>(); + final List dimValues = new ArrayList<>(); for (int j = 0; j < length; j += 12) { final String dimensionStrValue = binaryChromosome.getStringRepresentation(j, j + 12); - coordinates.add(Integer.parseUnsignedInt(dimensionStrValue, 2) / 100d); + dimValues.add(Integer.parseUnsignedInt(dimensionStrValue, 2) / 100d); } - return new Coordinate(coordinates); + return new Coordinate(dimValues); })); } return population; diff --git a/commons-math-examples/examples-ga/examples-ga-math-functions/src/main/java/org/apache/commons/math4/examples/ga/mathfunctions/StandAlone.java b/commons-math-examples/examples-ga/examples-ga-math-functions/src/main/java/org/apache/commons/math4/examples/ga/mathfunctions/StandAlone.java index 4d54ac58f3..80def572a2 100644 --- a/commons-math-examples/examples-ga/examples-ga-math-functions/src/main/java/org/apache/commons/math4/examples/ga/mathfunctions/StandAlone.java +++ b/commons-math-examples/examples-ga/examples-ga-math-functions/src/main/java/org/apache/commons/math4/examples/ga/mathfunctions/StandAlone.java @@ -16,7 +16,15 @@ */ package org.apache.commons.math4.examples.ga.mathfunctions; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; + import org.apache.commons.math4.examples.ga.mathfunctions.legacy.LegacyMathFunctionOptimizer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import picocli.CommandLine; import picocli.CommandLine.Command; @@ -28,35 +36,33 @@ public class StandAlone implements Runnable { /** number of dimension. **/ @Option(names = "-d", paramLabel = "DIMENSION", required = true, description = "Dimension of problem domain.") private int dimension; - /** size of tournament. **/ @Option(names = "-t", paramLabel = "TOURNAMENT_SIZE", required = true, description = "Tournament size.") private int tournamentSize; - /** size of population. **/ @Option(names = "-p", paramLabel = "POPULATION_SIZE", required = true, description = "Size of population.") private int populationSize; - /** rate of crossover. **/ @Option(names = "-c", paramLabel = "CROSSOVER_RATE", description = "Crossover rate (default: ${DEFAULT-VALUE}).") private double crossoverRate = 1.0; - /** rate of elitism. **/ @Option(names = "-e", paramLabel = "ELITISM_RATE", description = "Elitism rate (default: ${DEFAULT-VALUE}).") private double elitismRate = 0.25; - /** rate of mutation. **/ @Option(names = "-m", paramLabel = "MUTATION_RATE", description = "Mutation rate (default: ${DEFAULT-VALUE}).") private double mutationRate = 0.01; - /** number of generations with unchanged best fitness. **/ @Option(names = "-g", paramLabel = "GENERATIONS_EVOLVED_WITH_UNCHANGED_BEST_FITNESS", description = "No of generations evolved with unchanged best fitness (default: ${DEFAULT-VALUE}).") private int generationsEvolvedWithUnchangedBestFitness = 50; - /** indicates whether the algorithm should be legacy or not. **/ @Option(names = "--legacy", description = "Indicates which version of algorithm to execute current or legacy.") private boolean legacy; + /** indicates the absolute file path where output would be stored. **/ + @Option(names = {"-o", "--output"}, required = true, paramLabel = "OUTPUT_FILE_PATH") + private String output; + /** instance of logger. **/ + private final Logger logger = LoggerFactory.getLogger(StandAlone.class); public static void main(String[] args) { CommandLine.run(new StandAlone(), args); @@ -72,14 +78,26 @@ public void run() { // validate all input options. validateInput(); - if (!legacy) { - new MathFunctionOptimizer().optimize(dimension, crossoverRate, mutationRate, elitismRate, tournamentSize, - generationsEvolvedWithUnchangedBestFitness, populationSize); - } else { - new LegacyMathFunctionOptimizer().optimize(dimension, crossoverRate, mutationRate, elitismRate, - tournamentSize, generationsEvolvedWithUnchangedBestFitness, populationSize); + try (PrintWriter writer = new PrintWriter(new File(output), Charset.defaultCharset().name())) { + writer.println("Optimization Result:"); + if (!legacy) { + writer.println( + new MathFunctionOptimizer() + .optimize(dimension, crossoverRate, mutationRate, elitismRate, tournamentSize, + generationsEvolvedWithUnchangedBestFitness, populationSize) + .toString()); + } else { + writer.println( + new LegacyMathFunctionOptimizer() + .optimize(dimension, crossoverRate, mutationRate, elitismRate, tournamentSize, + generationsEvolvedWithUnchangedBestFitness, populationSize) + .toString()); + } + } catch (FileNotFoundException e) { + logger.error("Error while writing to file", e); + } catch (UnsupportedEncodingException e) { + logger.error("Encoding not supported for writing to output file", e); } - } private void validateInput() { @@ -105,5 +123,9 @@ private void validateInput() { throw new IllegalArgumentException( "Number of generations evolved with unchanged best fitness should be >= 1."); } + File outFile = new File(output); + if (outFile.exists() && !outFile.delete()) { + throw new IllegalArgumentException("Existing output file could not be deleted."); + } } } diff --git a/commons-math-examples/examples-ga/examples-ga-math-functions/src/main/java/org/apache/commons/math4/examples/ga/mathfunctions/legacy/LegacyMathFunctionOptimizer.java b/commons-math-examples/examples-ga/examples-ga-math-functions/src/main/java/org/apache/commons/math4/examples/ga/mathfunctions/legacy/LegacyMathFunctionOptimizer.java index ca49162476..55409b737a 100644 --- a/commons-math-examples/examples-ga/examples-ga-math-functions/src/main/java/org/apache/commons/math4/examples/ga/mathfunctions/legacy/LegacyMathFunctionOptimizer.java +++ b/commons-math-examples/examples-ga/examples-ga-math-functions/src/main/java/org/apache/commons/math4/examples/ga/mathfunctions/legacy/LegacyMathFunctionOptimizer.java @@ -31,6 +31,7 @@ * the legacy genetic algorithm. */ public final class LegacyMathFunctionOptimizer { + /** length of chromosome per dimension. **/ private static final int CHROMOSOME_LENGTH_PER_DIMENSION = 12; @@ -44,8 +45,9 @@ public final class LegacyMathFunctionOptimizer { * @param generationCountWithUnchangedBestFitness no of generation evolved with * unchanged best fitness * @param populationSize size of population + * @return returns best chromosome */ - public void optimize(int dimension, + public Chromosome optimize(int dimension, double crossoverRate, double mutationRate, double elitismRate, @@ -67,9 +69,7 @@ public void optimize(int dimension, // best chromosome from the final population final Chromosome bestFinal = finalPopulation.getFittestChromosome(); - //CHECKSTYLE: stop all - System.out.println("best=" + bestFinal.toString()); - //CHECKSTYLE: resume all + return bestFinal; } private static Population getInitialPopulation(int dimension, int populationSize, double elitismRate) { diff --git a/commons-math-examples/examples-ga/examples-ga-tsp/src/main/java/org/apache/commons/math4/examples/ga/tsp/StandAlone.java b/commons-math-examples/examples-ga/examples-ga-tsp/src/main/java/org/apache/commons/math4/examples/ga/tsp/StandAlone.java index 8828fecd82..3948016f39 100644 --- a/commons-math-examples/examples-ga/examples-ga-tsp/src/main/java/org/apache/commons/math4/examples/ga/tsp/StandAlone.java +++ b/commons-math-examples/examples-ga/examples-ga-tsp/src/main/java/org/apache/commons/math4/examples/ga/tsp/StandAlone.java @@ -16,11 +16,20 @@ */ package org.apache.commons.math4.examples.ga.tsp; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; import java.util.Arrays; import java.util.Collections; import java.util.List; +import org.apache.commons.math3.genetics.RandomKey; import org.apache.commons.math4.examples.ga.tsp.legacy.LegacyTSPOptimizer; +import org.apache.commons.math4.ga.chromosome.Chromosome; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import picocli.CommandLine; import picocli.CommandLine.Command; @@ -29,40 +38,44 @@ @Command(name = "tsp-optimizer", mixinStandardHelpOptions = true, version = "tsp-optimizer 1.0") public class StandAlone implements Runnable { + /** label for city for output file. **/ + private static final String CITY_LABEL = "City - "; + /** label for total distance for output file. **/ + private static final String TOT_DST_LABEL = "Total distance - "; + /** label for travel distance for output file. **/ + private static final String TRAVEL_DIST_LABEL = "Travel Shcedule:"; /** list of cities. **/ - public static final List CITIES = Collections.unmodifiableList( + private static final List CITIES = Collections.unmodifiableList( Arrays.asList(new City[] {new City(1, 0, 0), new City(2, 1, 0), new City(3, 2, 0), new City(4, 3, 0), new City(5, 3, 1), new City(6, 3, 2), new City(7, 3, 3), new City(8, 2, 3), new City(9, 1, 3), new City(10, 0, 3), new City(11, 1, 2), new City(12, 2, 2), new City(13, 2, 1), new City(14, 1, 1)})); - /** size of tournament. **/ @Option(names = "-t", paramLabel = "TOURNAMENT_SIZE", required = true, description = "Tournament size.") private int tournamentSize; - /** size of population. **/ @Option(names = "-p", paramLabel = "POPULATION_SIZE", required = true, description = "Size of population.") private int populationSize; - /** rate of crossover. **/ @Option(names = "-c", paramLabel = "CROSSOVER_RATE", description = "Crossover rate (default: ${DEFAULT-VALUE}).") private double crossoverRate = 1.0; - /** rate of elitism. **/ @Option(names = "-e", paramLabel = "ELITISM_RATE", description = "Elitism rate (default: ${DEFAULT-VALUE}).") private double elitismRate = 0.25; - /** rate of mutation. **/ @Option(names = "-m", paramLabel = "MUTATION_RATE", description = "Mutation rate (default: ${DEFAULT-VALUE}).") private double mutationRate = 0.01; - /** number of generations with unchanged best fitness. **/ @Option(names = "-g", paramLabel = "GENERATIONS_EVOLVED_WITH_UNCHANGED_BEST_FITNESS", description = "No of generations evolved with unchanged best fitness (default: ${DEFAULT-VALUE}).") private int generationsEvolvedWithUnchangedBestFitness = 50; - /** indicates whether the algorithm should be legacy or not. **/ @Option(names = "--legacy", description = "Indicates which version of algorithm to execute current or legacy.") private boolean legacy; + /** indicates the absolute file path where output would be stored. **/ + @Option(names = {"-o", "--output"}, required = true, paramLabel = "OUTPUT_FILE_PATH") + private String output; + /** instance of logger. **/ + private final Logger logger = LoggerFactory.getLogger(StandAlone.class); public static void main(String[] args) { CommandLine.run(new StandAlone(), args); @@ -77,14 +90,35 @@ public void run() { // validate all input options. validateInput(); - if (!legacy) { - new TSPOptimizer().optimize(CITIES, crossoverRate, mutationRate, elitismRate, tournamentSize, - generationsEvolvedWithUnchangedBestFitness, populationSize); - } else { - new LegacyTSPOptimizer().optimize(CITIES, crossoverRate, mutationRate, elitismRate, tournamentSize, - generationsEvolvedWithUnchangedBestFitness, populationSize); + try (PrintWriter writer = new PrintWriter(new File(output), Charset.defaultCharset().name())) { + writer.println("Optimization Result:"); + if (!legacy) { + Chromosome> bestChromosome = new TSPOptimizer().optimize(CITIES, crossoverRate, mutationRate, + elitismRate, tournamentSize, generationsEvolvedWithUnchangedBestFitness, populationSize); + + writer.println(TRAVEL_DIST_LABEL); + List bestCities = bestChromosome.decode(); + for (City city : bestCities) { + writer.println(CITY_LABEL + city.getIndex()); + } + writer.println(TOT_DST_LABEL + Math.abs(bestChromosome.getFitness())); + } else { + RandomKey bestChromosome = (RandomKey) new LegacyTSPOptimizer().optimize(CITIES, + crossoverRate, mutationRate, elitismRate, tournamentSize, + generationsEvolvedWithUnchangedBestFitness, populationSize); + + writer.println(TRAVEL_DIST_LABEL); + List bestCities = bestChromosome.decode(CITIES); + for (City city : bestCities) { + writer.println(CITY_LABEL + city.getIndex()); + } + writer.println(TOT_DST_LABEL + Math.abs(bestChromosome.fitness())); + } + } catch (FileNotFoundException e) { + logger.error("Error while writing to file", e); + } catch (UnsupportedEncodingException e) { + logger.error("Encoding not supported for writing to output file", e); } - } private void validateInput() { @@ -107,5 +141,9 @@ private void validateInput() { throw new IllegalArgumentException( "Number of generations evolved with unchanged best fitness should be >= 1."); } + File outFile = new File(output); + if (outFile.exists() && !outFile.delete()) { + throw new IllegalArgumentException("Existing output file could not be deleted."); + } } } diff --git a/commons-math-examples/examples-ga/examples-ga-tsp/src/main/java/org/apache/commons/math4/examples/ga/tsp/TSPOptimizer.java b/commons-math-examples/examples-ga/examples-ga-tsp/src/main/java/org/apache/commons/math4/examples/ga/tsp/TSPOptimizer.java index 4b0e85c477..700b8a7c1f 100644 --- a/commons-math-examples/examples-ga/examples-ga-tsp/src/main/java/org/apache/commons/math4/examples/ga/tsp/TSPOptimizer.java +++ b/commons-math-examples/examples-ga/examples-ga-tsp/src/main/java/org/apache/commons/math4/examples/ga/tsp/TSPOptimizer.java @@ -19,6 +19,7 @@ import java.util.List; import org.apache.commons.math4.ga.GeneticAlgorithm; +import org.apache.commons.math4.ga.chromosome.Chromosome; import org.apache.commons.math4.ga.chromosome.RealValuedChromosome; import org.apache.commons.math4.ga.convergence.StoppingCondition; import org.apache.commons.math4.ga.convergence.UnchangedBestFitness; @@ -50,8 +51,9 @@ public final class TSPOptimizer { * @param generationCountWithUnchangedBestFitness no of generations evolved with * unchanged best fitness * @param populationSize size of population + * @return returns best chromosome */ - public void optimize(List cities, + public Chromosome> optimize(List cities, double crossoverRate, double mutationRate, double elitismRate, @@ -73,10 +75,7 @@ public void optimize(List cities, Runtime.getRuntime().availableProcessors()); // best chromosome from the final population - final RealValuedChromosome> bestFinal = (RealValuedChromosome>) finalPopulation - .getFittestChromosome(); - - logger.info(bestFinal.decode().toString()); + return finalPopulation.getFittestChromosome(); } private static Population> getInitialPopulation(List cities, int populationSize) { @@ -87,12 +86,9 @@ private static Population> getInitialPopulation(List cities, in ChromosomeRepresentationUtils.randomPermutation(cities.size()), decodedChromosome -> { final DistanceMatrix distanceMatrix = DistanceMatrix.getInstance(cities); double totalDistance = 0.0; - int index1 = 0; - int index2 = 0; for (int j = 0; j < cities.size(); j++) { - index1 = j; - index2 = (j == cities.size() - 1) ? 0 : j + 1; - totalDistance += distanceMatrix.getDistance(cities.get(index1), cities.get(index2)); + totalDistance += distanceMatrix.getDistance(decodedChromosome.get(j), + decodedChromosome.get((j == cities.size() - 1) ? 0 : j + 1)); } return -totalDistance; }, new RandomKeyDecoder(cities))); diff --git a/commons-math-examples/examples-ga/examples-ga-tsp/src/main/java/org/apache/commons/math4/examples/ga/tsp/legacy/LegacyTSPOptimizer.java b/commons-math-examples/examples-ga/examples-ga-tsp/src/main/java/org/apache/commons/math4/examples/ga/tsp/legacy/LegacyTSPOptimizer.java index 9d826e73ba..77879b11ba 100644 --- a/commons-math-examples/examples-ga/examples-ga-tsp/src/main/java/org/apache/commons/math4/examples/ga/tsp/legacy/LegacyTSPOptimizer.java +++ b/commons-math-examples/examples-ga/examples-ga-tsp/src/main/java/org/apache/commons/math4/examples/ga/tsp/legacy/LegacyTSPOptimizer.java @@ -18,6 +18,7 @@ import java.util.List; +import org.apache.commons.math3.genetics.Chromosome; import org.apache.commons.math3.genetics.ElitisticListPopulation; import org.apache.commons.math3.genetics.GeneticAlgorithm; import org.apache.commons.math3.genetics.OnePointCrossover; @@ -27,12 +28,18 @@ import org.apache.commons.math3.genetics.StoppingCondition; import org.apache.commons.math3.genetics.TournamentSelection; import org.apache.commons.math4.examples.ga.tsp.City; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * This class represents the tsp optimizer based on legacy implementation of * Genetic Algorithm. */ public class LegacyTSPOptimizer { + + /** instance of logger. **/ + private final Logger logger = LoggerFactory.getLogger(LegacyTSPOptimizer.class); + /** * Optimizes the TSP problem. * @param cities list of cities @@ -43,8 +50,9 @@ public class LegacyTSPOptimizer { * @param generationCountWithUnchangedBestFitness no of generations evolved with * unchanged best fitness * @param populationSize size of population + * @return returns best chromosome */ - public void optimize(List cities, + public Chromosome optimize(List cities, double crossoverRate, double mutationRate, double elitismRate, @@ -63,13 +71,14 @@ public void optimize(List cities, final Population finalPopulation = ga.evolve(getInitialPopulation(cities, populationSize, elitismRate), stopCond); - // best chromosome from the final population - @SuppressWarnings("unchecked") - final RandomKey bestFinal = (RandomKey) finalPopulation.getFittestChromosome(); - - //CHECKSTYLE: stop all - System.out.println("best=" + bestFinal.toString()); - //CHECKSTYLE: resume all + return finalPopulation.getFittestChromosome(); +// StringBuilder schedule = new StringBuilder("Travel Shcedule: " + System.lineSeparator()); +// List bestCities = bestFinal.decode(cities); +// for (City city : bestCities) { +// schedule.append("City - " + city.getIndex() + System.lineSeparator()); +// } +// schedule.append("Total distance - " + Math.abs(bestFinal.fitness())); +// logger.info(schedule.toString()); } private static Population getInitialPopulation(List cities, int populationSize, double elitismRate) { diff --git a/commons-math-examples/examples-ga/examples-parallel-ga-math-functions/src/main/java/org/apache/commons/math4/examples/ga/parallel/mathfunctions/ParallelMathFunctionOptimizer.java b/commons-math-examples/examples-ga/examples-parallel-ga-math-functions/src/main/java/org/apache/commons/math4/examples/ga/parallel/mathfunctions/ParallelMathFunctionOptimizer.java index 6a1d56a9a1..5a69c9955d 100644 --- a/commons-math-examples/examples-ga/examples-parallel-ga-math-functions/src/main/java/org/apache/commons/math4/examples/ga/parallel/mathfunctions/ParallelMathFunctionOptimizer.java +++ b/commons-math-examples/examples-ga/examples-parallel-ga-math-functions/src/main/java/org/apache/commons/math4/examples/ga/parallel/mathfunctions/ParallelMathFunctionOptimizer.java @@ -42,8 +42,8 @@ * This class represents an optimizer for a 2-dimensional math function using * genetic algorithm. */ - public final class ParallelMathFunctionOptimizer { + /** length of chromosome. **/ private static final int CHROMOSOME_LENGTH_PER_DIMENSION = 12; /** instance of logger. **/ @@ -56,8 +56,9 @@ public final class ParallelMathFunctionOptimizer { * @param generationCountWithUnchangedBestFitness no of generation evolved with * unchanged best fitness * @param populationSize size of population + * @return returns best chromosome */ - public void optimize(int dimension, + public Chromosome optimize(int dimension, int tournamentSize, int generationCountWithUnchangedBestFitness, int populationSize) { @@ -94,10 +95,7 @@ public void optimize(int dimension, bestChromosomes.add(population.getFittestChromosome()); } - // best chromosome after convergence. - final Chromosome bestFinal = Collections.max(bestChromosomes); - - logger.info(bestFinal.toString()); + return Collections.max(bestChromosomes); } private static Population getInitialPopulation(int dimension, int populationSize) { diff --git a/commons-math-examples/examples-ga/examples-parallel-ga-math-functions/src/main/java/org/apache/commons/math4/examples/ga/parallel/mathfunctions/StandAlone.java b/commons-math-examples/examples-ga/examples-parallel-ga-math-functions/src/main/java/org/apache/commons/math4/examples/ga/parallel/mathfunctions/StandAlone.java index 97beb7e1ca..a5964dee7f 100644 --- a/commons-math-examples/examples-ga/examples-parallel-ga-math-functions/src/main/java/org/apache/commons/math4/examples/ga/parallel/mathfunctions/StandAlone.java +++ b/commons-math-examples/examples-ga/examples-parallel-ga-math-functions/src/main/java/org/apache/commons/math4/examples/ga/parallel/mathfunctions/StandAlone.java @@ -16,6 +16,15 @@ */ package org.apache.commons.math4.examples.ga.parallel.mathfunctions; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import picocli.CommandLine; import picocli.CommandLine.Command; import picocli.CommandLine.Option; @@ -26,19 +35,21 @@ public class StandAlone implements Runnable { /** number of dimension. **/ @Option(names = "-d", paramLabel = "DIMENSION", required = true, description = "Dimension of problem domain.") private int dimension; - /** size of tournament. **/ @Option(names = "-t", paramLabel = "TOURNAMENT_SIZE", required = true, description = "Tournament size.") private int tournamentSize; - /** size of population. **/ @Option(names = "-p", paramLabel = "POPULATION_SIZE", required = true, description = "Size of population.") private int populationSize; - /** number of generations with unchanged best fitness. **/ @Option(names = "-g", paramLabel = "GENERATIONS_EVOLVED_WITH_UNCHANGED_BEST_FITNESS", description = "No of generations evolved with unchanged best fitness (default: ${DEFAULT-VALUE}).") private int generationsEvolvedWithUnchangedBestFitness = 50; + /** indicates the absolute file path where output would be stored. **/ + @Option(names = {"-o", "--output"}, required = true, paramLabel = "OUTPUT_FILE_PATH") + private String output; + /** instance of logger. **/ + private final Logger logger = LoggerFactory.getLogger(StandAlone.class); public static void main(String[] args) { CommandLine.run(new StandAlone(), args); @@ -54,10 +65,15 @@ public void run() { // validate all input options. validateInput(); - final ParallelMathFunctionOptimizer optimizer = new ParallelMathFunctionOptimizer(); - - optimizer.optimize(dimension, tournamentSize, generationsEvolvedWithUnchangedBestFitness, populationSize); - + try (PrintWriter writer = new PrintWriter(new File(output), Charset.defaultCharset().name())) { + writer.println("Optimization Result:"); + writer.println(new ParallelMathFunctionOptimizer().optimize(dimension, tournamentSize, + generationsEvolvedWithUnchangedBestFitness, populationSize)); + } catch (FileNotFoundException e) { + logger.error("Error while writing to file", e); + } catch (UnsupportedEncodingException e) { + logger.error("Encoding not supported for writing to output file", e); + } } private void validateInput() { @@ -74,5 +90,9 @@ private void validateInput() { throw new IllegalArgumentException( "Number of generations evolved with unchanged best fitness should be >= 1."); } + File outFile = new File(output); + if (outFile.exists() && !outFile.delete()) { + throw new IllegalArgumentException("Existing output file could not be deleted."); + } } } diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/AbstractGeneticAlgorithm.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/AbstractGeneticAlgorithm.java index e06ca7fe03..fb524c1bda 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/AbstractGeneticAlgorithm.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/AbstractGeneticAlgorithm.java @@ -42,46 +42,22 @@ public abstract class AbstractGeneticAlgorithm

{ /** instance of logger. **/ private static final Logger LOGGER = LoggerFactory.getLogger(AbstractGeneticAlgorithm.class); - /** the crossover policy used by the algorithm. */ private final CrossoverPolicy

crossoverPolicy; - /** the mutation policy used by the algorithm. */ private final MutationPolicy

mutationPolicy; - /** the selection policy used by the algorithm. */ private final SelectionPolicy

selectionPolicy; - + /** the elitism rate having default value of .25. */ + private final double elitismRate; /** * the number of generations evolved to reach {@link StoppingCondition} in the * last run. */ private int generationsEvolved; - - /** The elitism rate having default value of .25. */ - private double elitismRate = .25; - - /** The registry for all interested convergence listeners. **/ + /** the registry for all interested convergence listeners. **/ private ConvergenceListenerRegistry

convergenceListenerRegistry = new ConvergenceListenerRegistry<>(); - /** - * @param crossoverPolicy The {@link CrossoverPolicy} - * @param mutationPolicy The {@link MutationPolicy} - * @param selectionPolicy The {@link SelectionPolicy} - * @param convergenceListeners An optional collection of - * {@link ConvergenceListener} with variable arity - */ - @SafeVarargs - protected AbstractGeneticAlgorithm(final CrossoverPolicy

crossoverPolicy, - final MutationPolicy

mutationPolicy, - final SelectionPolicy

selectionPolicy, - ConvergenceListener

... convergenceListeners) { - this.crossoverPolicy = crossoverPolicy; - this.mutationPolicy = mutationPolicy; - this.selectionPolicy = selectionPolicy; - updateListenerRigistry(convergenceListeners); - } - /** * @param crossoverPolicy The {@link CrossoverPolicy} * @param mutationPolicy The {@link MutationPolicy} @@ -100,13 +76,7 @@ protected AbstractGeneticAlgorithm(final CrossoverPolicy

crossoverPolicy, this.mutationPolicy = mutationPolicy; this.selectionPolicy = selectionPolicy; this.elitismRate = elitismRate; - updateListenerRigistry(convergenceListeners); - } - // suppressed warnings as the parameter is annotated as @SafeVarargs in - // constructor. - @SuppressWarnings("unchecked") - private void updateListenerRigistry(ConvergenceListener

... convergenceListeners) { if (convergenceListeners.length > 0) { for (ConvergenceListener

convergenceListener : convergenceListeners) { convergenceListenerRegistry.addConvergenceListener(convergenceListener); diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/AdaptiveGeneticAlgorithm.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/AdaptiveGeneticAlgorithm.java index 226e60455c..f8ed9e4c8e 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/AdaptiveGeneticAlgorithm.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/AdaptiveGeneticAlgorithm.java @@ -53,35 +53,11 @@ public class AdaptiveGeneticAlgorithm

extends AbstractGeneticAlgorithm

{ /** instance of logger. **/ private static final Logger LOGGER = LoggerFactory.getLogger(AdaptiveGeneticAlgorithm.class); - /** The crossover rate generator. **/ private final CrossoverRateGenerator

crossoverRateGenerator; - /** The mutation rate generator. **/ private final MutationRateGenerator

mutationRateGenerator; - /** - * @param crossoverPolicy crossover policy - * @param crossoverProbabilityGenerator crossover probability generator - * @param mutationPolicy mutation policy - * @param mutationProbabilityGenerator mutation probability generator - * @param selectionPolicy selection policy - * @param convergenceListeners An optional collection of - * {@link ConvergenceListener} with - * variable arity - */ - @SafeVarargs - public AdaptiveGeneticAlgorithm(CrossoverPolicy

crossoverPolicy, - CrossoverRateGenerator

crossoverProbabilityGenerator, - MutationPolicy

mutationPolicy, - MutationRateGenerator

mutationProbabilityGenerator, - SelectionPolicy

selectionPolicy, - ConvergenceListener

... convergenceListeners) { - super(crossoverPolicy, mutationPolicy, selectionPolicy, convergenceListeners); - this.crossoverRateGenerator = crossoverProbabilityGenerator; - this.mutationRateGenerator = mutationProbabilityGenerator; - } - /** * @param crossoverPolicy crossover policy * @param crossoverProbabilityGenerator crossover probability generator @@ -123,8 +99,7 @@ protected Population

nextGeneration(final Population

current, final Execut final int maxOffspringCount = nextGeneration.getPopulationLimit() - nextGeneration.getPopulationSize(); - final Population

offsprings = reproduceOffsprings(current, executorService, - maxOffspringCount); + final Population

offsprings = reproduceOffsprings(current, executorService, maxOffspringCount); LOGGER.debug("Performing adaptive mutation of offsprings."); @@ -139,9 +114,10 @@ private List> mutateChromosomes(final ExecutorService executorServ final Population

offspringPopulation) { // recompute the statistics of the offspring population. - final PopulationStatisticalSummary

offspringPopulationStats = ConstantMutationRateGenerator.class - .isAssignableFrom(this.mutationRateGenerator.getClass()) ? null : - new PopulationStatisticalSummaryImpl<>(offspringPopulation); + final PopulationStatisticalSummary

offspringPopulationStats = + mutationRateGenerator instanceof ConstantMutationRateGenerator ? + null : + new PopulationStatisticalSummaryImpl<>(offspringPopulation); List>> mutatedChromosomes = new ArrayList<>(); @@ -173,9 +149,10 @@ private Population

reproduceOffsprings(final Population

current, final ExecutorService executorService, final int maxOffspringCount) { // compute statistics of current generation chromosomes. - final PopulationStatisticalSummary

currentGenPopulationStats = ConstantCrossoverRateGenerator.class - .isAssignableFrom(this.crossoverRateGenerator.getClass()) ? null : - new PopulationStatisticalSummaryImpl<>(current); + final PopulationStatisticalSummary

currentGenPopulationStats = + this.crossoverRateGenerator instanceof ConstantCrossoverRateGenerator ? + null : + new PopulationStatisticalSummaryImpl<>(current); List>> chromosomePairs = new ArrayList<>(); for (int i = maxOffspringCount / 2; i > 0; i--) { chromosomePairs.add(executorService.submit(() -> { diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/GeneticAlgorithm.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/GeneticAlgorithm.java index ef37a8806c..f220754cd4 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/GeneticAlgorithm.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/GeneticAlgorithm.java @@ -43,44 +43,15 @@ public class GeneticAlgorithm

extends AbstractGeneticAlgorithm

{ /** instance of logger. **/ private static final Logger LOGGER = LoggerFactory.getLogger(GeneticAlgorithm.class); - /** crossover rate string. **/ private static final String CROSSOVER_RATE = "CROSSOVER_RATE"; - /** mutation rate string. **/ private static final String MUTATION_RATE = "MUTATION_RATE"; - /** the rate of crossover for the algorithm. */ private final double crossoverRate; - /** the rate of mutation for the algorithm. */ private final double mutationRate; - /** - * Create a new genetic algorithm. - * @param crossoverPolicy The {@link CrossoverPolicy} - * @param crossoverRate The crossover rate as a percentage (0-1 - * inclusive) - * @param mutationPolicy The {@link MutationPolicy} - * @param mutationRate The mutation rate as a percentage (0-1 inclusive) - * @param selectionPolicy The {@link SelectionPolicy} - * @param convergenceListeners An optional collection of - * {@link ConvergenceListener} with variable arity - */ - @SafeVarargs - public GeneticAlgorithm(final CrossoverPolicy

crossoverPolicy, - final double crossoverRate, - final MutationPolicy

mutationPolicy, - final double mutationRate, - final SelectionPolicy

selectionPolicy, - ConvergenceListener

... convergenceListeners) { - super(crossoverPolicy, mutationPolicy, selectionPolicy, convergenceListeners); - - checkValidity(crossoverRate, mutationRate); - this.crossoverRate = crossoverRate; - this.mutationRate = mutationRate; - } - /** * Create a new genetic algorithm. * @param crossoverPolicy The {@link CrossoverPolicy} diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/ParallelGeneticAlgorithm.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/ParallelGeneticAlgorithm.java index c5463510a8..b7df18dbe6 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/ParallelGeneticAlgorithm.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/ParallelGeneticAlgorithm.java @@ -42,7 +42,6 @@ public class ParallelGeneticAlgorithm

{ /** instance of logger. **/ private static final Logger LOGGER = LoggerFactory.getLogger(ParallelGeneticAlgorithm.class); - /** List of algorithm execution configurations to be executed in parallel. **/ private List algorithmConfigParams = new ArrayList<>(); @@ -99,7 +98,6 @@ private List> evolve(ExecutorService executorService) { } catch (InterruptedException | ExecutionException e) { throw new GeneticIllegalArgumentException(e); } - return convergedPopulations; } @@ -107,10 +105,8 @@ private final class AlgorithmExecutionConfig { /** instance of genetic algorithm. **/ private AbstractGeneticAlgorithm

algorithm; - /** initial population to converge. **/ private Population

initialPopulation; - /** stopping condition to decide convergence. **/ private StoppingCondition

stoppingCondition; @@ -121,7 +117,5 @@ private AlgorithmExecutionConfig(AbstractGeneticAlgorithm

algorithm, this.initialPopulation = initialPopulation; this.stoppingCondition = stoppingCondition; } - } - } diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/AbstractChromosome.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/AbstractChromosome.java index ccb8ed5138..d7503058ce 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/AbstractChromosome.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/AbstractChromosome.java @@ -34,18 +34,10 @@ */ public abstract class AbstractChromosome

implements Chromosome

{ - /** Value assigned when no fitness has been computed yet. */ - private static final double NO_FITNESS = Double.NEGATIVE_INFINITY; - - /** Cached value of the fitness of this chromosome. */ - private double fitness = NO_FITNESS; - /** Fitness function to evaluate fitness of chromosome. **/ private final FitnessFunction

fitnessFunction; - /** decoder to deode the chromosome's genotype representation. **/ private final Decoder

decoder; - /** Id of chromosome. **/ private final String id; @@ -84,23 +76,6 @@ public String getId() { return id; } - /** - * Access the fitness of this chromosome. The bigger the fitness, the better the - * chromosome. - *

- * Computation of fitness is usually very time-consuming task, therefore the - * fitness is cached. - * @return the fitness - */ - @Override - public double evaluate() { - if (this.fitness == NO_FITNESS) { - // no cache - compute the fitness - this.fitness = fitnessFunction.compute(decode()); - } - return this.fitness; - } - /** * Decodes the chromosome genotype and returns the phenotype. * @return chromosome phenotype @@ -123,7 +98,7 @@ public P decode() { */ @Override public int compareTo(final Chromosome

another) { - return Double.compare(evaluate(), another.evaluate()); + return Double.compare(getFitness(), another.getFitness()); } /** @@ -142,7 +117,7 @@ public boolean isSame(final AbstractChromosome

another) { /** {@inheritDoc} */ @Override public String toString() { - return String.format("(f=%s %s)", evaluate(), decode()); + return String.format("(f=%s %s)", getFitness(), decode()); } } diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/AbstractListChromosome.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/AbstractListChromosome.java index a0e873d1de..51b783daa2 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/AbstractListChromosome.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/AbstractListChromosome.java @@ -36,6 +36,8 @@ public abstract class AbstractListChromosome extends AbstractChromosome

/** List of allele/genes. */ private final List representation; + /** Fitness of this chromosome. */ + private final double fitness; /** * @param representation The representation of chromosome genotype as @@ -78,6 +80,7 @@ protected AbstractListChromosome(final List representation, super(fitnessFunction, decoder); Objects.requireNonNull(representation); this.representation = Collections.unmodifiableList(copyList ? new ArrayList<>(representation) : representation); + this.fitness = getFitnessFunction().compute(decode()); } /** @@ -119,6 +122,19 @@ public AbstractListChromosomeDecoder getDecoder() { * @return new instance extended from FixedLengthChromosome with the given * arrayRepresentation */ - public abstract AbstractListChromosome newChromosome(List chromosomeRepresentation); + public abstract AbstractListChromosome from(List chromosomeRepresentation); + + /** + * Access the fitness of this chromosome. The bigger the fitness, the better the + * chromosome. + *

+ * Computation of fitness is usually very time-consuming task, therefore the + * fitness is cached. + * @return the fitness + */ + @Override + public double getFitness() { + return this.fitness; + } } diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/BinaryChromosome.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/BinaryChromosome.java index 210b7f0519..2e96def11d 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/BinaryChromosome.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/BinaryChromosome.java @@ -35,16 +35,16 @@ public class BinaryChromosome

extends AbstractChromosome

{ * maximum allowed length of binary chromosome. */ public static final long MAX_LENGTH = Integer.MAX_VALUE; - /** * length of binary chromosome. */ private final long length; - /** * binary representation of chromosome. */ private final long[] representation; + /** Fitness of this chromosome. */ + private final double fitness; /** * @param representation Internal representation of chromosome. @@ -64,6 +64,7 @@ public BinaryChromosome(List representation, for (int i = 0; i < representation.size(); i++) { this.representation[i] = representation.get(i); } + this.fitness = getFitnessFunction().compute(decode()); } /** @@ -84,6 +85,7 @@ public BinaryChromosome(Long[] representation, for (int i = 0; i < representation.length; i++) { this.representation[i] = representation[i]; } + this.fitness = getFitnessFunction().compute(decode()); } /** @@ -106,6 +108,7 @@ public BinaryChromosome(long[] inputRepresentation, this.length = length; this.representation = new long[inputRepresentation.length]; System.arraycopy(inputRepresentation, 0, representation, 0, inputRepresentation.length); + this.fitness = getFitnessFunction().compute(decode()); } /** @@ -118,6 +121,7 @@ public BinaryChromosome(String representation, FitnessFunction

fitnessFunctio Objects.requireNonNull(representation); this.length = representation.length(); this.representation = encode(representation); + this.fitness = getFitnessFunction().compute(decode()); } /** @@ -281,7 +285,7 @@ public FitnessFunction

getFitnessFunction() { * @param chromosomeLength length of chromosome * @return new instance of chromosome */ - public BinaryChromosome

newChromosome(long[] chromosomeRepresentation, long chromosomeLength) { + public BinaryChromosome

from(long[] chromosomeRepresentation, long chromosomeLength) { return new BinaryChromosome

(chromosomeRepresentation, chromosomeLength, getFitnessFunction(), getDecoder()); } @@ -300,4 +304,16 @@ public static

BinaryChromosome

randomChromosome(int length, fitnessFunction, decoder); } + /** + * Access the fitness of this chromosome. The bigger the fitness, the better the + * chromosome. + *

+ * Computation of fitness is usually very time-consuming task, therefore the + * fitness is cached. + * @return the fitness + */ + @Override + public double getFitness() { + return this.fitness; + } } diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/Chromosome.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/Chromosome.java index 91d598b770..774f2203da 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/Chromosome.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/Chromosome.java @@ -27,12 +27,9 @@ public interface Chromosome

extends Comparable> { /** * Access the fitness of this chromosome. The bigger the fitness, the better the * chromosome. - *

- * Computation of fitness is usually very time-consuming task, therefore the - * fitness is cached. * @return the fitness */ - double evaluate(); + double getFitness(); /** * Decodes the chromosome genotype and returns the phenotype. diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/ChromosomePair.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/ChromosomePair.java index 1157a00822..08cade1943 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/ChromosomePair.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/ChromosomePair.java @@ -25,7 +25,6 @@ public class ChromosomePair

{ /** the first chromosome in the pair. */ private final Chromosome

first; - /** the second chromosome in the pair. */ private final Chromosome

second; diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/IntegralValuedChromosome.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/IntegralValuedChromosome.java index 51f9f917c4..2cd5b094bd 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/IntegralValuedChromosome.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/IntegralValuedChromosome.java @@ -33,7 +33,6 @@ public class IntegralValuedChromosome

extends AbstractListChromosome newChromosome(List chromosomeRepresentation) { + public IntegralValuedChromosome

from(List chromosomeRepresentation) { return new IntegralValuedChromosome<>(chromosomeRepresentation, getFitnessFunction(), getDecoder(), this.min, this.max); } diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/RealValuedChromosome.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/RealValuedChromosome.java index 4b1f067608..a38dce170e 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/RealValuedChromosome.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/chromosome/RealValuedChromosome.java @@ -36,7 +36,6 @@ public class RealValuedChromosome

extends AbstractListChromosome { /** minimum acceptable value of allele. **/ private final double min; - /** maximum acceptable value of allele. **/ private final double max; @@ -132,7 +131,7 @@ private void checkValidity() { * {@inheritDoc} */ @Override - public RealValuedChromosome

newChromosome(List chromosomeRepresentation) { + public RealValuedChromosome

from(List chromosomeRepresentation) { return new RealValuedChromosome<>(chromosomeRepresentation, getFitnessFunction(), getDecoder(), this.min, this.max); } diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/convergence/FixedElapsedTime.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/convergence/FixedElapsedTime.java index be98071236..6470241133 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/convergence/FixedElapsedTime.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/convergence/FixedElapsedTime.java @@ -36,7 +36,6 @@ public class FixedElapsedTime

implements StoppingCondition

{ /** Maximum allowed time period (in nanoseconds). */ private final long maxTimePeriod; - /** The predetermined termination time (stopping condition). */ private long endTime = -1; @@ -73,7 +72,6 @@ public boolean isSatisfied(Population

population) { if (endTime < 0) { endTime = System.nanoTime() + maxTimePeriod; } - return System.nanoTime() >= endTime; } diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/convergence/FixedGenerationCount.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/convergence/FixedGenerationCount.java index a80e049b9a..565bdeffe1 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/convergence/FixedGenerationCount.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/convergence/FixedGenerationCount.java @@ -30,9 +30,9 @@ * @since 2.0 */ public class FixedGenerationCount

implements StoppingCondition

{ + /** Number of generations that have passed. */ private int numGenerations; - /** Maximum number of generations (stopping criteria). */ private final int maxGenerations; diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/convergence/UnchangedBestFitness.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/convergence/UnchangedBestFitness.java index 56d9655b8b..f1ae2cd25d 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/convergence/UnchangedBestFitness.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/convergence/UnchangedBestFitness.java @@ -30,13 +30,11 @@ public class UnchangedBestFitness

implements StoppingCondition

{ /** best fitness of previous generation. **/ private double lastBestFitness = Double.MIN_VALUE; - /** * The configured number of generations for which optimization process will * continue with unchanged best fitness value. **/ private final int maxGenerationsWithUnchangedBestFitness; - /** Number of generations the best fitness value has not been changed. **/ private int generationsHavingUnchangedBestFitness; @@ -54,7 +52,7 @@ public UnchangedBestFitness(final int maxGenerationsWithUnchangedAverageFitness) */ @Override public boolean isSatisfied(Population

population) { - final double currentBestFitness = population.getFittestChromosome().evaluate(); + final double currentBestFitness = population.getFittestChromosome().getFitness(); if (lastBestFitness == currentBestFitness) { generationsHavingUnchangedBestFitness++; diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/convergence/UnchangedMeanFitness.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/convergence/UnchangedMeanFitness.java index 25bacc9a77..85055c0ade 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/convergence/UnchangedMeanFitness.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/convergence/UnchangedMeanFitness.java @@ -31,13 +31,11 @@ public class UnchangedMeanFitness

implements StoppingCondition

{ /** Mean fitness of previous generation. **/ private double lastMeanFitness = Double.MIN_VALUE; - /** * The configured number of generations for which optimization process will * continue with unchanged best fitness value. **/ private final int maxGenerationsWithUnchangedMeanFitness; - /** Number of generations the mean fitness value has not been changed. **/ private int generationsHavingUnchangedMeanFitness; @@ -66,7 +64,6 @@ public boolean isSatisfied(Population

population) { this.generationsHavingUnchangedMeanFitness = 0; lastMeanFitness = currentMeanFitness; } - return false; } @@ -78,7 +75,7 @@ public boolean isSatisfied(Population

population) { private double calculateMeanFitness(Population

population) { double totalFitness = 0.0; for (Chromosome

chromosome : population) { - totalFitness += chromosome.evaluate(); + totalFitness += chromosome.getFitness(); } return totalFitness / population.getPopulationSize(); } diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/AbstractChromosomeCrossoverPolicy.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/AbstractChromosomeCrossoverPolicy.java index 027efb47f8..a9f2b716d7 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/AbstractChromosomeCrossoverPolicy.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/AbstractChromosomeCrossoverPolicy.java @@ -19,7 +19,8 @@ import org.apache.commons.math4.ga.chromosome.Chromosome; import org.apache.commons.math4.ga.chromosome.ChromosomePair; -import org.apache.commons.math4.ga.utils.RandomProviderManager; +import org.apache.commons.rng.simple.RandomSource; +import org.apache.commons.rng.simple.ThreadLocalRandomSource; /** * An abstraction of base crossover policy. Checks the crossoverRate and decides @@ -30,6 +31,17 @@ */ public abstract class AbstractChromosomeCrossoverPolicy

implements CrossoverPolicy

{ + /** The random source for random number generation. **/ + private final RandomSource randomSource; + + /** + * Creates an abstract crossover policy and initializes the random source. + * @param randomSource random source to instantiate UniformRandomProvider. + */ + public AbstractChromosomeCrossoverPolicy(final RandomSource randomSource) { + this.randomSource = randomSource; + } + /** * {@inheritDoc} */ @@ -37,7 +49,7 @@ public abstract class AbstractChromosomeCrossoverPolicy

implements CrossoverP public ChromosomePair

crossover(final Chromosome

first, final Chromosome

second, final double crossoverRate) { - if (RandomProviderManager.getRandomProvider().nextDouble() < crossoverRate) { + if (ThreadLocalRandomSource.current(randomSource).nextDouble() < crossoverRate) { return crossover(first, second); } else { return new ChromosomePair<>(first, second); @@ -52,4 +64,11 @@ public ChromosomePair

crossover(final Chromosome

first, */ protected abstract ChromosomePair

crossover(Chromosome

first, Chromosome

second); + /** + * Returns the configured random source instance. + * @return random source. + */ + public RandomSource getRandomSource() { + return randomSource; + } } diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/AbstractListChromosomeCrossoverPolicy.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/AbstractListChromosomeCrossoverPolicy.java index 261a51f342..49c5772a90 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/AbstractListChromosomeCrossoverPolicy.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/AbstractListChromosomeCrossoverPolicy.java @@ -21,6 +21,7 @@ import org.apache.commons.math4.ga.chromosome.Chromosome; import org.apache.commons.math4.ga.chromosome.ChromosomePair; import org.apache.commons.math4.ga.internal.exception.GeneticIllegalArgumentException; +import org.apache.commons.rng.simple.RandomSource; /** * An abstraction of crossover policy for {@link AbstractListChromosome}. @@ -32,6 +33,15 @@ */ public abstract class AbstractListChromosomeCrossoverPolicy extends AbstractChromosomeCrossoverPolicy

{ + /** + * Creates an abstract crossover policy for {@link AbstractListChromosome} and + * initializes the random source. + * @param randomSource random source to instantiate UniformRandomProvider. + */ + public AbstractListChromosomeCrossoverPolicy(final RandomSource randomSource) { + super(randomSource); + } + /** * {@inheritDoc} */ @@ -65,7 +75,6 @@ private void checkValidity(final Chromosome

first, final Chromosome

second throw new GeneticIllegalArgumentException(GeneticIllegalArgumentException.SIZE_MISMATCH, secondListChromosome.getLength(), length); } - } /** diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/CycleCrossover.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/CycleCrossover.java index ff4bf348bd..169dee54b1 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/CycleCrossover.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/CycleCrossover.java @@ -23,7 +23,8 @@ import org.apache.commons.math4.ga.chromosome.AbstractListChromosome; import org.apache.commons.math4.ga.chromosome.ChromosomePair; -import org.apache.commons.math4.ga.utils.RandomProviderManager; +import org.apache.commons.rng.simple.RandomSource; +import org.apache.commons.rng.simple.ThreadLocalRandomSource; /** * Cycle Crossover [CX] builds offspring from ordered chromosomes by @@ -77,6 +78,14 @@ public CycleCrossover() { this(false); } + /** + * Constructs a new CycleCrossover policy with given random source. + * @param randomSource random source required to instantiate UniformRandomProvider. + */ + public CycleCrossover(final RandomSource randomSource) { + this(false, randomSource); + } + /** * Creates a new {@link CycleCrossover} policy using the given * {@code randomStart} behavior. @@ -85,6 +94,20 @@ public CycleCrossover() { * to 0 */ public CycleCrossover(final boolean randomStart) { + super(RandomSource.XO_RO_SHI_RO_128_PP); + this.randomStart = randomStart; + } + + /** + * Constructs a new CycleCrossover policy using the given random start behavior + * and random source. + * + * @param randomStart whether the start index shall be chosen randomly or be + * set to 0. + * @param randomSource random source required to instantiate UniformRandomProvider. + */ + public CycleCrossover(final boolean randomStart, final RandomSource randomSource) { + super(randomSource); this.randomStart = randomStart; } @@ -124,7 +147,7 @@ protected ChromosomePair

mate(final AbstractListChromosome first, final List indices = new ArrayList<>(length); // determine the starting index - int idx = randomStart ? RandomProviderManager.getRandomProvider().nextInt(length) : 0; + int idx = randomStart ? ThreadLocalRandomSource.current(getRandomSource()).nextInt(length) : 0; int cycle = 1; while (visitedIndices.size() < length) { @@ -163,6 +186,6 @@ protected ChromosomePair

mate(final AbstractListChromosome first, indices.clear(); } - return new ChromosomePair<>(first.newChromosome(child1Rep), second.newChromosome(child2Rep)); + return new ChromosomePair<>(first.from(child1Rep), second.from(child2Rep)); } } diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/NPointCrossover.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/NPointCrossover.java index 24154213d6..38124c58d3 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/NPointCrossover.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/NPointCrossover.java @@ -22,8 +22,9 @@ import org.apache.commons.math4.ga.chromosome.AbstractListChromosome; import org.apache.commons.math4.ga.chromosome.ChromosomePair; import org.apache.commons.math4.ga.internal.exception.GeneticIllegalArgumentException; -import org.apache.commons.math4.ga.utils.RandomProviderManager; import org.apache.commons.rng.UniformRandomProvider; +import org.apache.commons.rng.simple.RandomSource; +import org.apache.commons.rng.simple.ThreadLocalRandomSource; /** * N-point crossover policy. For each iteration a random crossover point is @@ -65,6 +66,27 @@ public class NPointCrossover extends AbstractListChromosomeCrossoverPolicy * @param crossoverPoints the number of crossover points */ public NPointCrossover(final int crossoverPoints) { + super(RandomSource.XO_RO_SHI_RO_128_PP); + if (crossoverPoints <= 0) { + throw new GeneticIllegalArgumentException(GeneticIllegalArgumentException.NOT_STRICTLY_POSITIVE, + crossoverPoints); + } + this.crossoverPoints = crossoverPoints; + } + + /** + * Creates a new {@link NPointCrossover} policy using the given number of + * points and random source. + *

+ * Note: the number of crossover points must be < + * chromosome length - 1. This condition can only be checked at + * runtime, as the chromosome length is not known in advance. + * + * @param crossoverPoints the number of crossover points. + * @param randomSource random source to instantiate UniformRandomProvider. + */ + public NPointCrossover(final int crossoverPoints, final RandomSource randomSource) { + super(randomSource); if (crossoverPoints <= 0) { throw new GeneticIllegalArgumentException(GeneticIllegalArgumentException.NOT_STRICTLY_POSITIVE, crossoverPoints); @@ -120,7 +142,7 @@ protected ChromosomePair

mate(final AbstractListChromosome first, final List child1Rep = new ArrayList<>(length); final List child2Rep = new ArrayList<>(length); - final UniformRandomProvider random = RandomProviderManager.getRandomProvider(); + final UniformRandomProvider random = ThreadLocalRandomSource.current(getRandomSource()); List c1 = child1Rep; List c2 = child2Rep; @@ -151,6 +173,6 @@ protected ChromosomePair

mate(final AbstractListChromosome first, c2.add(parent2Rep.get(j)); } - return new ChromosomePair<>(first.newChromosome(child1Rep), second.newChromosome(child2Rep)); + return new ChromosomePair<>(first.from(child1Rep), second.from(child2Rep)); } } diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/OnePointBinaryCrossover.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/OnePointBinaryCrossover.java index 11babc0695..f9e40a8c58 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/OnePointBinaryCrossover.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/OnePointBinaryCrossover.java @@ -20,7 +20,8 @@ import org.apache.commons.math4.ga.chromosome.Chromosome; import org.apache.commons.math4.ga.chromosome.ChromosomePair; import org.apache.commons.math4.ga.internal.exception.GeneticIllegalArgumentException; -import org.apache.commons.math4.ga.utils.RandomProviderManager; +import org.apache.commons.rng.simple.RandomSource; +import org.apache.commons.rng.simple.ThreadLocalRandomSource; /** * OnePoint Crossover Policy for Binary chromosomes. @@ -28,6 +29,23 @@ */ public class OnePointBinaryCrossover

extends AbstractChromosomeCrossoverPolicy

{ + /** + * Creates a one-point binary crossover policy and initializes the default + * random source. + */ + public OnePointBinaryCrossover() { + super(RandomSource.XO_RO_SHI_RO_128_PP); + } + + /** + * Creates a one-point binary crossover policy for {@link BinaryChromosome} with + * given random source. + * @param randomSource random source to instantiate UniformRandomProvider. + */ + public OnePointBinaryCrossover(final RandomSource randomSource) { + super(randomSource); + } + /** * {@inheritDoc} */ @@ -51,7 +69,7 @@ protected ChromosomePair

crossover(Chromosome

first, Chromosome

second) final long[] child2Rep = new long[parent2Rep.length]; // select a crossover point at random (0 and length makes no sense) - final long crossoverIndex = 1 + (RandomProviderManager.getRandomProvider().nextLong(alleleCount - 1)); + final long crossoverIndex = 1 + (ThreadLocalRandomSource.current(getRandomSource()).nextLong(alleleCount - 1)); final int offset = (int) (alleleCount % Long.SIZE == 0 ? 0 : Long.SIZE - alleleCount % Long.SIZE); final long offsettedCrossoverIndex = crossoverIndex + offset; diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/OnePointCrossover.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/OnePointCrossover.java index 2c6da54ccb..3756f3cab5 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/OnePointCrossover.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/OnePointCrossover.java @@ -21,7 +21,8 @@ import org.apache.commons.math4.ga.chromosome.AbstractListChromosome; import org.apache.commons.math4.ga.chromosome.ChromosomePair; -import org.apache.commons.math4.ga.utils.RandomProviderManager; +import org.apache.commons.rng.simple.RandomSource; +import org.apache.commons.rng.simple.ThreadLocalRandomSource; /** * One point crossover policy. A random crossover point is selected and the @@ -50,6 +51,23 @@ */ public class OnePointCrossover extends AbstractListChromosomeCrossoverPolicy { + /** + * Creates a one-point crossover operator and initializes the default random + * source. + */ + public OnePointCrossover() { + super(RandomSource.XO_RO_SHI_RO_128_PP); + } + + /** + * Creates an instance of one-point crossover operator for + * {@link AbstractListChromosome} using given random source. + * @param randomSource random source to instantiate UniformRandomProvider. + */ + public OnePointCrossover(final RandomSource randomSource) { + super(randomSource); + } + /** * Performs one point crossover. A random crossover point is selected and the * first part from each parent is copied to the corresponding child, and the @@ -83,7 +101,7 @@ protected ChromosomePair

mate(final AbstractListChromosome first, final List child2Rep = new ArrayList<>(length); // select a crossover point at random (0 and length makes no sense) - final int crossoverIndex = 1 + (RandomProviderManager.getRandomProvider().nextInt(length - 1)); + final int crossoverIndex = 1 + (ThreadLocalRandomSource.current(getRandomSource()).nextInt(length - 1)); // copy the first part for (int i = 0; i < crossoverIndex; i++) { @@ -96,7 +114,7 @@ protected ChromosomePair

mate(final AbstractListChromosome first, child2Rep.add(parent1Rep.get(i)); } - return new ChromosomePair<>(first.newChromosome(child1Rep), second.newChromosome(child2Rep)); + return new ChromosomePair<>(first.from(child1Rep), second.from(child2Rep)); } } diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/OrderedCrossover.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/OrderedCrossover.java index c53180fdf2..761650622f 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/OrderedCrossover.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/OrderedCrossover.java @@ -24,8 +24,9 @@ import org.apache.commons.math4.ga.chromosome.AbstractListChromosome; import org.apache.commons.math4.ga.chromosome.ChromosomePair; -import org.apache.commons.math4.ga.utils.RandomProviderManager; import org.apache.commons.rng.UniformRandomProvider; +import org.apache.commons.rng.simple.RandomSource; +import org.apache.commons.rng.simple.ThreadLocalRandomSource; /** * Order 1 Crossover [OX1] builds offspring from ordered chromosomes by @@ -60,6 +61,21 @@ */ public class OrderedCrossover extends AbstractListChromosomeCrossoverPolicy { + /** + * Creates an instance of ordered crossover operator with default random source. + */ + public OrderedCrossover() { + super(RandomSource.XO_RO_SHI_RO_128_PP); + } + + /** + * Creates an instance of ordered crossover operator using given random source. + * @param randomSource random source to instantiate UniformRandomProvider. + */ + public OrderedCrossover(final RandomSource randomSource) { + super(randomSource); + } + /** * Helper for {@link #crossover(Chromosome, Chromosome, double)}. Performs the * actual crossover. @@ -83,7 +99,7 @@ protected ChromosomePair

mate(final AbstractListChromosome first, final Set child1Set = new HashSet<>(length); final Set child2Set = new HashSet<>(length); - final UniformRandomProvider random = RandomProviderManager.getRandomProvider(); + final UniformRandomProvider random = ThreadLocalRandomSource.current(getRandomSource()); // choose random points, making sure that lb < ub. final int a = random.nextInt(length); int b; @@ -125,6 +141,6 @@ protected ChromosomePair

mate(final AbstractListChromosome first, Collections.rotate(child1, lb); Collections.rotate(child2, lb); - return new ChromosomePair<>(first.newChromosome(child1), second.newChromosome(child2)); + return new ChromosomePair<>(first.from(child1), second.from(child2)); } } diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/UniformCrossover.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/UniformCrossover.java index bb0f07fbe3..8607626347 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/UniformCrossover.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/UniformCrossover.java @@ -22,8 +22,9 @@ import org.apache.commons.math4.ga.chromosome.AbstractListChromosome; import org.apache.commons.math4.ga.chromosome.ChromosomePair; import org.apache.commons.math4.ga.internal.exception.GeneticIllegalArgumentException; -import org.apache.commons.math4.ga.utils.RandomProviderManager; import org.apache.commons.rng.UniformRandomProvider; +import org.apache.commons.rng.simple.RandomSource; +import org.apache.commons.rng.simple.ThreadLocalRandomSource; /** * Perform Uniform Crossover [UX] on the specified chromosomes. A fixed mixing @@ -69,6 +70,23 @@ public class UniformCrossover extends AbstractListChromosomeCrossoverPolic * @param ratio the mixing ratio */ public UniformCrossover(final double ratio) { + super(RandomSource.XO_RO_SHI_RO_128_PP); + if (ratio < 0.0d || ratio > 1.0d) { + throw new GeneticIllegalArgumentException(GeneticIllegalArgumentException.OUT_OF_RANGE, ratio, + CROSSOVER_RATE, 0.0d, 1.0d); + } + this.ratio = ratio; + } + + /** + * Creates a new UniformCrossover policy using the given mixing ratio and random + * source. + * + * @param ratio mixing ratio. + * @param randomSource random source to instantiate UniformRandomProvider. + */ + public UniformCrossover(final double ratio, final RandomSource randomSource) { + super(randomSource); if (ratio < 0.0d || ratio > 1.0d) { throw new GeneticIllegalArgumentException(GeneticIllegalArgumentException.OUT_OF_RANGE, ratio, CROSSOVER_RATE, 0.0d, 1.0d); @@ -104,7 +122,7 @@ protected ChromosomePair

mate(final AbstractListChromosome first, final List child1Rep = new ArrayList<>(length); final List child2Rep = new ArrayList<>(length); - final UniformRandomProvider random = RandomProviderManager.getRandomProvider(); + final UniformRandomProvider random = ThreadLocalRandomSource.current(getRandomSource()); for (int index = 0; index < length; index++) { @@ -118,6 +136,6 @@ protected ChromosomePair

mate(final AbstractListChromosome first, } } - return new ChromosomePair<>(first.newChromosome(child1Rep), second.newChromosome(child2Rep)); + return new ChromosomePair<>(first.from(child1Rep), second.from(child2Rep)); } } diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/rategenerator/AdaptiveLinearAverageRankBasedCrossoverRateGenerator.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/rategenerator/AdaptiveLinearAverageRankBasedCrossoverRateGenerator.java index 1b1057de0f..fc373a43f5 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/rategenerator/AdaptiveLinearAverageRankBasedCrossoverRateGenerator.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/rategenerator/AdaptiveLinearAverageRankBasedCrossoverRateGenerator.java @@ -29,7 +29,6 @@ public class AdaptiveLinearAverageRankBasedCrossoverRateGenerator

implements /** minimum crossover rate. **/ private final double minimumRate; - /** maximum crossover rate. **/ private final double maximumRate; @@ -54,5 +53,4 @@ public double generate(Chromosome

first, return minimumRate + (maximumRate - minimumRate) * (1.0 - (double) averageRank / (populationStats.getPopulationSize() - 1)); } - } diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/rategenerator/AdaptiveLinearMaximumRankBasedCrossoverRateGenerator.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/rategenerator/AdaptiveLinearMaximumRankBasedCrossoverRateGenerator.java index c03f488f5f..d929b3073b 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/rategenerator/AdaptiveLinearMaximumRankBasedCrossoverRateGenerator.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/crossover/rategenerator/AdaptiveLinearMaximumRankBasedCrossoverRateGenerator.java @@ -29,7 +29,6 @@ public class AdaptiveLinearMaximumRankBasedCrossoverRateGenerator

implements /** minimum crossover rate. **/ private final double minimumRate; - /** maximum crossover rate. **/ private final double maximumRate; diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/decoder/AbstractListChromosomeDecoder.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/decoder/AbstractListChromosomeDecoder.java index 78365080e7..bcea2590ca 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/decoder/AbstractListChromosomeDecoder.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/decoder/AbstractListChromosomeDecoder.java @@ -45,7 +45,7 @@ public P decode(Chromosome

chromosome) { * @param chromosome the {@link Chromosome} */ private void checkValidity(Chromosome

chromosome) { - if (!AbstractListChromosome.class.isAssignableFrom(chromosome.getClass())) { + if (!(chromosome instanceof AbstractListChromosome)) { throw new GeneticIllegalArgumentException(GeneticIllegalArgumentException.ILLEGAL_ARGUMENT, chromosome.getClass().getSimpleName()); } diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/internal/stats/PopulationStatisticalSummaryImpl.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/internal/stats/PopulationStatisticalSummaryImpl.java index e83c8647e0..731b66da0a 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/internal/stats/PopulationStatisticalSummaryImpl.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/internal/stats/PopulationStatisticalSummaryImpl.java @@ -37,19 +37,14 @@ public class PopulationStatisticalSummaryImpl

implements PopulationStatistica /** maximum fitness of the population. **/ private final double maxFitness; - /** minimum fitness of the population. **/ private final double minFitness; - /** mean fitness of the population. **/ private double meanFitness; - /** variance of population fitness. **/ private final double variance; - /** population size. **/ private final int populationSize; - /** a map of chromosome Id and corresponding rank in population. **/ private final Map chromosomeIdRankMap = new HashMap<>(); @@ -65,8 +60,8 @@ public PopulationStatisticalSummaryImpl(Population

population) { Collections.sort(chromosomes); this.populationSize = chromosomes.size(); - this.maxFitness = chromosomes.get(chromosomes.size() - 1).evaluate(); - this.minFitness = chromosomes.get(0).evaluate(); + this.maxFitness = chromosomes.get(chromosomes.size() - 1).getFitness(); + this.minFitness = chromosomes.get(0).getFitness(); this.meanFitness = calculateMeanFitness(chromosomes); this.variance = calculateVariance(chromosomes); @@ -145,7 +140,7 @@ public long getPopulationSize() { private double calculateMeanFitness(List> chromosomes) { double sum = 0.0; for (Chromosome

chromosome : chromosomes) { - sum += chromosome.evaluate(); + sum += chromosome.getFitness(); } return sum / chromosomes.size(); } @@ -161,7 +156,7 @@ private double calculateVariance(List> chromosomes) { } double sumOfSquare = 0.0; for (Chromosome

chromosome : chromosomes) { - sumOfSquare += Math.pow(chromosome.evaluate(), 2); + sumOfSquare += Math.pow(chromosome.getFitness(), 2); } return (sumOfSquare / chromosomes.size()) - Math.pow(this.meanFitness, 2); diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/listener/PopulationStatisticsLogger.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/listener/PopulationStatisticsLogger.java index bf1812428e..ad09ad5add 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/listener/PopulationStatisticsLogger.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/listener/PopulationStatisticsLogger.java @@ -45,5 +45,4 @@ public void notify(int generation, Population

population) { generation, populationStatisticalSummary.getMeanFitness(), populationStatisticalSummary.getMaxFitness(), populationStatisticalSummary.getFitnessVariance()); } - } diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/mutation/AbstractListChromosomeMutationPolicy.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/mutation/AbstractListChromosomeMutationPolicy.java index 3a80f68e9e..911f63d232 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/mutation/AbstractListChromosomeMutationPolicy.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/mutation/AbstractListChromosomeMutationPolicy.java @@ -25,8 +25,9 @@ import org.apache.commons.math4.ga.chromosome.AbstractListChromosome; import org.apache.commons.math4.ga.chromosome.Chromosome; import org.apache.commons.math4.ga.internal.exception.GeneticIllegalArgumentException; -import org.apache.commons.math4.ga.utils.RandomProviderManager; import org.apache.commons.rng.UniformRandomProvider; +import org.apache.commons.rng.simple.RandomSource; +import org.apache.commons.rng.simple.ThreadLocalRandomSource; /** * An abstraction of mutation operator for {@link AbstractListChromosome}. @@ -36,6 +37,17 @@ */ public abstract class AbstractListChromosomeMutationPolicy implements MutationPolicy

{ + /** The default RandomSource for random number generation. **/ + private final RandomSource randomSource; + + /** + * Initializes an abstract chromosome mutation policy with given random source. + * @param randomSource random source to instantiate UniformRandomProvide. + */ + public AbstractListChromosomeMutationPolicy(final RandomSource randomSource) { + this.randomSource = randomSource; + } + /** * Mutate the given chromosome based on mutation rate. Checks chromosome * validity and finds the mutable gene indexes. For each selected gene invokes @@ -59,7 +71,7 @@ public AbstractListChromosome mutate(Chromosome

original, double mutati newRep.set(mutableGeneIndex, mutateGene(newRep.get(mutableGeneIndex))); } - return chromosome.newChromosome(newRep); + return chromosome.from(newRep); } /** @@ -67,7 +79,7 @@ public AbstractListChromosome mutate(Chromosome

original, double mutati * @param original chromosome */ private void checkValidity(Chromosome

original) { - if (!AbstractListChromosome.class.isAssignableFrom(original.getClass())) { + if (!(original instanceof AbstractListChromosome)) { throw new GeneticIllegalArgumentException(GeneticIllegalArgumentException.ILLEGAL_ARGUMENT, original.getClass().getSimpleName()); } @@ -84,7 +96,7 @@ private Set getMutableGeneIndexes(int length, double mutationRate) { // calculate the total mutation rate of all the alleles i.e. chromosome. final double chromosomeMutationRate = mutationRate * length; final Set indexSet = new HashSet<>(); - final UniformRandomProvider randomProvider = RandomProviderManager.getRandomProvider(); + final UniformRandomProvider randomProvider = ThreadLocalRandomSource.current(randomSource); // if chromosomeMutationRate >= 1 then more than one allele will be mutated. if (chromosomeMutationRate >= 1) { @@ -95,7 +107,6 @@ private Set getMutableGeneIndexes(int length, double mutationRate) { } else if (randomProvider.nextDouble() < chromosomeMutationRate) { indexSet.add(randomProvider.nextInt(length)); } - return indexSet; } @@ -106,4 +117,12 @@ private Set getMutableGeneIndexes(int length, double mutationRate) { */ protected abstract T mutateGene(T originalValue); + /** + * Returns the configured random source instance. + * @return random source. + */ + public RandomSource getRandomSource() { + return randomSource; + } + } diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/mutation/BinaryMutation.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/mutation/BinaryMutation.java index c6582f6a9c..5837c6a41c 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/mutation/BinaryMutation.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/mutation/BinaryMutation.java @@ -25,7 +25,9 @@ import org.apache.commons.math4.ga.chromosome.BinaryChromosome; import org.apache.commons.math4.ga.chromosome.Chromosome; import org.apache.commons.math4.ga.internal.exception.GeneticIllegalArgumentException; -import org.apache.commons.math4.ga.utils.RandomProviderManager; +import org.apache.commons.rng.UniformRandomProvider; +import org.apache.commons.rng.simple.RandomSource; +import org.apache.commons.rng.simple.ThreadLocalRandomSource; /** * Mutation operator for {@link BinaryChromosome}s. Randomly changes few genes. @@ -34,6 +36,24 @@ */ public class BinaryMutation

implements MutationPolicy

{ + /** The default RandomSource for random number generation. **/ + private final RandomSource randomSource; + + /** + * Initializes a binary mutation policy with default random source. + */ + public BinaryMutation() { + this.randomSource = RandomSource.XO_RO_SHI_RO_128_PP; + } + + /** + * Initializes a binary mutation policy with provided random source. + * @param randomSource random source to instantiate UniformRandomProvider. + */ + public BinaryMutation(final RandomSource randomSource) { + this.randomSource = randomSource; + } + /** * {@inheritDoc} */ @@ -58,7 +78,7 @@ public BinaryChromosome

mutate(Chromosome

original, double mutationRate) { newRep[alleleBlockIndex] = newRep[alleleBlockIndex] ^ mask; } - return chromosome.newChromosome(newRep, chromosome.getLength()); + return chromosome.from(newRep, chromosome.getLength()); } /** @@ -66,7 +86,7 @@ public BinaryChromosome

mutate(Chromosome

original, double mutationRate) { * @param original chromosome to be mutated */ private void checkValidity(Chromosome

original) { - if (!BinaryChromosome.class.isAssignableFrom(original.getClass())) { + if (!(original instanceof BinaryChromosome)) { throw new GeneticIllegalArgumentException(GeneticIllegalArgumentException.ILLEGAL_ARGUMENT, original.getClass().getSimpleName()); } @@ -83,26 +103,27 @@ private Map> getMutableGeneIndexes(long length, double mut // calculate the total mutation rate of all the alleles i.e. chromosome. final double chromosomeMutationRate = mutationRate * length; final Map> indexMap = new HashMap<>(); + UniformRandomProvider randomProvider = ThreadLocalRandomSource.current(randomSource); // if chromosomeMutationRate >= 1 then more than one allele will be mutated. if (chromosomeMutationRate >= 1) { final int noOfMutation = (int) Math.round(chromosomeMutationRate); final Set mutationIndexes = new HashSet<>(); for (int i = 0; i < noOfMutation; i++) { - final long mutationIndex = generateMutationIndex(length, mutationIndexes); + final long mutationIndex = generateMutationIndex(length, mutationIndexes, randomProvider); mutationIndexes.add(mutationIndex); updateIndexMap(indexMap, length, mutationIndex); } - } else if (RandomProviderManager.getRandomProvider().nextDouble() < chromosomeMutationRate) { - updateIndexMap(indexMap, length); + } else if (randomProvider.nextDouble() < chromosomeMutationRate) { + updateIndexMap(indexMap, length, randomProvider); } return indexMap; } - private long generateMutationIndex(long length, Set mutationIndexes) { + private long generateMutationIndex(long length, Set mutationIndexes, UniformRandomProvider randomProvider) { long mutationIndex = 0; do { - mutationIndex = RandomProviderManager.getRandomProvider().nextLong(length); + mutationIndex = randomProvider.nextLong(length); } while (mutationIndexes.contains(mutationIndex)); return mutationIndex; } @@ -121,8 +142,10 @@ private void updateIndexMap(Map> indexMap, long length, lo indexMap.get(alleleBlockIndex).add(alleleElementIndex); } - private void updateIndexMap(Map> indexMap, long length) { - updateIndexMap(indexMap, length, RandomProviderManager.getRandomProvider().nextLong(length)); + private void updateIndexMap(Map> indexMap, + long length, + UniformRandomProvider randomProvider) { + updateIndexMap(indexMap, length, randomProvider.nextLong(length)); } } diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/mutation/IntegralValuedMutation.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/mutation/IntegralValuedMutation.java index f0952c7629..0555699de2 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/mutation/IntegralValuedMutation.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/mutation/IntegralValuedMutation.java @@ -19,7 +19,8 @@ import org.apache.commons.math4.ga.chromosome.Chromosome; import org.apache.commons.math4.ga.chromosome.IntegralValuedChromosome; import org.apache.commons.math4.ga.internal.exception.GeneticIllegalArgumentException; -import org.apache.commons.math4.ga.utils.RandomProviderManager; +import org.apache.commons.rng.simple.RandomSource; +import org.apache.commons.rng.simple.ThreadLocalRandomSource; /** * Mutation operator for {@link IntegralValuedChromosome}. Randomly changes few @@ -31,7 +32,6 @@ public class IntegralValuedMutation

extends AbstractListChromosomeMutationPol /** minimum acceptable value of allele. **/ private final int min; - /** maximum acceptable value of allele. **/ private final int max; @@ -40,6 +40,28 @@ public class IntegralValuedMutation

extends AbstractListChromosomeMutationPol * @param max maximum(exclusive) value of allele */ public IntegralValuedMutation(final int min, final int max) { + super(RandomSource.XO_RO_SHI_RO_128_PP); + this.min = min; + this.max = max; + + // To perform mutation for an IntegralValuedChromosome the minimum difference + // between + // max and min should be 2. + if ((max - min) < 2) { + throw new GeneticIllegalArgumentException(GeneticIllegalArgumentException.TOO_LARGE, min, max); + } + + } + + /** + * Constructs an IntegralValuedMutation policy with given minimum, maximum + * values and random source. + * @param min minimum value of allele + * @param max maximum(exclusive) value of allele + * @param randomSource random source to instantiate UniformRandomProvider. + */ + public IntegralValuedMutation(final int min, final int max, final RandomSource randomSource) { + super(randomSource); this.min = min; this.max = max; @@ -84,7 +106,7 @@ public IntegralValuedChromosome

mutate(Chromosome

original, double mutatio * @param original chromosome */ private void checkValidity(Chromosome

original) { - if (!IntegralValuedChromosome.class.isAssignableFrom(original.getClass())) { + if (!(original instanceof IntegralValuedChromosome)) { throw new GeneticIllegalArgumentException(GeneticIllegalArgumentException.ILLEGAL_ARGUMENT, original.getClass().getSimpleName()); } @@ -102,7 +124,7 @@ private void checkValidity(Chromosome

original) { protected Integer mutateGene(Integer originalValue) { Integer mutatedValue = 0; do { - mutatedValue = min + RandomProviderManager.getRandomProvider().nextInt(max - min); + mutatedValue = min + ThreadLocalRandomSource.current(getRandomSource()).nextInt(max - min); } while (mutatedValue.equals(originalValue)); return mutatedValue; diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/mutation/RealValuedMutation.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/mutation/RealValuedMutation.java index 54d676cb1b..c89f6367bd 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/mutation/RealValuedMutation.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/mutation/RealValuedMutation.java @@ -19,7 +19,8 @@ import org.apache.commons.math4.ga.chromosome.Chromosome; import org.apache.commons.math4.ga.chromosome.RealValuedChromosome; import org.apache.commons.math4.ga.internal.exception.GeneticIllegalArgumentException; -import org.apache.commons.math4.ga.utils.RandomProviderManager; +import org.apache.commons.rng.simple.RandomSource; +import org.apache.commons.rng.simple.ThreadLocalRandomSource; /** * Mutation operator for {@link RealValuedChromosome}. Mutates the randomly @@ -32,24 +33,54 @@ public class RealValuedMutation

extends AbstractListChromosomeMutationPolicy< /** minimum value of chromosome gene/allele. **/ private final double min; - /** maximum exclusive value of chromosome gene/allele. **/ private final double max; /** - * Constructs the mutation operator with normalized range of double values. + * Constructs the mutation operator with normalized range of double values and + * default random source. */ public RealValuedMutation() { + super(RandomSource.XO_RO_SHI_RO_128_PP); + this.min = 0d; + this.max = 1d; + } + + /** + * Constructs the mutation operator with normalized range of double values and + * provided random source. + * @param randomSource random source to instantiate UniformRandomProvider. + */ + public RealValuedMutation(RandomSource randomSource) { + super(randomSource); this.min = 0d; this.max = 1d; } /** - * Constructs the mutation operator with provided range of double values. + * Constructs the mutation operator with provided range of double values and + * default random source. * @param min minimum inclusive value of allele * @param max maximum exclusive value of allele */ public RealValuedMutation(double min, double max) { + super(RandomSource.XO_RO_SHI_RO_128_PP); + this.min = min; + this.max = max; + if (min >= max) { + throw new GeneticIllegalArgumentException(GeneticIllegalArgumentException.TOO_LARGE, min, max); + } + } + + /** + * Constructs the mutation operator with provided range of double values and + * provided random source. + * @param min minimum inclusive value of allele + * @param max maximum exclusive value of allele + * @param randomSource random source to instantiate UniformRandomProvider. + */ + public RealValuedMutation(final double min, final double max, final RandomSource randomSource) { + super(randomSource); this.min = min; this.max = max; if (min >= max) { @@ -88,7 +119,7 @@ public RealValuedChromosome

mutate(Chromosome

original, double mutationRat * @param original chromosome */ private void checkValidity(Chromosome

original) { - if (!RealValuedChromosome.class.isAssignableFrom(original.getClass())) { + if (!(original instanceof RealValuedChromosome)) { throw new GeneticIllegalArgumentException(GeneticIllegalArgumentException.ILLEGAL_ARGUMENT, original.getClass().getSimpleName()); } @@ -106,7 +137,7 @@ private void checkValidity(Chromosome

original) { protected Double mutateGene(Double originalValue) { Double mutatedValue = 0.0; do { - mutatedValue = min + RandomProviderManager.getRandomProvider().nextDouble() * (max - min); + mutatedValue = min + ThreadLocalRandomSource.current(getRandomSource()).nextDouble() * (max - min); } while (mutatedValue.equals(originalValue)); return mutatedValue; diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/mutation/rategenerator/AdaptiveLinearMutationRateGenerator.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/mutation/rategenerator/AdaptiveLinearMutationRateGenerator.java index 555465fff2..a4eb609abb 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/mutation/rategenerator/AdaptiveLinearMutationRateGenerator.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/mutation/rategenerator/AdaptiveLinearMutationRateGenerator.java @@ -29,7 +29,6 @@ public class AdaptiveLinearMutationRateGenerator

implements MutationRateGener /** minimum crossover rate. **/ private final double minimumRate; - /** maximum crossover rate. **/ private final double maximumRate; @@ -50,5 +49,4 @@ public double generate(Chromosome

chromosome, PopulationStatisticalSummary

return minimumRate + (maximumRate - minimumRate) * (1.0 - (double) populationStats.findRank(chromosome) / (populationStats.getPopulationSize() - 1)); } - } diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/mutation/rategenerator/ConstantMutationRateGenerator.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/mutation/rategenerator/ConstantMutationRateGenerator.java index ad1739bb07..c06bfa9c5f 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/mutation/rategenerator/ConstantMutationRateGenerator.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/mutation/rategenerator/ConstantMutationRateGenerator.java @@ -44,5 +44,4 @@ public ConstantMutationRateGenerator(double mutationRate) { public double generate(Chromosome

chromosome, PopulationStatisticalSummary

populationStats, int generation) { return mutationRate; } - } diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/population/ListPopulation.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/population/ListPopulation.java index 006cc4f971..a697d27038 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/population/ListPopulation.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/population/ListPopulation.java @@ -36,10 +36,8 @@ public class ListPopulation

implements Population

{ /** new line constant. **/ public static final String NEW_LINE = System.getProperty("line.separator"); - /** List of chromosomes. */ private final List> chromosomes; - /** maximal size of the population. */ private int populationLimit; @@ -213,10 +211,4 @@ public Population

nextGeneration(final double elitismRate) { return nextGeneration; } } - -// @Override -// public void addChromosomes(List> chromosomes) { -// this.chromosomes.addAll(chromosomes); -// } - } diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/selection/TournamentSelection.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/selection/TournamentSelection.java index afaf7958f8..ad850e138f 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/selection/TournamentSelection.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/selection/TournamentSelection.java @@ -25,7 +25,8 @@ import org.apache.commons.math4.ga.internal.exception.GeneticIllegalArgumentException; import org.apache.commons.math4.ga.population.ListPopulation; import org.apache.commons.math4.ga.population.Population; -import org.apache.commons.math4.ga.utils.RandomProviderManager; +import org.apache.commons.rng.simple.RandomSource; +import org.apache.commons.rng.simple.ThreadLocalRandomSource; /** * Tournament selection scheme. Each of the two selected chromosomes is selected @@ -40,13 +41,30 @@ public class TournamentSelection

implements SelectionPolicy

{ /** number of chromosomes included in the tournament selections. */ private final int arity; + /** The random source for random number generation. **/ + private final RandomSource randomSource; + /** - * Creates a new TournamentSelection instance. + * Constructs a new TournamentSelection instance with given arity and default + * random source. * * @param arity how many chromosomes will be drawn to the tournament */ public TournamentSelection(final int arity) { this.arity = arity; + this.randomSource = RandomSource.XO_RO_SHI_RO_128_PP; + } + + /** + * Constructs a new TournamentSelection instance with given arity and random + * source. + * + * @param arity how many chromosomes will be drawn to the tournament + * @param randomSource random source to instantiate UniformRandomProvider. + */ + public TournamentSelection(final int arity, final RandomSource randomSource) { + this.arity = arity; + this.randomSource = randomSource; } /** @@ -87,7 +105,7 @@ private Chromosome

tournament(final ListPopulation

population) { for (int i = 0; i < this.arity; i++) { // select a random individual and add it to the tournament - final int rind = RandomProviderManager.getRandomProvider().nextInt(chromosomes.size()); + final int rind = ThreadLocalRandomSource.current(randomSource).nextInt(chromosomes.size()); selectedChromosomes.add(chromosomes.get(rind)); // do not select it again chromosomes.remove(rind); @@ -105,5 +123,4 @@ private Chromosome

tournament(final ListPopulation

population) { public int getArity() { return arity; } - } diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/utils/ChromosomeRepresentationUtils.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/utils/ChromosomeRepresentationUtils.java index 731a108a96..5145091b25 100644 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/utils/ChromosomeRepresentationUtils.java +++ b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/utils/ChromosomeRepresentationUtils.java @@ -26,6 +26,8 @@ import org.apache.commons.math4.ga.chromosome.BinaryChromosome; import org.apache.commons.math4.ga.internal.exception.GeneticIllegalArgumentException; import org.apache.commons.rng.UniformRandomProvider; +import org.apache.commons.rng.simple.RandomSource; +import org.apache.commons.rng.simple.ThreadLocalRandomSource; /** * This interface generates all random representations for chromosomes. @@ -41,7 +43,19 @@ public interface ChromosomeRepresentationUtils { * @return representation of a random permutation */ static List randomPermutation(final int l) { - final UniformRandomProvider randomProvider = RandomProviderManager.getRandomProvider(); + return randomPermutation(l, RandomSource.XO_RO_SHI_RO_128_PP); + } + + /** + * Generates a representation corresponding to a random permutation of length l + * which can be passed to the RandomKey constructor. + * + * @param l length of the permutation + * @param randomSource random source to instantiate UniformRandomProvider. + * @return representation of a random permutation + */ + static List randomPermutation(final int l, final RandomSource randomSource) { + final UniformRandomProvider randomProvider = ThreadLocalRandomSource.current(randomSource); final List repr = new ArrayList<>(l); for (int i = 0; i < l; i++) { repr.add(randomProvider.nextDouble()); @@ -123,14 +137,30 @@ static List inducedPermutation(final List originalData, final Lis /** * Returns a representation of a random binary array of length - * length. + * length and default random source. * @param length length of the array * @param min minimum inclusive value of allele * @param max maximum exclusive value of allele * @return a random binary array of length length */ static List randomIntegralRepresentation(final int length, final int min, final int max) { - final UniformRandomProvider randomProvider = RandomProviderManager.getRandomProvider(); + return randomIntegralRepresentation(length, min, max, RandomSource.XO_RO_SHI_RO_128_PP); + } + + /** + * Returns a representation of a random binary array of length + * length. + * @param length length of the array + * @param min minimum inclusive value of allele + * @param max maximum exclusive value of allele + * @param randomSource random source to instantiate UniformRandomProvider. + * @return a random binary array of length length + */ + static List randomIntegralRepresentation(final int length, + final int min, + final int max, + final RandomSource randomSource) { + final UniformRandomProvider randomProvider = ThreadLocalRandomSource.current(randomSource); final List rList = new ArrayList<>(length); for (int j = 0; j < length; j++) { rList.add(min + randomProvider.nextInt(max - min)); @@ -140,16 +170,27 @@ static List randomIntegralRepresentation(final int length, final int mi /** * Returns a representation of a random binary array of length - * length. - * @param length length of the array + * length and default random source. + * @param length length of the array * @return a random binary array of length length */ static long[] randomBinaryRepresentation(final long length) { + return randomBinaryRepresentation(length, RandomSource.XO_RO_SHI_RO_128_PP); + } + + /** + * Returns a representation of a random binary array of length + * length. + * @param length length of the array + * @param randomSource random source to instantiate UniformRandomProvider. + * @return a random binary array of length length + */ + static long[] randomBinaryRepresentation(final long length, final RandomSource randomSource) { if (length > BinaryChromosome.MAX_LENGTH) { throw new GeneticIllegalArgumentException(GeneticIllegalArgumentException.ILLEGAL_ARGUMENT, "length exceeded the max length " + BinaryChromosome.MAX_LENGTH); } - final UniformRandomProvider randomProvider = RandomProviderManager.getRandomProvider(); + final UniformRandomProvider randomProvider = ThreadLocalRandomSource.current(randomSource); int elementCount = (int) Math.ceil(length / (double) Long.SIZE); // random binary list final long[] representation = new long[elementCount]; @@ -165,20 +206,43 @@ static long[] randomBinaryRepresentation(final long length) { /** * Generates a random string representation of chromosome with specified * characters. - * @param alleles characters representing alleles - * @param length length of chromosome + * @param alleles characters representing alleles + * @param length length of chromosome * @return returns chromosome representation as string */ static String randomStringRepresentation(char[] alleles, final long length) { + return randomStringRepresentation(alleles, length, RandomSource.XO_RO_SHI_RO_128_PP); + } + + /** + * Generates a random string representation of chromosome with specified + * characters. + * @param alleles characters representing alleles + * @param length length of chromosome + * @param randomSource random source to instantiate UniformRandomProvider. + * @return returns chromosome representation as string + */ + static String randomStringRepresentation(char[] alleles, final long length, final RandomSource randomSource) { Objects.requireNonNull(alleles); final StringBuilder representationStr = new StringBuilder(); for (int i = 0; i < length; i++) { representationStr - .append(alleles[(int) (RandomProviderManager.getRandomProvider().nextInt(alleles.length))]); + .append(alleles[(int) (ThreadLocalRandomSource.current(randomSource).nextInt(alleles.length))]); } return representationStr.toString(); } + /** + * Generates a representation corresponding to a random double values[0..1] of + * length l and provided random source. + * @param l length of the permutation + * @param randomSource random source to instantiate UniformRandomProvider. + * @return representation of a random permutation + */ + static List randomNormalizedDoubleRepresentation(final int l, final RandomSource randomSource) { + return randomDoubleRepresentation(l, 0, 1, randomSource); + } + /** * Generates a representation corresponding to a random double values[0..1] of * length l. @@ -191,23 +255,38 @@ static List randomNormalizedDoubleRepresentation(final int l) { /** * Generates a representation corresponding to a random double values of length - * l. + * l, within min and max values and default random source. * @param l length of representation * @param min minimum inclusive value of chromosome gene * @param max maximum exclusive value of chromosome gene * @return representation as List of Double */ static List randomDoubleRepresentation(final int l, double min, double max) { + return randomDoubleRepresentation(l, min, max, RandomSource.XO_RO_SHI_RO_128_PP); + } + + /** + * Generates a representation corresponding to a random double values of length + * l, within min and max values and provided random source. + * @param l length of representation + * @param min minimum inclusive value of chromosome gene + * @param max maximum exclusive value of chromosome gene + * @param randomSource random source to instantiate UniformRandomProvider. + * @return representation as List of Double + */ + static List randomDoubleRepresentation(final int l, + final double min, + final double max, + final RandomSource randomSource) { if (min >= max) { throw new GeneticIllegalArgumentException(GeneticIllegalArgumentException.TOO_LARGE, min, max); } final double range = max - min; - final UniformRandomProvider randomProvider = RandomProviderManager.getRandomProvider(); + final UniformRandomProvider randomProvider = ThreadLocalRandomSource.current(randomSource); final List repr = new ArrayList<>(l); for (int i = 0; i < l; i++) { repr.add(min + randomProvider.nextDouble() * range); } return repr; } - } diff --git a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/utils/RandomProviderManager.java b/commons-math-ga/src/main/java/org/apache/commons/math4/ga/utils/RandomProviderManager.java deleted file mode 100644 index 0c01896524..0000000000 --- a/commons-math-ga/src/main/java/org/apache/commons/math4/ga/utils/RandomProviderManager.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.commons.math4.ga.utils; - -import org.apache.commons.rng.UniformRandomProvider; -import org.apache.commons.rng.simple.RandomSource; -import org.apache.commons.rng.simple.ThreadLocalRandomSource; - -/** - * An utility to generate per thread {@link UniformRandomProvider} instance. - * @since 4.0 - */ -public final class RandomProviderManager { - - /** The default RandomSource for random number generation. **/ - private static RandomSource randomSource = RandomSource.XO_RO_SHI_RO_128_PP; - - /** - * constructs the singleton instance. - */ - private RandomProviderManager() { - } - - /** - * Returns the (static) random generator. - * @return the static random generator shared by GA implementation classes - */ - public static UniformRandomProvider getRandomProvider() { - return ThreadLocalRandomSource.current(RandomProviderManager.randomSource); - } - -} diff --git a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/GeneticAlgorithmTestBinaryOneMax.java b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/GeneticAlgorithmTestBinaryOneMax.java index 2876b8f461..d21be0ef2b 100644 --- a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/GeneticAlgorithmTestBinaryOneMax.java +++ b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/GeneticAlgorithmTestBinaryOneMax.java @@ -56,7 +56,7 @@ public void test() { // initialize a new genetic algorithm GeneticAlgorithm> ga = new GeneticAlgorithm<>(new OnePointBinaryCrossover>(), CROSSOVER_RATE, new BinaryMutation>(), MUTATION_RATE, - new TournamentSelection>(TOURNAMENT_ARITY)); + new TournamentSelection>(TOURNAMENT_ARITY), .25); Assertions.assertEquals(0, ga.getGenerationsEvolved()); @@ -147,7 +147,7 @@ public List decode(Chromosome> chromosome) { public void testCrossoverRate() { Assertions.assertThrows(GeneticIllegalArgumentException.class, () -> { new GeneticAlgorithm<>(new OnePointCrossover<>(), 1.5, new BinaryMutation<>(), .01, - new TournamentSelection<>(10)); + new TournamentSelection<>(10), .25); }); } @@ -155,7 +155,7 @@ public void testCrossoverRate() { public void testMutationRate() { Assertions.assertThrows(GeneticIllegalArgumentException.class, () -> { new GeneticAlgorithm<>(new OnePointCrossover<>(), .5, new BinaryMutation<>(), 1.5, - new TournamentSelection<>(10)); + new TournamentSelection<>(10), .25); }); } diff --git a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/GeneticAlgorithmTestPermutations.java b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/GeneticAlgorithmTestPermutations.java index 72ad0a76c8..5f3d41b101 100644 --- a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/GeneticAlgorithmTestPermutations.java +++ b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/GeneticAlgorithmTestPermutations.java @@ -117,7 +117,7 @@ private static class MinPermutations extends RealValuedChromosome> } @Override - public RealValuedChromosome> newChromosome(List chromosomeRepresentation) { + public RealValuedChromosome> from(List chromosomeRepresentation) { return new MinPermutations(chromosomeRepresentation); } diff --git a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/chromosome/AbstractChromosomeTest.java b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/chromosome/AbstractChromosomeTest.java index a682024bab..67878ee6f8 100644 --- a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/chromosome/AbstractChromosomeTest.java +++ b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/chromosome/AbstractChromosomeTest.java @@ -21,42 +21,37 @@ public class AbstractChromosomeTest { - @Test - public void testGetFitness() { - Chromosome c1 = new AbstractChromosome(chromosome -> 1, chromosome -> "1") { - }; - Assertions.assertEquals(1, c1.evaluate(), .001); - } - @Test public void testDecode() { Chromosome c1 = new AbstractChromosome(chromosome -> 1, chromosome -> "1") { - }; - Assertions.assertEquals("1", c1.decode()); - } - @Test - public void testCompareTo() { - Chromosome c1 = new AbstractChromosome(chromosome -> 0, chromosome -> "0") { - }; - Chromosome c2 = new AbstractChromosome(chromosome -> 10, chromosome -> "10") { + @Override + public double getFitness() { + return 1; + } }; - Chromosome c3 = new AbstractChromosome(chromosome -> 10, chromosome -> "10") { - }; - - Assertions.assertTrue(c1.compareTo(c2) < 0); - Assertions.assertTrue(c2.compareTo(c1) > 0); - Assertions.assertEquals(0, c3.compareTo(c2)); - Assertions.assertEquals(0, c2.compareTo(c3)); + Assertions.assertEquals("1", c1.decode()); } @Test public void testIsSame() { AbstractChromosome c1 = new AbstractChromosome(chromosome -> 1, chromosome -> "1") { + @Override + public double getFitness() { + return 1; + } }; AbstractChromosome c2 = new AbstractChromosome(chromosome -> 2, chromosome -> "2") { + @Override + public double getFitness() { + return 2; + } }; AbstractChromosome c3 = new AbstractChromosome(chromosome -> 3, chromosome -> "1") { + @Override + public double getFitness() { + return 3; + } }; Assertions.assertTrue(c1.isSame(c3)); Assertions.assertFalse(c1.isSame(c2)); diff --git a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/chromosome/AbstractListChromosomeTest.java b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/chromosome/AbstractListChromosomeTest.java new file mode 100644 index 0000000000..cb14ab29f8 --- /dev/null +++ b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/chromosome/AbstractListChromosomeTest.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.math4.ga.chromosome; + +import org.apache.commons.math4.ga.dummy.DummyListChromosome; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class AbstractListChromosomeTest { + + @Test + public void testCompareTo() { + final Integer[] repr = new Integer[] {1, 0, 1}; + Chromosome c1 = new DummyListChromosome(repr, c -> 0); + Chromosome c2 = new DummyListChromosome(repr, c -> 10); + Chromosome c3 = new DummyListChromosome(repr, c -> 10); + + Assertions.assertTrue(c1.compareTo(c2) < 0); + Assertions.assertTrue(c2.compareTo(c1) > 0); + Assertions.assertEquals(0, c3.compareTo(c2)); + Assertions.assertEquals(0, c2.compareTo(c3)); + } + + @Test + public void testGetFitness() { + final Integer[] repr = new Integer[] {1, 0, 1}; + Chromosome ch = new DummyListChromosome(repr, c -> .001); + Assertions.assertEquals(.001, ch.getFitness(), .00001); + } +} diff --git a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/chromosome/BinaryChromosomeTest.java b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/chromosome/BinaryChromosomeTest.java index 0e03c9af45..1cf53596a2 100644 --- a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/chromosome/BinaryChromosomeTest.java +++ b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/chromosome/BinaryChromosomeTest.java @@ -16,7 +16,6 @@ */ package org.apache.commons.math4.ga.chromosome; -import org.apache.commons.math4.ga.dummy.DummyListChromosomeDecoder; import org.apache.commons.math4.ga.internal.exception.GeneticIllegalArgumentException; import org.apache.commons.math4.ga.utils.ChromosomeRepresentationUtils; import org.junit.Assert; @@ -40,7 +39,7 @@ public void testInvalidConstructor() { @Test public void testRandomConstructor() { for (int i = 0; i < 20; i++) { - BinaryChromosome.randomChromosome(10, c -> 1, new DummyListChromosomeDecoder<>("1")); + BinaryChromosome.randomChromosome(10, c -> 1, c -> "0"); } } diff --git a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/chromosome/ChromosomePairTest.java b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/chromosome/ChromosomePairTest.java index f43a27ccb8..ec43f2a302 100644 --- a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/chromosome/ChromosomePairTest.java +++ b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/chromosome/ChromosomePairTest.java @@ -23,16 +23,22 @@ public class ChromosomePairTest { @Test public void testChromosomePair() { - Chromosome chromosome1 = new AbstractChromosome(c -> 0, c -> "0") { + AbstractChromosome chromosome1 = new AbstractChromosome(c -> 0, c -> "0") { + @Override + public double getFitness() { + return 1; + } }; - Chromosome chromosome2 = new AbstractChromosome(c -> 1, c -> "1") { + AbstractChromosome chromosome2 = new AbstractChromosome(c -> 1, c -> "1") { + @Override + public double getFitness() { + return 1; + } }; ChromosomePair chromosomePair = new ChromosomePair<>(chromosome1, chromosome2); - Assertions.assertEquals(chromosomePair.getFirst(), chromosome1); - Assertions.assertEquals(chromosomePair.getSecond(), chromosome2); - - Assertions.assertNotNull(chromosomePair.toString()); + Assertions.assertTrue(chromosome1.isSame((AbstractChromosome) chromosomePair.getFirst())); + Assertions.assertTrue(chromosome2.isSame((AbstractChromosome) chromosomePair.getSecond())); } } diff --git a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/chromosome/IntegralValuedChromosomeTest.java b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/chromosome/IntegralValuedChromosomeTest.java index 4766a97825..a5f34ee7ec 100644 --- a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/chromosome/IntegralValuedChromosomeTest.java +++ b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/chromosome/IntegralValuedChromosomeTest.java @@ -18,7 +18,6 @@ import org.apache.commons.math4.ga.dummy.DummyListChromosomeDecoder; import org.apache.commons.math4.ga.internal.exception.GeneticIllegalArgumentException; - import org.apache.commons.math4.ga.utils.ChromosomeRepresentationUtils; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -72,7 +71,7 @@ public void testNewChromosome() { ChromosomeRepresentationUtils.randomIntegralRepresentation(10, min, max), c -> 0, new DummyListChromosomeDecoder<>("0"), min, max); IntegralValuedChromosome newChromosome = chromosome - .newChromosome(ChromosomeRepresentationUtils.randomIntegralRepresentation(10, min, max)); + .from(ChromosomeRepresentationUtils.randomIntegralRepresentation(10, min, max)); Assertions.assertEquals(chromosome.getMin(), newChromosome.getMin()); Assertions.assertEquals(chromosome.getMax(), newChromosome.getMax()); Assertions.assertEquals(chromosome.getDecoder(), newChromosome.getDecoder()); diff --git a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/chromosome/RealValuedChromosomeTest.java b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/chromosome/RealValuedChromosomeTest.java index 65c37dc98c..a6e89ed34f 100644 --- a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/chromosome/RealValuedChromosomeTest.java +++ b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/chromosome/RealValuedChromosomeTest.java @@ -41,7 +41,7 @@ public void testNewChromosome() { RealValuedChromosome chromosome = new RealValuedChromosome<>( ChromosomeRepresentationUtils.randomDoubleRepresentation(10, 0, 1), c1 -> 1, new DummyListChromosomeDecoder<>("1")); - chromosome.newChromosome(ChromosomeRepresentationUtils.randomDoubleRepresentation(10, 0, 1)); + chromosome.from(ChromosomeRepresentationUtils.randomDoubleRepresentation(10, 0, 1)); } } diff --git a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/convergencecond/FixedGenerationCountTest.java b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/convergencecond/FixedGenerationCountTest.java index 3ebc3ec237..0389a5237d 100644 --- a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/convergencecond/FixedGenerationCountTest.java +++ b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/convergencecond/FixedGenerationCountTest.java @@ -17,7 +17,6 @@ package org.apache.commons.math4.ga.convergencecond; import org.apache.commons.math4.ga.convergence.FixedGenerationCount; - import org.apache.commons.math4.ga.internal.exception.GeneticIllegalArgumentException; import org.apache.commons.math4.ga.population.ListPopulation; import org.apache.commons.math4.ga.population.Population; diff --git a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/convergencecond/UnchangedBestFitnessTest.java b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/convergencecond/UnchangedBestFitnessTest.java index 5fffd0650a..8000d10ae0 100644 --- a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/convergencecond/UnchangedBestFitnessTest.java +++ b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/convergencecond/UnchangedBestFitnessTest.java @@ -17,13 +17,12 @@ package org.apache.commons.math4.ga.convergencecond; import java.util.ArrayList; - import java.util.List; -import org.apache.commons.math4.ga.chromosome.AbstractChromosome; import org.apache.commons.math4.ga.chromosome.Chromosome; import org.apache.commons.math4.ga.convergence.StoppingCondition; import org.apache.commons.math4.ga.convergence.UnchangedBestFitness; +import org.apache.commons.math4.ga.dummy.DummyListChromosome; import org.apache.commons.math4.ga.internal.stats.PopulationStatisticalSummaryImpl; import org.apache.commons.math4.ga.population.ListPopulation; import org.apache.commons.math4.ga.population.Population; @@ -44,9 +43,10 @@ public void testIsSatisfied() { fitnesses[i] = i; } List> chromosomes = new ArrayList<>(); + final Integer[] repr = new Integer[] {1, 0, 1}; for (int i = 0; i < 10; i++) { final double fitness = fitnesses[i]; - Chromosome ch = new AbstractChromosome(c -> fitness, c -> "Fixed") { + Chromosome ch = new DummyListChromosome(repr, c -> fitness) { }; chromosomes.add(ch); } diff --git a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/convergencecond/UnchangedMeanFitnessTest.java b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/convergencecond/UnchangedMeanFitnessTest.java index 6e4042cbfb..b788eb09c7 100644 --- a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/convergencecond/UnchangedMeanFitnessTest.java +++ b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/convergencecond/UnchangedMeanFitnessTest.java @@ -17,13 +17,12 @@ package org.apache.commons.math4.ga.convergencecond; import java.util.ArrayList; - import java.util.List; -import org.apache.commons.math4.ga.chromosome.AbstractChromosome; import org.apache.commons.math4.ga.chromosome.Chromosome; import org.apache.commons.math4.ga.convergence.StoppingCondition; import org.apache.commons.math4.ga.convergence.UnchangedMeanFitness; +import org.apache.commons.math4.ga.dummy.DummyListChromosome; import org.apache.commons.math4.ga.internal.stats.PopulationStatisticalSummaryImpl; import org.apache.commons.math4.ga.population.ListPopulation; import org.apache.commons.math4.ga.population.Population; @@ -44,9 +43,10 @@ public void testIsSatisfied() { fitnesses[i] = i; } List> chromosomes = new ArrayList<>(); + final Integer[] repr = new Integer[] {1, 0, 1}; for (int i = 0; i < 10; i++) { final double fitness = fitnesses[i]; - Chromosome ch = new AbstractChromosome(c -> fitness, c -> "Fixed") { + Chromosome ch = new DummyListChromosome(repr, c -> fitness) { }; chromosomes.add(ch); } diff --git a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/crossover/AbstractChromosomeCrossoverPolicyTest.java b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/crossover/AbstractChromosomeCrossoverPolicyTest.java index c1249b52a5..5d581f15e2 100644 --- a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/crossover/AbstractChromosomeCrossoverPolicyTest.java +++ b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/crossover/AbstractChromosomeCrossoverPolicyTest.java @@ -19,6 +19,7 @@ import org.apache.commons.math4.ga.chromosome.Chromosome; import org.apache.commons.math4.ga.chromosome.ChromosomePair; import org.apache.commons.math4.ga.dummy.DummyChromosome; +import org.apache.commons.rng.simple.RandomSource; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -27,7 +28,7 @@ public class AbstractChromosomeCrossoverPolicyTest { @Test public void testCrossoverProbability() { - CrossoverPolicy crossoverPolicy = new AbstractChromosomeCrossoverPolicy() { + CrossoverPolicy crossoverPolicy = new AbstractChromosomeCrossoverPolicy(RandomSource.XO_RO_SHI_RO_128_PP) { @Override protected ChromosomePair crossover(Chromosome first, Chromosome second) { return null; diff --git a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/crossover/AbstractListChromosomeCrossoverPolicyTest.java b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/crossover/AbstractListChromosomeCrossoverPolicyTest.java index 5500382338..f8e1e6c7d7 100644 --- a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/crossover/AbstractListChromosomeCrossoverPolicyTest.java +++ b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/crossover/AbstractListChromosomeCrossoverPolicyTest.java @@ -23,6 +23,7 @@ import org.apache.commons.math4.ga.dummy.DummyListChromosome; import org.apache.commons.math4.ga.internal.exception.GeneticIllegalArgumentException; import org.apache.commons.math4.ga.utils.ChromosomeRepresentationUtils; +import org.apache.commons.rng.simple.RandomSource; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -31,7 +32,8 @@ public class AbstractListChromosomeCrossoverPolicyTest { @Test public void testCrossoverWithNonListChromosome() { - CrossoverPolicy crossoverPolicy = new AbstractListChromosomeCrossoverPolicy() { + CrossoverPolicy crossoverPolicy = new AbstractListChromosomeCrossoverPolicy( + RandomSource.XO_RO_SHI_RO_128_PP) { @Override protected ChromosomePair mate(AbstractListChromosome first, @@ -40,9 +42,17 @@ protected ChromosomePair mate(AbstractListChromosome fi } }; Chromosome ch1 = new AbstractChromosome(c -> 0, c -> "0") { + @Override + public double getFitness() { + return 0; + } }; Chromosome ch2 = new AbstractChromosome(c -> 1, c -> "1") { + @Override + public double getFitness() { + return 1; + } }; Assertions.assertThrows(GeneticIllegalArgumentException.class, () -> { @@ -54,7 +64,8 @@ protected ChromosomePair mate(AbstractListChromosome fi @Test public void testCrossoverWithUnEqualLengthChromosome() { - CrossoverPolicy crossoverPolicy = new AbstractListChromosomeCrossoverPolicy() { + CrossoverPolicy crossoverPolicy = new AbstractListChromosomeCrossoverPolicy( + RandomSource.XO_RO_SHI_RO_128_PP) { @Override protected ChromosomePair mate(AbstractListChromosome first, diff --git a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/crossover/NPointCrossoverTest.java b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/crossover/NPointCrossoverTest.java index 2f9a8a013f..808567c9d4 100644 --- a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/crossover/NPointCrossoverTest.java +++ b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/crossover/NPointCrossoverTest.java @@ -21,6 +21,7 @@ import org.apache.commons.math4.ga.chromosome.AbstractChromosome; import org.apache.commons.math4.ga.chromosome.ChromosomePair; import org.apache.commons.math4.ga.chromosome.IntegralValuedChromosome; +import org.apache.commons.math4.ga.dummy.DummyListChromosome; import org.apache.commons.math4.ga.dummy.DummyListChromosomeDecoder; import org.apache.commons.math4.ga.internal.exception.GeneticIllegalArgumentException; import org.junit.jupiter.api.Assertions; @@ -47,11 +48,10 @@ public void testNumberIsTooLargeException() { @Test public void testCrossoverInvalidFixedLengthChromosomeFirst() { final Integer[] p1 = new Integer[] {1, 0, 1, 0, 0, 1, 0, 1, 1}; + final Integer[] p2 = new Integer[] {1, 0, 1}; final IntegralValuedChromosome p1c = new IntegralValuedChromosome(p1, chromosome -> 0, new DummyListChromosomeDecoder<>("0"), 0, 2); - final AbstractChromosome p2c = new AbstractChromosome(chromosome -> 0, - new DummyListChromosomeDecoder<>("0")) { - }; + final AbstractChromosome p2c = new DummyListChromosome(p2); final CrossoverPolicy cp = new NPointCrossover(1); @@ -68,6 +68,10 @@ public void testCrossoverInvalidFixedLengthChromosomeSecond() { new DummyListChromosomeDecoder<>("0"), 0, 2); final AbstractChromosome p1c = new AbstractChromosome(chromosome -> 0, new DummyListChromosomeDecoder<>("0")) { + @Override + public double getFitness() { + return 0; + } }; final CrossoverPolicy cp = new NPointCrossover(1); diff --git a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/decoder/AbstractListChromosomeDecoderTest.java b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/decoder/AbstractListChromosomeDecoderTest.java index fd92c0bc93..48591fc52a 100644 --- a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/decoder/AbstractListChromosomeDecoderTest.java +++ b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/decoder/AbstractListChromosomeDecoderTest.java @@ -38,7 +38,6 @@ protected String decode(AbstractListChromosome chromosome) { Assertions.assertThrows(GeneticIllegalArgumentException.class, () -> { decoder.decode(ch); }); - } } diff --git a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/decoder/RandomKeyDecoderTest.java b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/decoder/RandomKeyDecoderTest.java index 151ea36ffd..d13a7b71c6 100644 --- a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/decoder/RandomKeyDecoderTest.java +++ b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/decoder/RandomKeyDecoderTest.java @@ -50,9 +50,8 @@ public void testSequenceLength() { Double[] keys = new Double[] {0.4, 0.1, 0.5, 0.8, 0.2}; RandomKeyDecoder decoder = new RandomKeyDecoder<>(sequence); - RealValuedChromosome> chromosome = new RealValuedChromosome<>(keys, c -> 0, decoder); Assertions.assertThrows(GeneticIllegalArgumentException.class, () -> { - chromosome.decode(); + new RealValuedChromosome<>(keys, c -> 0, decoder); }); } } diff --git a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/dummy/DummyChromosome.java b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/dummy/DummyChromosome.java index 3583b3561c..58cc92c3b0 100644 --- a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/dummy/DummyChromosome.java +++ b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/dummy/DummyChromosome.java @@ -24,4 +24,9 @@ public DummyChromosome() { super(c -> 0, c -> "0"); } + @Override + public double getFitness() { + return 0; + } + } diff --git a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/dummy/DummyListChromosome.java b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/dummy/DummyListChromosome.java index 908bb43e78..09fe9c7801 100644 --- a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/dummy/DummyListChromosome.java +++ b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/dummy/DummyListChromosome.java @@ -19,6 +19,7 @@ import java.util.List; import org.apache.commons.math4.ga.chromosome.AbstractListChromosome; +import org.apache.commons.math4.ga.fitness.FitnessFunction; import org.apache.commons.math4.ga.utils.ChromosomeRepresentationUtils; /** @@ -39,8 +40,16 @@ public DummyListChromosome(final List representation) { super(representation, chromosome -> 0, new DummyListChromosomeDecoder<>("0")); } + public DummyListChromosome(final List representation, FitnessFunction fitnessFunction) { + super(representation, fitnessFunction, new DummyListChromosomeDecoder<>("0")); + } + + public DummyListChromosome(final Integer[] representation, FitnessFunction fitnessFunction) { + super(representation, fitnessFunction, new DummyListChromosomeDecoder<>("0")); + } + @Override - public DummyListChromosome newChromosome(final List chromosomeRepresentation) { + public DummyListChromosome from(final List chromosomeRepresentation) { return new DummyListChromosome(chromosomeRepresentation); } diff --git a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/mutation/BinaryMutationTest.java b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/mutation/BinaryMutationTest.java index 960a4d59dd..bfb45e5d74 100644 --- a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/mutation/BinaryMutationTest.java +++ b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/mutation/BinaryMutationTest.java @@ -43,7 +43,7 @@ public void testMutate() { // stochastic testing for single gene mutation :) for (int i = 0; i < 20; i++) { BinaryChromosome original = BinaryChromosome.randomChromosome(10, chromosome -> 0, - new DummyListChromosomeDecoder<>("0")); + c -> "0"); BinaryChromosome mutated = (BinaryChromosome) mutation.mutate(original, .1); // one gene should be different diff --git a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/mutation/IntegralValuedMutationTest.java b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/mutation/IntegralValuedMutationTest.java index f5620a671c..49585c3063 100644 --- a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/mutation/IntegralValuedMutationTest.java +++ b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/mutation/IntegralValuedMutationTest.java @@ -22,7 +22,8 @@ import org.apache.commons.math4.ga.dummy.DummyListChromosomeDecoder; import org.apache.commons.math4.ga.internal.exception.GeneticIllegalArgumentException; import org.apache.commons.math4.ga.utils.ChromosomeRepresentationUtils; -import org.apache.commons.math4.ga.utils.RandomProviderManager; +import org.apache.commons.rng.simple.RandomSource; +import org.apache.commons.rng.simple.ThreadLocalRandomSource; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -76,7 +77,7 @@ public void testMutateGene() { int max = 10; IntegralValuedMutation mutation = new IntegralValuedMutation<>(min, max); for (int i = 0; i < 100; i++) { - int origValue = min + RandomProviderManager.getRandomProvider().nextInt(max - min); + int origValue = min + ThreadLocalRandomSource.current(RandomSource.XO_RO_SHI_RO_128_PP).nextInt(max - min); int mutatedValued = mutation.mutateGene(origValue); Assertions.assertTrue(min <= mutatedValued && mutatedValued < max); Assertions.assertNotEquals(origValue, mutatedValued); diff --git a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/mutation/RealValuedMutationTest.java b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/mutation/RealValuedMutationTest.java index b0bf81ad3c..b08592146b 100644 --- a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/mutation/RealValuedMutationTest.java +++ b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/mutation/RealValuedMutationTest.java @@ -24,7 +24,8 @@ import org.apache.commons.math4.ga.dummy.DummyListChromosomeDecoder; import org.apache.commons.math4.ga.internal.exception.GeneticIllegalArgumentException; import org.apache.commons.math4.ga.utils.ChromosomeRepresentationUtils; -import org.apache.commons.math4.ga.utils.RandomProviderManager; +import org.apache.commons.rng.simple.RandomSource; +import org.apache.commons.rng.simple.ThreadLocalRandomSource; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -100,7 +101,8 @@ public void testMutateGene() { double max = 10; RealValuedMutation mutation = new RealValuedMutation<>(min, max); for (int i = 0; i < 100; i++) { - double origValue = min + (max - min) * RandomProviderManager.getRandomProvider().nextDouble(); + double origValue = min + + (max - min) * ThreadLocalRandomSource.current(RandomSource.XO_RO_SHI_RO_128_PP).nextDouble(); double mutatedValue = mutation.mutateGene(origValue); Assertions.assertTrue(min <= mutatedValue && mutatedValue < max); Assertions.assertNotEquals(origValue, mutatedValue); diff --git a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/mutation/rategenerator/ConstantMutationRateGeneratorTest.java b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/mutation/rategenerator/ConstantMutationRateGeneratorTest.java index 0c7793fdd9..c64834803f 100644 --- a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/mutation/rategenerator/ConstantMutationRateGeneratorTest.java +++ b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/mutation/rategenerator/ConstantMutationRateGeneratorTest.java @@ -21,7 +21,8 @@ import org.apache.commons.math4.ga.internal.stats.PopulationStatisticalSummaryImpl; import org.apache.commons.math4.ga.population.ListPopulation; import org.apache.commons.math4.ga.population.Population; -import org.apache.commons.math4.ga.utils.RandomProviderManager; +import org.apache.commons.rng.simple.RandomSource; +import org.apache.commons.rng.simple.ThreadLocalRandomSource; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -30,7 +31,7 @@ public class ConstantMutationRateGeneratorTest { @Test public void testGenerate() { for (int i = 0; i < 100; i++) { - double mutationRate = RandomProviderManager.getRandomProvider().nextDouble(); + double mutationRate = ThreadLocalRandomSource.current(RandomSource.XO_RO_SHI_RO_128_PP).nextDouble(); MutationRateGenerator mutationRateGenerator = new ConstantMutationRateGenerator<>(mutationRate); IntegralValuedChromosome chromosome = IntegralValuedChromosome.randomChromosome(10, c -> 0, new DummyListChromosomeDecoder<>("Fixed"), 0, 2); diff --git a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/population/ListPopulationTest.java b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/population/ListPopulationTest.java index 36044d06f2..98e9aab54c 100644 --- a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/population/ListPopulationTest.java +++ b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/population/ListPopulationTest.java @@ -19,9 +19,9 @@ import java.util.ArrayList; import java.util.Iterator; -import org.apache.commons.math4.ga.chromosome.AbstractChromosome; import org.apache.commons.math4.ga.chromosome.Chromosome; import org.apache.commons.math4.ga.chromosome.IntegralValuedChromosome; +import org.apache.commons.math4.ga.dummy.DummyListChromosome; import org.apache.commons.math4.ga.dummy.DummyListChromosomeDecoder; import org.apache.commons.math4.ga.internal.exception.GeneticIllegalArgumentException; import org.junit.jupiter.api.Assertions; @@ -31,12 +31,11 @@ public class ListPopulationTest { @Test public void testGetFittestChromosome() { - AbstractChromosome c1 = new AbstractChromosome(chromosome -> 0, chromosome -> "0") { - }; - AbstractChromosome c2 = new AbstractChromosome(chromosome -> 10, chromosome -> "10") { - }; - AbstractChromosome c3 = new AbstractChromosome(chromosome -> 15, chromosome -> "15") { + Integer[] repr = new Integer[] {0, 2, 1, 3}; + Chromosome c1 = new DummyListChromosome(repr, chromosome -> 0); + Chromosome c2 = new DummyListChromosome(repr, chromosome -> 10) { }; + Chromosome c3 = new DummyListChromosome(repr, chromosome -> 15); ArrayList> chromosomes = new ArrayList<>(); chromosomes.add(c1); diff --git a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/selection/TournamentSelectionTest.java b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/selection/TournamentSelectionTest.java index f77fb58deb..395d2c9d83 100644 --- a/commons-math-ga/src/test/java/org/apache/commons/math4/ga/selection/TournamentSelectionTest.java +++ b/commons-math-ga/src/test/java/org/apache/commons/math4/ga/selection/TournamentSelectionTest.java @@ -19,9 +19,9 @@ import java.util.Collection; import java.util.Iterator; -import org.apache.commons.math4.ga.chromosome.AbstractChromosome; import org.apache.commons.math4.ga.chromosome.Chromosome; import org.apache.commons.math4.ga.chromosome.ChromosomePair; +import org.apache.commons.math4.ga.dummy.DummyListChromosome; import org.apache.commons.math4.ga.internal.exception.GeneticIllegalArgumentException; import org.apache.commons.math4.ga.population.ListPopulation; import org.apache.commons.math4.ga.population.Population; @@ -39,26 +39,20 @@ public void testSelect() { Assertions.assertEquals(2, ts.getArity()); ListPopulation pop = new ListPopulation<>(100); + Integer[] repr = new Integer[] {0, 1, 2}; for (int i = 0; i < pop.getPopulationLimit(); i++) { - pop.addChromosome(new DummyChromosome()); + pop.addChromosome(new DummyListChromosome(repr, c -> counter++)); } // how to write a test for stochastic method? for (int i = 0; i < 20; i++) { ChromosomePair pair = ts.select(pop); // the worst chromosome should NEVER be selected - Assertions.assertTrue(pair.getFirst().evaluate() > 0); - Assertions.assertTrue(pair.getSecond().evaluate() > 0); + Assertions.assertTrue(pair.getFirst().getFitness() > 0); + Assertions.assertTrue(pair.getSecond().getFitness() > 0); } } - private static class DummyChromosome extends AbstractChromosome { - DummyChromosome() { - super(c -> counter++, c -> "0"); - } - - } - @Test public void testNonListPopulation() {