diff --git a/api/src/main/java/org/iconic/ea/strategies/gsemo/GSEMO.java b/api/src/main/java/org/iconic/ea/strategies/gsemo/GSEMO.java index cff8ffa..9705636 100644 --- a/api/src/main/java/org/iconic/ea/strategies/gsemo/GSEMO.java +++ b/api/src/main/java/org/iconic/ea/strategies/gsemo/GSEMO.java @@ -70,11 +70,11 @@ public List evolve(List population) { // Exactly one parent is required final R parent = getSelector(0).apply(newPopulation); - // Create a single offspring by performing mutation on the parent + // Create a single offspring by performing crossover and mutation on the parent R offspring = mutate((R) parent.clone()); - // Continue mutating the offspring based on its parent's length - // reducing the probability of mutation with each attempt + // Continue evolving the offspring based on its parent's length + // reducing the probability of evolution with each attempt for (int j = 2; j <= parent.getSize(); ++j) { if ((1. / (double) j) >= ThreadLocalRandom.current().nextDouble()) { offspring = mutate(offspring); diff --git a/cli/src/main/java/org/iconic/Client.java b/cli/src/main/java/org/iconic/Client.java index c9c0797..456adad 100644 --- a/cli/src/main/java/org/iconic/Client.java +++ b/cli/src/main/java/org/iconic/Client.java @@ -19,10 +19,10 @@ import lombok.extern.log4j.Log4j2; import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVPrinter; +import org.iconic.ea.chromosome.cartesian.CartesianChromosome; import org.iconic.ea.strategies.EvolutionaryAlgorithm; import org.iconic.ea.chromosome.Chromosome; import org.iconic.ea.chromosome.ChromosomeFactory; -import org.iconic.ea.chromosome.cartesian.CartesianChromosome; import org.iconic.ea.chromosome.cartesian.CartesianChromosomeFactory; import org.iconic.ea.data.DataManager; import org.iconic.ea.data.FeatureClass; @@ -51,6 +51,7 @@ import java.time.Instant; import java.util.*; import java.util.List; +import java.util.concurrent.ThreadLocalRandom; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -96,7 +97,7 @@ public static void main(String[] args) { log.info("Feature Size: {}", () -> featureSize - 1); log.info("Sample Size: {}", () -> sampleSize); - // Create a supplier for Gene Expression Programming chromosomes + // Create a supplier for Gene Cartesian Programming chromosomes List inputs = new ArrayList<>(featureSize - 1); for (int i = 0; i < featureSize - 1; ++i) { inputs.add(String.valueOf(i)); @@ -116,6 +117,19 @@ public static void main(String[] args) { new Division(), new Power(), new Exponential(), new Sin(), new Cos() )); + final int numConstants = 100; + final int min = -100; + final int max = 100; + final List> constants = new ArrayList<>(numConstants); + + while (constants.size() < numConstants) { + constants.add(new Constant<>(ThreadLocalRandom.current().nextDouble( + min, max + ))); + } + + supplier.addFunction(constants); + final int generations = client.getArgs().getGenerations(); final Set> nonDominatedFinal = new LinkedHashSet<>(); final List>> nonDominatedAll = new ArrayList<>(generations); @@ -181,6 +195,7 @@ public static void main(String[] args) { graphWriter.write(series.draw()); } + graphWriter.setAxesLogarithmic(true); graphWriter.export("All Generations - Non-Dominated", directory, "results-all"); graphWriter.clear(); @@ -192,6 +207,7 @@ public static void main(String[] args) { nonDominatedFinal.forEach(seriesWriter::write); graphWriter.write(seriesWriter.draw()); + graphWriter.setAxesLogarithmic(true); graphWriter.export("Last Generation - Non-Dominated", directory, "results-last"); // Create a map of global best values so we can graph just their solution-fit plots @@ -327,6 +343,9 @@ private static void exportCsv( new FileWriter(new File(directory + "//" + fileName + ".csv")), CSVFormat.EXCEL )) { + printer.printRecord( + "Mean Squared Error", "Size", "Model" + ); for (final Chromosome chromosome : population) { printer.printRecord( chromosome.getFitness(), chromosome.getSize(), chromosome.toString() @@ -349,7 +368,7 @@ private static EvolutionaryAlgorithm, Double> getEvo // Create the evolutionary algorithm EvolutionaryAlgorithm, Double> ea = // TODO: generify with a factory so it isn't always GSEMO - new GSEMO<>(supplier, 1); + new GSEMO<>(supplier, 4); ea.setCrossoverProbability(args.getCrossoverProbability()); ea.setMutationProbability(args.getMutationProbability()); diff --git a/cli/src/main/java/org/iconic/utils/GraphWriter.java b/cli/src/main/java/org/iconic/utils/GraphWriter.java index 68c590d..3b9f546 100644 --- a/cli/src/main/java/org/iconic/utils/GraphWriter.java +++ b/cli/src/main/java/org/iconic/utils/GraphWriter.java @@ -16,6 +16,7 @@ package org.iconic.utils; import org.iconic.ea.chromosome.Chromosome; +import org.knowm.xchart.BitmapEncoder; import org.knowm.xchart.VectorGraphicsEncoder; import org.knowm.xchart.internal.chartpart.Chart; import org.knowm.xchart.internal.series.Series; @@ -25,6 +26,7 @@ public abstract class GraphWriter { private boolean axesTruncated; + private boolean axesLogarithmic; /** * Constructs a new GraphWriter that will truncate outliers from its axes by default. @@ -48,9 +50,9 @@ public abstract class GraphWriter { public void export(final String chartTitle, final String directory, final String fileName) throws IOException { Chart chart = draw(); chart.setTitle(chartTitle); - VectorGraphicsEncoder.saveVectorGraphic( + BitmapEncoder.saveBitmap( chart, directory + "//" + fileName, - VectorGraphicsEncoder.VectorGraphicsFormat.PDF + BitmapEncoder.BitmapFormat.PNG ); } @@ -71,10 +73,24 @@ public boolean isAxesTruncated() { return axesTruncated; } + /** + * @return True if axes of the graph written by the GraphWriter will use logarithmic scaling. + */ + public boolean isAxesLogarithmic() { + return axesLogarithmic; + } + /** * @param truncate True if the axes of the graph being written should remove outliers. */ public void setAxesTruncated(boolean truncate) { this.axesTruncated = truncate; } + + /** + * @param logarithmic True if the axes of the graph being written should use logarithmic scaling. + */ + public void setAxesLogarithmic(boolean logarithmic) { + this.axesLogarithmic = logarithmic; + } } diff --git a/cli/src/main/java/org/iconic/utils/XYGraphWriter.java b/cli/src/main/java/org/iconic/utils/XYGraphWriter.java index 3bf6e54..c4f6aca 100644 --- a/cli/src/main/java/org/iconic/utils/XYGraphWriter.java +++ b/cli/src/main/java/org/iconic/utils/XYGraphWriter.java @@ -179,7 +179,10 @@ private XYChart getChart() { .theme(Styler.ChartTheme.Matlab).build(); chart.getStyler().setChartTitleVisible(true); chart.getStyler().setMarkerSize(12); - chart.getStyler().setXAxisLogarithmic(true); + + if (isAxesLogarithmic()) { + chart.getStyler().setXAxisLogarithmic(true); + } } return chart;