1  #region License Information


2  /* HeuristicLab


3  * Copyright (C) 20022013 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 


22  using System.Collections.Generic;


23  using System.Linq;


24  using HeuristicLab.Common;


25  using HeuristicLab.Core;


26  using HeuristicLab.Encodings.IntegerVectorEncoding;


27  using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;


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


29  using HeuristicLab.Problems.GrammaticalEvolution.Mappers;


30 


31  namespace HeuristicLab.Problems.GrammaticalEvolution {


32  /// <summary>


33  /// GenotypeToPhenotypeMapper


34  /// </summary>


35  public abstract class GenotypeToPhenotypeMapper : IntegerVectorOperator, IGenotypeToPhenotypeMapper {


36 


37  [StorableConstructor]


38  protected GenotypeToPhenotypeMapper(bool deserializing) : base(deserializing) { }


39  protected GenotypeToPhenotypeMapper(GenotypeToPhenotypeMapper original, Cloner cloner) : base(original, cloner) { }


40  protected GenotypeToPhenotypeMapper() : base() { }


41 


42  public abstract SymbolicExpressionTree Map(ISymbolicExpressionGrammar grammar,


43  IntegerVector genotype);


44 


45  /// <summary>


46  /// Randomly returns a terminal node for the given <paramref name="parentNode"/>.


47  /// (A terminal has got a minimum and maximum arity of 0.)


48  /// </summary>


49  /// <param name="parentNode">parent node for which a child node is returned randomly</param>


50  /// <param name="grammar">grammar to determine the allowed child symbols for parentNode</param>


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


52  /// <returns>randomly chosen terminal node with arity 0 or null, if no terminal node exists</returns>


53  protected ISymbolicExpressionTreeNode GetRandomTerminalNode(ISymbolicExpressionTreeNode parentNode,


54  ISymbolicExpressionGrammar grammar,


55  IRandom random) {


56  // only select specific symbols, which can be interpreted ...


57  var possibleSymbolsList = (from s in grammar.GetAllowedChildSymbols(parentNode.Symbol)


58  where s.InitialFrequency > 0.0


59  where s.MaximumArity == 0


60  where s.MinimumArity == 0


61  select s).ToList();


62 


63  // no terminal node exists for the given parent node


64  if (possibleSymbolsList.Count() < 1) return null;


65 


66  var newNode = possibleSymbolsList.SelectRandom(random).CreateTreeNode();


67  if (newNode.HasLocalParameters) newNode.ResetLocalParameters(random);


68  return newNode;


69  }


70 


71 


72  /// <summary>


73  /// Returns a randomly chosen child node for the given <paramref name="parentNode"/>.


74  /// </summary>


75  /// <param name="parentNode">parent node to find a child node randomly for</param>


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


77  /// <param name="grammar">grammar used to define the allowed child symbols</param>


78  /// <param name="genotypeIndex">index in the integer vector; can be greater than vector length</param>


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


80  /// <returns>randomly chosen child node or null, if no child node exits</returns>


81  protected ISymbolicExpressionTreeNode GetNewChildNode(ISymbolicExpressionTreeNode parentNode,


82  IntegerVector genotype,


83  ISymbolicExpressionGrammar grammar,


84  int genotypeIndex,


85  IRandom random) {


86 


87  // only select specific symbols, which can be interpreted ...


88  IEnumerable<ISymbol> symbolList = (from s in grammar.GetAllowedChildSymbols(parentNode.Symbol)


89  where s.InitialFrequency > 0.0


90  select s).ToList();


91 


92  int prodRuleCount = symbolList.Count();


93 


94  // no child node exists for the given parent node


95  if (prodRuleCount < 1) return null;


96 


97  int prodRuleIndex = genotype[genotypeIndex % genotype.Length] % prodRuleCount;


98 


99  var newNode = symbolList.ElementAt(prodRuleIndex).CreateTreeNode();


100  if (newNode.HasLocalParameters) newNode.ResetLocalParameters(random);


101  return newNode;


102  }


103 


104 


105  /// <summary>


106  /// Randomly determines an arity for the given node.


107  /// </summary>


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


109  /// <param name="node">node, for which a random arity is determined</param>


110  /// <param name="maxAllowedArity">the resulting arity must not exceed this maximum arity</param>


111  /// <returns>random arity in the interval [minArity, maxArity] of the node or


112  /// 1, if minArity exceeds maxAllowedArity</returns>


113  protected int SampleArity(IRandom random,


114  ISymbolicExpressionTreeNode node,


115  int maxAllowedArity) {


116  int minArity = node.Symbol.MinimumArity;


117  int maxArity = node.Symbol.MaximumArity;


118 


119  if (maxAllowedArity < maxArity) {


120  maxArity = maxAllowedArity;


121  }


122 


123  if (maxAllowedArity < minArity) {


124  return 1;


125  }


126 


127  if (minArity == maxArity) {


128  return minArity;


129  }


130 


131  return random.Next(minArity, maxArity);


132  }


133  }


134  }

