#region License Information /* HeuristicLab * Copyright (C) 2002-2013 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 HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Encodings.IntegerVectorEncoding; using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; namespace HeuristicLab.Problems.GrammaticalEvolution { /// /// DepthFirstMapper /// [Item("DepthFirstMapper", "")] [StorableClass] public class DepthFirstMapper : GenotypeToPhenotypeMapper { [StorableConstructor] protected DepthFirstMapper(bool deserializing) : base(deserializing) { } protected DepthFirstMapper(DepthFirstMapper original, Cloner cloner) : base(original, cloner) { } public DepthFirstMapper() : base() { } public override IDeepCloneable Clone(Cloner cloner) { return new DepthFirstMapper(this, cloner); } /// /// Maps a genotype (an integer vector) to a phenotype (a symbolic expression tree). /// Depth-first approach. /// /// grammar definition /// integer vector, which should be mapped to a tree /// phenotype (a symbolic expression tree) public override SymbolicExpressionTree Map(ISymbolicExpressionGrammar grammar, IntegerVector genotype) { SymbolicExpressionTree tree = new SymbolicExpressionTree(); var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode(); var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode(); rootNode.AddSubtree(startNode); tree.Root = rootNode; int genotypeIndex = 0; int currSubtreeCount = 1; MapDepthFirstRecursively(startNode, genotype, grammar, genotype.Length, ref genotypeIndex, ref currSubtreeCount); return tree; } /// /// Genotype-to-Phenotype mapper (recursive depth-first approach). /// Appends maximum allowed children (non-terminal symbols) to /// , as long as /// doesn't exceed . /// If at most subtrees were created, /// each non-full node is filled with randomly chosen nodes /// (non-terminal and terminal), and each non-terminal node is again filled with a terminal node. /// /// current parent node /// integer vector, which should be mapped to a tree /// grammar definition to determine the allowed child symbols for currentNode /// maximum allowed subtrees (= number of used genomes) /// current index in integer vector /// number of already determined subtrees (filled or still incomplete) private void MapDepthFirstRecursively(ISymbolicExpressionTreeNode currentNode, IntegerVector genotype, ISymbolicExpressionGrammar grammar, int maxSubtreeCount, ref int genotypeIndex, ref int currSubtreeCount) { if (currSubtreeCount < maxSubtreeCount) { var newNode = GetNewChildNode(currentNode, genotype, grammar, genotypeIndex); if ((currSubtreeCount + newNode.Symbol.MaximumArity) > maxSubtreeCount) { // TODO: maybe check, if there is any node, which fits in the tree yet currentNode.AddSubtree(GetRandomTerminalNode(currentNode, grammar)); } else { currentNode.AddSubtree(newNode); genotypeIndex++; currSubtreeCount += newNode.Symbol.MaximumArity; while (newNode.Symbol.MaximumArity > newNode.SubtreeCount) { MapDepthFirstRecursively(newNode, genotype, grammar, maxSubtreeCount, ref genotypeIndex, ref currSubtreeCount); } } } else { while (currentNode.Symbol.MaximumArity > currentNode.SubtreeCount) { var newNode = GetNewChildNode(currentNode, genotype, grammar, genotypeIndex); currentNode.AddSubtree(newNode); genotypeIndex++; while (newNode.Symbol.MaximumArity > newNode.SubtreeCount) { newNode.AddSubtree(GetRandomTerminalNode(newNode, grammar)); } } } } } }