#region License Information /* HeuristicLab * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Linq; using HeuristicLab.Core; using HeuristicLab.Random; namespace HeuristicLab.ExpressionGenerator { public static class ExpressionGenerator { public static IEnumerable GenerateRandomDistributedVariables(int numberOfVariables, string variablePrefix, IRandom randomDistribution) { return Enumerable.Range(1, numberOfVariables).Select(x => Expression.RandomVariable(string.Format("{0}{1}", variablePrefix, x), randomDistribution)); } public static Expression Polynomial(IRandom uniformRandom, Expression[] variables, bool useLog, bool useExp) { var sumTemplate = new RandomArityTemplate(Sum, new UniformDistributedRandom(uniformRandom, 1, variables.Length)) { Label = "+" }; sumTemplate.AddArguments(variables); var productTemplate = new RandomArityTemplate(Product, new UniformDistributedRandom(uniformRandom, 1, variables.Length)) { Label = "*" }; productTemplate.AddArguments(variables); const int count = 10; // how many instances of each template should be produce? int i = 1; var logTemplate = new FixedArityTemplate(Log, 1) { Label = "log" }; logTemplate.AddArguments(variables); logTemplate.AddArguments(Enumerable.Range(1, count).Select(x => sumTemplate.Instantiate(string.Format("sum{0}", i++), uniformRandom))); var expTemplate = new FixedArityTemplate(Exp, 1) { Label = "exp" }; expTemplate.AddArguments(variables); expTemplate.AddArguments(Enumerable.Range(1, count).Select(x => productTemplate.Instantiate(string.Format("prod{0}", i++), uniformRandom))); var inverseTemplate = new FixedArityTemplate(Division, 1) { Label = "/" }; inverseTemplate.AddArguments(variables); inverseTemplate.AddArguments(Enumerable.Range(1, count).Select(x => sumTemplate.Instantiate(string.Format("sum{0}", i++), uniformRandom))); inverseTemplate.AddArguments(Enumerable.Range(1, count).Select(x => productTemplate.Instantiate(string.Format("prod{0}", i++), uniformRandom))); inverseTemplate.AddArguments(Enumerable.Range(1, count).Select(x => logTemplate.Instantiate(string.Format("log{0}", i++), uniformRandom))); inverseTemplate.AddArguments(Enumerable.Range(1, count).Select(x => expTemplate.Instantiate(string.Format("exp{0}", i++), uniformRandom))); var template = new RandomArityTemplate(Sum, new UniformDistributedRandom(uniformRandom, 2, count)) { Label = "+" }; template.AddArguments(variables); template.AddArguments(Enumerable.Range(1, count).Select(x => logTemplate.Instantiate(string.Format("log{0}", i++), uniformRandom))); template.AddArguments(Enumerable.Range(1, count).Select(x => expTemplate.Instantiate(string.Format("exp{0}", i++), uniformRandom))); template.AddArguments(Enumerable.Range(1, count).Select(x => inverseTemplate.Instantiate(string.Format("inv{0}", i++), uniformRandom))); return template.Instantiate("polynomial", uniformRandom); } #region static functions private static double Sum(IEnumerable args) { return args.Sum(); } private static double Product(IEnumerable args) { return args.Aggregate((x, y) => x * y); } private static double Division(IEnumerable args) { if (args.Count() == 1) return 1 / args.First(); return args.Aggregate((x, y) => x / y); } private static double Subtraction(IEnumerable args) { if (args.Count() == 1) return -args.First(); return args.Aggregate((x, y) => x - y); } private static double Exp(IEnumerable args) { return Math.Exp(args.Single()); } private static double Log(IEnumerable args) { return Math.Log(args.Single()); } private static double Square(IEnumerable args) { var v = args.Single(); return v * v; } #endregion } }