1  #region License Information


2  /* HeuristicLab


3  * Copyright (C) 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  * Author: Sabine Winkler


21  */


22 


23  #endregion


24 


25  using System.Collections.Generic;


26  using System.Linq;


27  using HEAL.Attic;


28  using HeuristicLab.Common;


29  using HeuristicLab.Core;


30  using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;


31  using HeuristicLab.Problems.DataAnalysis.Symbolic;


32  using HeuristicLab.Random;


33 


34  namespace HeuristicLab.Problems.GrammaticalEvolution {


35  [StorableType("73D43A2302FF4BD8983455D8A90E0FCE")]


36  [Item("GESymbolicExpressionGrammar", "Represents a grammar for functional expressions for grammatical evolution.")]


37  public class GESymbolicExpressionGrammar : DataAnalysisGrammar, ISymbolicDataAnalysisGrammar {


38  [StorableConstructor]


39  protected GESymbolicExpressionGrammar(StorableConstructorFlag _) : base(_) { }


40  protected GESymbolicExpressionGrammar(GESymbolicExpressionGrammar original, Cloner cloner) : base(original, cloner) { }


41  public GESymbolicExpressionGrammar()


42  : base(ItemAttribute.GetName(typeof(GESymbolicExpressionGrammar)), ItemAttribute.GetDescription(typeof(GESymbolicExpressionGrammar))) {


43  // empty ctor is necessary to allow creation of new GEGrammars from the GUI.


44  // the problem creates a new correctly configured grammar when the grammar is set


45  }


46  internal GESymbolicExpressionGrammar(IEnumerable<string> variableNames, int nConstants)


47  : base(ItemAttribute.GetName(typeof(GESymbolicExpressionGrammar)), ItemAttribute.GetDescription(typeof(GESymbolicExpressionGrammar))) {


48  // this ctor is called by the problem as only the problem knows the allowed input variables


49  Initialize(variableNames, nConstants);


50  }


51  public override IDeepCloneable Clone(Cloner cloner) {


52  return new GESymbolicExpressionGrammar(this, cloner);


53  }


54 


55  private void Initialize(IEnumerable<string> variableNames, int nConstants) {


56  #region symbol declaration


57  var add = new Addition();


58  var sub = new Subtraction();


59  var mul = new Multiplication();


60  var div = new Division();


61  var mean = new Average();


62  var log = new Logarithm();


63  var pow = new Power();


64  var square = new Square();


65  var root = new Root();


66  var sqrt = new SquareRoot();


67  var exp = new Exponential();


68 


69  // we use our own random number generator here because we assume


70  // that grammars are only initialized once when setting the grammar in the problem.


71  // This means everytime the grammar parameter in the problem is changed


72  // we initialize the constants to new values


73  var rand = new MersenneTwister();


74  // warm up


75  for (int i = 0; i < 1000; i++) rand.NextDouble();


76 


77  var constants = new List<Constant>(nConstants);


78  for (int i = 0; i < nConstants; i++) {


79  var constant = new Constant();


80  do {


81  var constVal = rand.NextDouble() * 20.0  10.0;


82  constant.Name = string.Format("{0:0.000}", constVal);


83  } while (constants.Any(c => c.Name == constant.Name)); // unlikely, but it could happen that the same constant value is sampled twice. so we resample if necessary.


84  constants.Add(constant);


85  }


86 


87  var variables = new List<HeuristicLab.Problems.DataAnalysis.Symbolic.Variable>();


88  foreach (var variableName in variableNames) {


89  var variableSymbol = new HeuristicLab.Problems.DataAnalysis.Symbolic.Variable();


90  variableSymbol.Name = variableName;


91  variableSymbol.WeightManipulatorMu = 0.0;


92  variableSymbol.WeightManipulatorSigma = 0.0;


93  variableSymbol.WeightMu = 1.0;


94  variableSymbol.WeightSigma = 0.0;


95  variableSymbol.MultiplicativeWeightManipulatorSigma = 0.0;


96  variableSymbol.AllVariableNames = new[] { variableName };


97  variableSymbol.VariableNames = new[] { variableName };


98  variables.Add(variableSymbol);


99  }


100 


101  #endregion


102 


103  AddSymbol(add);


104  AddSymbol(sub);


105  AddSymbol(mul);


106  AddSymbol(div);


107  AddSymbol(mean);


108  AddSymbol(log);


109  AddSymbol(pow);


110  AddSymbol(square);


111  AddSymbol(root);


112  AddSymbol(sqrt);


113  AddSymbol(exp);


114  constants.ForEach(AddSymbol);


115  variables.ForEach(AddSymbol);


116 


117  #region subtree count configuration


118  SetSubtreeCount(add, 2, 2);


119  SetSubtreeCount(sub, 2, 2);


120  SetSubtreeCount(mul, 2, 2);


121  SetSubtreeCount(div, 2, 2);


122  SetSubtreeCount(mean, 2, 2);


123  SetSubtreeCount(log, 1, 1);


124  SetSubtreeCount(pow, 2, 2);


125  SetSubtreeCount(square, 1, 1);


126  SetSubtreeCount(root, 2, 2);


127  SetSubtreeCount(sqrt, 1, 1);


128  SetSubtreeCount(exp, 1, 1);


129  constants.ForEach((c) => SetSubtreeCount(c, 0, 0));


130  variables.ForEach((v) => SetSubtreeCount(v, 0, 0));


131  #endregion


132 


133  var functions = new ISymbol[] { add, sub, mul, div, mean, log, pow, root, square, sqrt };


134  var terminalSymbols = variables.Concat<ISymbol>(constants);


135  var allSymbols = functions.Concat(terminalSymbols);


136 


137  #region allowed child symbols configuration


138  foreach (var s in allSymbols) {


139  AddAllowedChildSymbol(StartSymbol, s);


140  }


141  foreach (var parentSymb in functions)


142  foreach (var childSymb in allSymbols) {


143  AddAllowedChildSymbol(parentSymb, childSymb);


144  }


145 


146  #endregion


147  }


148  }


149  }

