public void MathExpressionConverterThrowsArgumentException(string expression) { var mathExpressionConverter = new MathExpressionConverter(); var result = new TestDelegate(() => mathExpressionConverter.Convert(0d, type, expression, cultureInfo)); Assert.Throws <ArgumentException>(result); }
public void ShrinkMutationTest() { var converter = new MathExpressionConverter(MathPrimitiveSets.Default); var prog1 = converter.FromNormalNotation("((3*2)/2)"); var prog2 = converter.FromNormalNotation("(4/2)"); Console.WriteLine($"{prog1}, {prog2}"); var op = new ShrinkMutation <MathProgram, double>(ExtraPrimitiveSet); var allProgs = new HashSet <MathProgram>(op.GetAllMutations(prog1)); Assert.IsTrue(allProgs.Contains(prog2), $"{prog2} should be a valid mutation of {prog1}."); }
public void ProgInAllMutationsTest() { var converter = new MathExpressionConverter(MathPrimitiveSets.Default); var prog1 = converter.FromPrefixNotation("(+ 2 1)"); Console.WriteLine(prog1); foreach (var op in Operators) { var allProgs = new HashSet <MathProgram>(op.GetAllMutations(prog1)); Assert.IsTrue(allProgs.Contains(prog1), $"{prog1} should be a valid mutation of {prog1}."); } }
public void PointMutationTest() { var converter = new MathExpressionConverter(MathPrimitiveSets.Default); var prog1 = converter.FromNormalNotation("1"); var prog2 = converter.FromNormalNotation("4"); Console.WriteLine($"{prog1}, {prog2}"); var op = new PointMutation <MathProgram, double>(ExtraPrimitiveSet); var allProgs = new HashSet <MathProgram>(op.GetAllMutations(prog1)); Assert.IsTrue(allProgs.Contains(prog2), $"{prog2} should be a valid mutation of {prog1}."); Assert.AreEqual(allProgs.Count, 2, double.Epsilon, $"Mutation of {prog1} should only have 2 elements."); }
private static MathExpressionConverter GetConverter(out Variable xVar, out Variable yVar) { xVar = new Variable("x", new Range(-1, 1)); yVar = new Variable("y", new Range(2, 4)); var primitiveSet = new PrimitiveSet <MathProgram>( new List <Terminal> { xVar, yVar }, new MathProgram[0]); primitiveSet.Add(MathPrimitiveSets.Default); var converter = new MathExpressionConverter(primitiveSet); return(converter); }
public void NullParent2CrossoversTest() { var converter = new MathExpressionConverter(MathPrimitiveSets.Default); foreach (var op in Operators) { var prog2 = converter.FromNormalNotation("log(2,4)"); var allProgs = new HashSet <MathProgram>(op.GetAllOffspring(null, prog2)); var prog = op.Crossover(null, prog2); Assert.IsNotNull(allProgs, "Crossover list of null should not be null."); Assert.AreEqual(allProgs.Count, 0, double.Epsilon, "Crossover list of null should be empty."); Assert.IsNull(prog, "Crossover of null should be null."); } }
public void Parent2InAllCrossoversTest() { var converter = new MathExpressionConverter(MathPrimitiveSets.Default); var prog1 = converter.FromPrefixNotation("(- (+ 2 1) 3)"); var prog2 = converter.FromPrefixNotation("(/ (+ (cos 3) 1) 2)"); Console.WriteLine($"{prog1}, {prog2}"); foreach (var op in Operators) { var allProgs = new HashSet <MathProgram>(op.GetAllOffspring(prog1, prog2)); Assert.IsTrue(allProgs.Contains(prog2), $"{prog2} should be a valid crossover between {prog1} and {prog2}."); } }
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 void AllOnePointInAllUniformCrossoverTest() { var converter = new MathExpressionConverter(MathPrimitiveSets.Default); var prog1 = converter.FromPrefixNotation("(- (+ 2 1) 3)"); var prog2 = converter.FromPrefixNotation("(/ (+ (cos 3) 1) 2)"); Console.WriteLine($"{prog1}, {prog2}"); var allOnePointProgs = new HashSet <MathProgram>(new OnePointCrossover <MathProgram, double>().GetAllOffspring(prog1, prog2)); var allUniformProgs = new HashSet <MathProgram>(new UniformCrossover <MathProgram, double>().GetAllOffspring(prog1, prog2)); Assert.IsTrue(allOnePointProgs.IsSubsetOf(allUniformProgs), $"All one-point crossovers between {prog1} and {prog2} should be included in all uniform crossovers."); }
/// <inheritdoc /> public double Calculate(MathProgram prog1, MathProgram prog2) { if (prog1 == null || prog2 == null) { return(0); } if (prog1.Equals(prog2)) { return(1); } var expr1 = MathExpressionConverter.ToPrefixNotationExpression(prog1); var expr2 = MathExpressionConverter.ToPrefixNotationExpression(prog2); return(1d - (double)expr1.LevenshteinDistance(expr2) / Math.Max(expr1.Length, expr2.Length)); }
public void MathExpressionConverter_ReturnsCorrectResult( string expression, double x, double expectedResult) { var mathExpressionConverter = new MathExpressionConverter(); var result = mathExpressionConverter.Convert(x, type, expression, cultureInfo); if (result == null) { Assert.Fail(); } else { Assert.IsTrue(Math.Abs((double)result - expectedResult) < tolerance); } }
public void Sin() { var converter = new MathExpressionConverter() { ConvertExpression = "Sin(x)", ConvertBackExpression = "Asin(x)" }; var r = new Random(); for (int i = 0; i < 100; i++) { var d = r.NextDouble(); Assert.AreEqual(Math.Sin(d), (double)converter.Convert(d, typeof(double), null, null), 0.00001); Assert.AreEqual(d, (double)converter.ConvertBack(Math.Sin(d), typeof(double), null, null), 0.00001); } }
public void Square() { var converter = new MathExpressionConverter() { ConvertExpression = "x^2", ConvertBackExpression = "Sqrt(x)" }; var r = new Random(); for (int i = 0; i < 100; i++) { var d = r.NextDouble() * 100; Assert.AreEqual(d * d, (double)converter.Convert(d, typeof(double), null, null), 0.00001); Assert.AreEqual(d, (double)converter.ConvertBack(d * d, typeof(double), null, null), 0.00001); } }
internal ProgramInfo(MathExpressionConverter converter, MathProgram program) { this.NormalExpression = converter.ToNormalNotation(program); this.PrefixExpression = converter.ToPrefixNotation(program); this.Length = program.Length; this.Breadth = program.GetMaxBreadth(); this.Depth = program.GetMaxDepth(); this.SubPrograms = program.GetSubPrograms() .Select(subProg => converter.ToNormalNotation((MathProgram)subProg)).ToList(); this.SubCombinations = program.GetSubCombinations() .Select(subProg => converter.ToNormalNotation((MathProgram)subProg)).ToList(); this.Leaves = program.GetLeaves() .ToDictionary(leaf => converter.ToNormalNotation((MathProgram)leaf.Key), count => count.Value); this.Primitives = program.GetPrimitives() .ToDictionary(primitive => primitive.Key.Label, count => count.Value); }
public MainForm() { this.InitializeComponent(); // creates primitives var terminals = new List <MathProgram>(); for (var c = 'a'; c <= 'z'; c++) { terminals.Add(new Variable(c.ToString())); } var primitives = new PrimitiveSet <MathProgram>(terminals, MathPrimitiveSets.Default.Functions); // creates converter this._converter = new MathExpressionConverter(primitives); }
public void SimplifyMutationTest() { var converter = new MathExpressionConverter(MathPrimitiveSets.Default); var prog1 = converter.FromNormalNotation("((2/1)-3)"); var prog2 = converter.FromNormalNotation("-1"); Console.WriteLine($"{prog1}, {prog2}"); var op = new SimplifyMutation(); var allProgs = new HashSet <MathProgram>(op.GetAllMutations(prog1)); foreach (var mut in allProgs) { Console.WriteLine($"\t{mut}"); } Assert.IsTrue(allProgs.Contains(prog1), $"{prog2} should be a valid mutation of {prog1}."); Assert.IsTrue(allProgs.Contains(prog2), $"{prog2} should be a valid mutation of {prog1}."); Assert.AreEqual(allProgs.Count, 3, double.Epsilon, $"Mutation of {prog1} should only have 3 elements."); }
public void NoContextCrossoverTest() { var converter = new MathExpressionConverter(MathPrimitiveSets.Default); var prog1 = converter.FromNormalNotation("0"); var prog2 = converter.FromNormalNotation("((2+3)-1)"); Console.WriteLine($"{prog1}, {prog2}"); var op = new ContextPreservingCrossover <MathProgram, double>(); var allProgs = new HashSet <MathProgram>(op.GetAllOffspring(prog1, prog2)); var prog = op.Crossover(prog1, prog2); Assert.IsTrue(allProgs.Contains(prog2), $"{prog} should be a valid crossover between {prog1} and {prog2}."); Assert.IsTrue(prog.Equals(prog2), $"{prog} should be the only valid crossover between {prog1} and {prog2}."); Assert.AreEqual(allProgs.Count, 1, double.Epsilon, $"Crossover between {prog1} and {prog2} should only have 1 element."); }
public void EqualCrossoversTest() { var converter = new MathExpressionConverter(MathPrimitiveSets.Default); var prog1 = converter.FromNormalNotation("((2+3)-1)"); var prog2 = converter.FromNormalNotation("((3+2)-1)"); Console.WriteLine($"{prog1}, {prog2}"); foreach (var op in Operators) { var allProgs = new HashSet <MathProgram>(op.GetAllOffspring(prog1, prog2)); Assert.IsTrue(allProgs.Contains(prog1), $"{prog1} should be a valid crossover between {prog1} and {prog2}."); Assert.IsTrue(allProgs.Contains(prog2), $"{prog1} should be a valid crossover between {prog1} and {prog2}."); Assert.AreEqual(allProgs.Count, 1, double.Epsilon, $"Crossover between {prog1} and {prog2} should only have 1 element."); } }
private static MathProgram CreateProgram() { var a = new Variable("a"); var b = new Variable("b"); var c = new Variable("c"); var d = new Variable("d"); var e = new Variable("e"); var addition = new AdditionFunction(a, a); var subtr = new SubtractionFunction(a, a); var primitives = new PrimitiveSet <MathProgram>( new HashSet <Terminal> { a, b, c, d, e }, new HashSet <MathProgram> { addition, subtr }); var converter = new MathExpressionConverter(primitives); return(converter.FromPrefixNotation("(+ (- a b) (- c (+ d e)))")); }
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(); }