1  #region License Information


2  /* HeuristicLab


3  * Copyright (C) 20022015 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  #endregion


23 


24  using System.Collections.Generic;


25  using HeuristicLab.Common;


26  using HeuristicLab.Core;


27  using HeuristicLab.Data;


28  using HeuristicLab.Encodings.IntegerVectorEncoding;


29  using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;


30  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;


31 


32  namespace HeuristicLab.Problems.GrammaticalEvolution {


33  /// <summary>


34  /// RandomMapper


35  /// </summary>


36  [Item("RandomMapper", "Randomly determines the next nonterminal symbol to expand.")]


37  [StorableClass]


38  public class RandomMapper : GenotypeToPhenotypeMapper {


39 


40  [StorableConstructor]


41  protected RandomMapper(bool deserializing) : base(deserializing) { }


42  protected RandomMapper(RandomMapper original, Cloner cloner) : base(original, cloner) { }


43  public RandomMapper() : base() { }


44 


45  public override IDeepCloneable Clone(Cloner cloner) {


46  return new RandomMapper(this, cloner);


47  }


48 


49 


50  /// <summary>


51  /// Maps a genotype (an integer vector) to a phenotype (a symbolic expression tree).


52  /// Random approach.


53  /// </summary>


54  /// <param name="random">random number generator</param>


55  /// <param name="bounds">only used for PIGEMapper (ignore here)</param>


56  /// <param name="length">only used for PIGEMapper (ignore here)</param>


57  /// <param name="grammar">grammar definition</param>


58  /// <param name="genotype">integer vector, which should be mapped to a tree</param>


59  /// <returns>phenotype (a symbolic expression tree)</returns>


60  public override SymbolicExpressionTree Map(IRandom random, IntMatrix bounds, int length,


61  ISymbolicExpressionGrammar grammar,


62  IntegerVector genotype) {


63 


64  SymbolicExpressionTree tree = new SymbolicExpressionTree();


65  var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode();


66  var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode();


67  rootNode.AddSubtree(startNode);


68  tree.Root = rootNode;


69 


70  MapRandomIteratively(startNode, genotype, grammar,


71  genotype.Length, random);


72 


73  return tree;


74  }


75 


76 


77  /// <summary>


78  /// GenotypetoPhenotype mapper (iterative random approach, where the next nonterminal


79  /// symbol to expand is randomly determined).


80  /// </summary>


81  /// <param name="startNode">first node of the tree with arity 1</param>


82  /// <param name="genotype">integer vector, which should be mapped to a tree</param>


83  /// <param name="grammar">grammar to determine the allowed child symbols for each node</param>


84  /// <param name="maxSubtreeCount">maximum allowed subtrees (= number of used genomes)</param>


85  /// <param name="random">random number generator</param>


86  private void MapRandomIteratively(ISymbolicExpressionTreeNode startNode,


87  IntegerVector genotype,


88  ISymbolicExpressionGrammar grammar,


89  int maxSubtreeCount, IRandom random) {


90 


91  List<ISymbolicExpressionTreeNode> nonTerminals = new List<ISymbolicExpressionTreeNode>();


92 


93  int genotypeIndex = 0;


94  nonTerminals.Add(startNode);


95 


96  while (nonTerminals.Count > 0) {


97  if (genotypeIndex >= maxSubtreeCount) {


98  // if all genomes were used, only add terminal nodes to the remaining subtrees


99  ISymbolicExpressionTreeNode current = nonTerminals[0];


100  nonTerminals.RemoveAt(0);


101  current.AddSubtree(GetRandomTerminalNode(current, grammar, random));


102  } else {


103  // similar to PIGEMapper, but here the current node is determined randomly ...


104  ISymbolicExpressionTreeNode current = nonTerminals.SelectRandom(random);


105  nonTerminals.Remove(current);


106 


107  ISymbolicExpressionTreeNode newNode = GetNewChildNode(current, genotype, grammar, genotypeIndex, random);


108  int arity = SampleArity(random, newNode, grammar);


109 


110  current.AddSubtree(newNode);


111  genotypeIndex++;


112  // new node has subtrees, so add "arity" number of copies of this node to the nonTerminals list


113  for (int i = 0; i < arity; ++i) {


114  nonTerminals.Add(newNode);


115  }


116  }


117  }


118  }


119  }


120  } 
