public void MutationsInAllStochasticMutationTest() { var converter = new MathExpressionConverter(MathPrimitiveSets.Default); var mut = new StochasticMutation <MathProgram>(Operators); var prog1 = converter.FromPrefixNotation("(* 2 (^ 1 4))"); var allMuts = new HashSet <MathProgram>(mut.GetAllMutations(prog1)); Console.WriteLine(prog1); foreach (var op in Operators) { var prog = op.Mutate(prog1); Console.WriteLine(prog); Assert.IsTrue(allMuts.Contains(prog), $"{prog} should be a valid mutation of {prog1}."); } }
public static void Main(string[] args) { const uint popSize = 200; const uint maxDepth = 4; const uint maxGenerations = 2000; const uint maxElementLength = 20; const uint maxNoImproveGen = (uint)(maxGenerations * 0.5); const string solutionExp = "(+ (+ x x) (+ (* 3 (* x x)) 1))"; var variable = new Variable("x"); var primitives = new PrimitiveSet <MathProgram>( new HashSet <Terminal> { variable, new Constant(0), new Constant(1), new Constant(3) }, new HashSet <MathProgram>()); primitives.Add(MathPrimitiveSets.Default); var fitnessFunction = new FitnessFunction(x => 2 * x + 3 * x * x + 1, variable, 100, -50, 50); var solution = new MathExpressionConverter(primitives).FromPrefixNotation(solutionExp); Console.WriteLine("==================================="); Console.WriteLine("Fitness: {0} | {1}", fitnessFunction.Evaluate(solution), solution); solution.ToGraphvizFile(Path.GetFullPath("."), "solution", GraphvizImageType.Png); Console.WriteLine("==================================="); var seed = new AdditionFunction(new Constant(1), variable); var elementGenerator = new StochasticProgramGenerator <MathProgram, double>( new List <IProgramGenerator <MathProgram, double> > { new GrowProgramGenerator <MathProgram, double>(), new FullProgramGenerator <MathProgram, double>() }); var selection = new TournamentSelection <MathProgram>(fitnessFunction, (uint)(popSize * 0.05)); var crossover = new StochasticCrossover <MathProgram>( new List <ICrossoverOperator <MathProgram> > { new SubtreeCrossover <MathProgram, double>(), new OnePointCrossover <MathProgram, double>(), new ContextPreservingCrossover <MathProgram, double>(), new UniformCrossover <MathProgram, double>() }); var mutation = new StochasticMutation <MathProgram>( new List <IMutationOperator <MathProgram> > { new SubtreeMutation <MathProgram, double>(elementGenerator, primitives, 1), new PointMutation <MathProgram, double>(primitives), //new ShrinkMutation(primitives), new SimplifyMutation(), new HoistMutation <MathProgram, double>() }); var pop = new Population <MathProgram, double>( popSize, primitives, elementGenerator, fitnessFunction, selection, crossover, mutation, maxDepth, maxElementLength); pop.Init(new HashSet <MathProgram> { seed }); MathProgram best = null; var numNoImproveGens = -1; for (var i = 0u; i < maxGenerations && numNoImproveGens < maxNoImproveGen; i++) { pop.Step(); var newBest = pop.BestProgram; if (best == null) { best = newBest; } var diff = fitnessFunction.Evaluate(newBest) - fitnessFunction.Evaluate(best); numNoImproveGens = diff.Equals(0) && best.Equals(newBest) ? numNoImproveGens + 1 : 0; best = newBest; Print(pop, i, fitnessFunction, diff); } best.ToGraphvizFile(Path.GetFullPath("."), "best", GraphvizImageType.Png); Console.WriteLine("==================================="); Console.WriteLine($"Best: {pop.BestProgram}, fitness: {fitnessFunction.Evaluate(pop.BestProgram):0.000}"); Console.ReadKey(); }