package aima.gui.fx.applications.search.local; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.function.Function; import aima.core.search.local.FitnessFunction; import aima.core.search.local.GeneticAlgorithm.ProgressTracer; import aima.core.search.local.GeneticAlgorithmForNumbers; import aima.core.search.local.Individual; /** * Command line demo which demonstrates how the generic algorithm for numbers * can be used to find maximums in a mathematical function. * * @author Ruediger Lunde */ public class GeneticMaximumFinderDemo { private Function<Double, Double> func = Functions.f1; private double mutProb = 0.2; private int populationSize = 20; private int maxIterations = 100; private FitnessFunction<Double> fitnessFn; public static void main(String[] args) { System.out.println("Genetic Maximum Finder Experiment (f1, mutProb=0.2) -->"); GeneticMaximumFinderDemo demo = new GeneticMaximumFinderDemo(); demo.startExperiment(demo::printGeneration); System.out.println("Experiment finished."); } public void setFunction(Function<Double, Double> func) { this.func = func; } public void setMutationProb(double mutProb) { this.mutProb = mutProb; } public void setPopulationSize(int populationSize) { this.populationSize = populationSize; } public void setMaxIterations(int maxIterations) { this.maxIterations = maxIterations; } public void startExperiment(ProgressTracer<Double> pTracer) { GeneticAlgorithmForNumbers genAlgo = new GeneticAlgorithmForNumbers(1, Functions.minX, Functions.maxX, mutProb); genAlgo.addProgressTracer(pTracer); fitnessFn = ind -> func.apply(ind.getRepresentation().get(0)); List<Individual<Double>> population = new ArrayList<Individual<Double>>(); for (int i = 0; i < populationSize; i++) population.add(genAlgo.createRandomIndividual()); @SuppressWarnings("unused") Individual<Double> best = genAlgo.geneticAlgorithm(population, fitnessFn, maxIterations); } private void printGeneration(int itCount, Collection<Individual<Double>> gen) { System.out.println("\n" + getIterationInfo(itCount, gen)); List<Individual<Double>> generation = new ArrayList<>(); generation.addAll(gen); Collections.sort(generation, Comparator.comparingDouble(fitnessFn::apply)); for (Individual<Double> ind : generation) System.out.println(ind + " -> " + fitnessFn.apply(ind)); } public String getIterationInfo(int itCount, Collection<Individual<Double>> gen) { double avg = 0.0; double max = Double.NEGATIVE_INFINITY; DecimalFormat f = new DecimalFormat("#0.00"); for (Individual<Double> ind : gen) { double fval = fitnessFn.apply(ind); avg += fval; max = Math.max(max, fval); } avg /= gen.size(); return "Generation: " + itCount + " Avg: " + f.format(avg) + " Max: " + f.format(max); } }