Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -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<Coordinate> optimize(int dimension,
double minCrossoverRate,
double maxCrossoverRate,
double minMutationRate,
Expand All @@ -75,7 +91,7 @@ public void optimize(int dimension,
// best chromosome from the final population
final Chromosome<Coordinate> bestFinal = finalPopulation.getFittestChromosome();

logger.info(bestFinal.toString());
return bestFinal;
}

private static Population<Coordinate> getInitialPopulation(int dimension, int populationSize) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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);
}

}

Expand Down Expand Up @@ -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.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
*/

public final class MathFunctionOptimizer {

/** length of chromosome. **/
private static final int CHROMOSOME_LENGTH_PER_DIMENSION = 12;
/** instance of logger. **/
Expand All @@ -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<Coordinate> optimize(int dimension,
double crossoverRate,
double mutationRate,
double elitismRate,
Expand All @@ -81,7 +83,7 @@ public void optimize(int dimension,
// best chromosome from the final population
final Chromosome<Coordinate> bestFinal = finalPopulation.getFittestChromosome();

logger.info(bestFinal.toString());
return bestFinal;
}

private static Population<Coordinate> getInitialPopulation(int dimension, int populationSize) {
Expand All @@ -101,14 +103,14 @@ private static Population<Coordinate> getInitialPopulation(int dimension, int po
final BinaryChromosome<Coordinate> binaryChromosome =
(BinaryChromosome<Coordinate>) chromosome;
final long length = binaryChromosome.getLength();
final List<Double> coordinates = new ArrayList<>();
final List<Double> 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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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() {
Expand All @@ -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.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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,
Expand All @@ -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) {
Expand Down
Loading