Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.ExpressionGenerator/HeuristicLab.ExpressionGenerator/3.4/ExpressionGenerator.cs @ 14879

Last change on this file since 14879 was 14879, checked in by gkronber, 5 years ago

#2704 added min value parameter for exp

File size: 8.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using HeuristicLab.Core;
26using HeuristicLab.Random;
27
28namespace HeuristicLab.ExpressionGenerator {
29  public static class ExpressionGenerator {
30    public static IEnumerable<Expression> GenerateRandomDistributedVariables(int numberOfVariables, string variablePrefix, IRandom randomDistribution) {
31      return Enumerable.Range(1, numberOfVariables).Select(x => Expression.RandomVariable(string.Format("{0}{1}", variablePrefix, x), randomDistribution));
32    }
33
34    public static Expression NonlinearExpression(IRandom uniformRandom, Expression[] variables, bool useLog, bool useExp) {
35      var scalingTemplate = ScaledExpression(uniformRandom, variables, varianceRandom: new UniformDistributedRandom(uniformRandom, 1, 10));
36      var scaledVars = Instantiate(scalingTemplate, uniformRandom, 100, "scaledVar");
37
38      var sumTemplate = new RandomArityTemplate(Sum, new UniformDistributedRandom(uniformRandom, 1, 3)) { Label = "+" };
39      sumTemplate.AddArguments(scaledVars);
40      var prodTemplate = new RandomArityTemplate(Product, new UniformDistributedRandom(uniformRandom, 1, 3)) { Label = "*" };
41      prodTemplate.AddArguments(variables);
42
43      var logTemplate = LogOfScaledExpression(uniformRandom, Instantiate(sumTemplate, uniformRandom, 100, "sumOfScaledVars"),
44        minValue: new UniformDistributedRandom(uniformRandom, 0.1, 2),
45        valueRange: new UniformDistributedRandom(uniformRandom, 1, 10));
46
47      var expTemplate = ExpOfScaledExpression(uniformRandom, Instantiate(prodTemplate, uniformRandom, 100, "prodOfVars"),
48        minValue: new PointDistribution(-3),
49        valueRange: new UniformDistributedRandom(uniformRandom, 4, 6));
50
51      var scaledExprTemplate = new ScalingTemplate(new UniformDistributedRandom(uniformRandom, 1, 10)) { Label = "*" };
52      if (useLog) scaledExprTemplate.AddArguments(Instantiate(logTemplate, uniformRandom, 100, "log"));
53      if (useExp) scaledExprTemplate.AddArguments(Instantiate(expTemplate, uniformRandom, 100, "exp"));
54
55      var mainTemplate = new RandomArityTemplate(Sum, new UniformDistributedRandom(uniformRandom, 3, 5));
56      mainTemplate.AddArguments(scaledVars);
57      if (useLog || useExp) {
58        mainTemplate.AddArguments(Instantiate(scaledExprTemplate, uniformRandom, 100, "scaledExpr"));
59      }
60      mainTemplate.Label = "+";
61
62      return mainTemplate.Instantiate("main", uniformRandom, false);
63    }
64
65    public static Expression Polynomial(IRandom uniformRandom, Expression[] variables, bool useLog, bool useExp) {
66      const int count = 10; // how many instances of each template should be produce?
67      int i = 1;
68      // the main template
69      var template = new RandomArityTemplate(Sum, new UniformDistributedRandom(uniformRandom, 2, count)) { Label = "+" };
70      template.AddArguments(variables);
71
72      var sumTemplate = new RandomArityTemplate(Sum, new UniformDistributedRandom(uniformRandom, 1, variables.Length)) { Label = "+" };
73      sumTemplate.AddArguments(variables);
74
75      var productTemplate = new RandomArityTemplate(Product, new UniformDistributedRandom(uniformRandom, 1, variables.Length)) { Label = "*" };
76      productTemplate.AddArguments(variables);
77
78      var inverseTemplate = new FixedArityTemplate(Division, 1) { Label = "/" };
79      inverseTemplate.AddArguments(variables);
80      inverseTemplate.AddArguments(Enumerable.Range(1, count).Select(x => sumTemplate.Instantiate(string.Format("sum{0}", i++), uniformRandom)));
81      inverseTemplate.AddArguments(Enumerable.Range(1, count).Select(x => productTemplate.Instantiate(string.Format("prod{0}", i++), uniformRandom)));
82
83      if (useLog) {
84        var logTemplate = new FixedArityTemplate(Log, 1) { Label = "log" };
85        logTemplate.AddArguments(variables);
86        logTemplate.AddArguments(Enumerable.Range(1, count).Select(x => sumTemplate.Instantiate(string.Format("sum{0}", i++), uniformRandom)));
87        template.AddArguments(Enumerable.Range(1, count).Select(x => logTemplate.Instantiate(string.Format("log{0}", i++), uniformRandom)));
88        inverseTemplate.AddArguments(Enumerable.Range(1, count).Select(x => logTemplate.Instantiate(string.Format("log{0}", i++), uniformRandom)));
89      }
90
91      if (useExp) {
92        var expTemplate = new FixedArityTemplate(Exp, 1) { Label = "exp" };
93        expTemplate.AddArguments(variables);
94        expTemplate.AddArguments(Enumerable.Range(1, count).Select(x => productTemplate.Instantiate(string.Format("prod{0}", i++), uniformRandom)));
95        template.AddArguments(Enumerable.Range(1, count).Select(x => expTemplate.Instantiate(string.Format("exp{0}", i++), uniformRandom)));
96        inverseTemplate.AddArguments(Enumerable.Range(1, count).Select(x => expTemplate.Instantiate(string.Format("exp{0}", i++), uniformRandom)));
97      }
98
99      template.AddArguments(Enumerable.Range(1, count).Select(x => inverseTemplate.Instantiate(string.Format("inv{0}", i++), uniformRandom)));
100      return template.Instantiate("polynomial", uniformRandom);
101    }
102
103    // variance random must have support only positive numbers
104    private static ExpressionTemplate ScaledExpression(IRandom uniformRandom, IEnumerable<Expression> arguments, IRandom varianceRandom) {
105      var scalingTemplate = new ScalingTemplate(scaledVariance: varianceRandom);
106      scalingTemplate.AddArguments(arguments);
107      scalingTemplate.Label = "*";
108      return scalingTemplate;
109    }
110
111    /// template scales and translates the argument expression first to guarantee positive values
112    private static ExpressionTemplate LogOfScaledExpression(IRandom uniformRandom, IEnumerable<Expression> arguments,
113      IRandom minValue = null, IRandom valueRange = null) {
114      var limitToRangeTemplate = new RangeTemplate(minValue, valueRange);
115      limitToRangeTemplate.AddArguments(arguments);
116
117      var logTemplate = new FixedArityTemplate(Log, 1) { Label = "log" };
118      logTemplate.AddArguments(Enumerable.Range(1, 100).Select(i => limitToRangeTemplate.Instantiate(string.Format("log{0}", i), uniformRandom, false)));
119      return logTemplate;
120    }
121
122    /// template scales the argument expression first to guarantee reasonable values
123    private static ExpressionTemplate ExpOfScaledExpression(IRandom uniformRandom, IEnumerable<Expression> arguments,
124      IRandom minValue = null,
125      IRandom valueRange = null) {
126      var limitToRangeTemplate = new RangeTemplate(minValue, valueRange);
127      limitToRangeTemplate.AddArguments(arguments);
128
129      var expTemplate = new FixedArityTemplate(Exp, 1) { Label = "exp" };
130      expTemplate.AddArguments(Enumerable.Range(1, 100).Select(i => limitToRangeTemplate.Instantiate(string.Format("exp{0}", i), uniformRandom, false)));
131      return expTemplate;
132    }
133
134    public static IEnumerable<Expression> Instantiate(ExpressionTemplate template, IRandom random, int count, string name) {
135      return Enumerable.Range(1, count).Select(i => template.Instantiate(name + i, random, false));
136    }
137
138    #region static functions
139    public static double Sum(IEnumerable<double> args) {
140      return args.Sum();
141    }
142
143    public static double Product(IEnumerable<double> args) {
144      return args.Aggregate((x, y) => x * y);
145    }
146
147    public static double Division(IEnumerable<double> args) {
148      if (args.Count() == 1)
149        return 1 / args.First();
150
151      return args.Aggregate((x, y) => x / y);
152    }
153
154    public static double Subtraction(IEnumerable<double> args) {
155      if (args.Count() == 1)
156        return -args.First();
157
158      return args.Aggregate((x, y) => x - y);
159    }
160
161    public static double Exp(IEnumerable<double> args) {
162      return Math.Exp(args.Single());
163    }
164
165    public static double Log(IEnumerable<double> args) {
166      return Math.Log(args.Single());
167    }
168
169    public static double Square(IEnumerable<double> args) {
170      var v = args.Single();
171      return v * v;
172    }
173    #endregion
174  }
175}
Note: See TracBrowser for help on using the repository browser.