Free cookie consent management tool by TermsFeed Policy Generator

source: branches/GrammaticalEvolution/HeuristicLab.Problems.GrammaticalEvolution/Mappers/PIGEMapper.cs @ 10968

Last change on this file since 10968 was 10968, checked in by gkronber, 10 years ago

#2109 updated license headers and the solution file (for VS2012)

File size: 7.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2014 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
24using System.Collections.Generic;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Encodings.IntegerVectorEncoding;
29using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
30using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
31
32namespace HeuristicLab.Problems.GrammaticalEvolution {
33
34  /// <summary>
35  /// Position Independent (PI) Grammatical Evolution Mapper
36  /// -----------------------------------------------------------------------------------
37  /// Standard GE mappers:
38  ///   Rule = Codon Value % Number Of Rules
39  ///   
40  /// 𝜋GE:
41  ///   𝜋GE codons consist of (nont, rule) tuples, where nont may be one value from an "order"
42  ///   integer vector and rule may be one value from a "content" integer vector.
43  ///   
44  ///   Order:   NT   = nont % Num. NT      ... determines, which non-terminal to expand next
45  ///   Content: Rule = rule % Num. Rules   ... rule determination as with standard GE mappers
46  ///
47  /// Four mutation and crossover strategies possible:
48  ///  * Order-only:    only "order" vector is modified, "content" vector is fixed (1:0),
49  ///                   worst result according to [2]
50  ///  * Content-only:  only "content" vector is modified, "order" vector is fixed (0:1),
51  ///                   best result according to [2]
52  ///  * 𝜋GE:           genetic operators are applied equally (1:1),
53  ///  * Content:Order: genetic operators are applied unequally (e.g. 2:1 or 1:2),
54  ///
55  /// Here, the "content-only" strategy is implemented, as it is the best solution according to [2]
56  /// and it does not require much to change in the problem and evaluator classes.
57  ///
58  /// </summary>
59  /// <remarks>
60  /// Described in
61  ///
62  /// [1] Michael O’Neill et al. 𝜋Grammatical Evolution. In: GECCO 2004.
63  /// Vol. 3103. LNCS. Heidelberg: Springer-Verlag Berlin, 2004, pp. 617–629.
64  /// url: http://dynamics.org/Altenberg/UH_ICS/EC_REFS/GP_REFS/GECCO/2004/31030617.pdf.
65  ///
66  /// [2] David Fagan et al. Investigating Mapping Order in πGE. IEEE, 2010
67  /// url: http://ncra.ucd.ie/papers/pigeWCCI2010.pdf
68  /// </remarks>
69  [Item("PIGEMapper", "Position Independent (PI) Grammatical Evolution Mapper")]
70  [StorableClass]
71  public class PIGEMapper : GenotypeToPhenotypeMapper {
72
73    private IntegerVector nontVector;
74
75    public IntegerVector NontVector {
76      get { return nontVector; }
77      set { nontVector = value; }
78    }
79
80    private IntegerVector GetNontVector(IRandom random, IntMatrix bounds, int length) {
81      IntegerVector v = new IntegerVector(length);
82      v.Randomize(random, bounds);
83      return v;
84    }
85
86    [StorableConstructor]
87    protected PIGEMapper(bool deserializing) : base(deserializing) { }
88    protected PIGEMapper(PIGEMapper original, Cloner cloner) : base(original, cloner) { }
89    public PIGEMapper() : base() { }
90
91    public override IDeepCloneable Clone(Cloner cloner) {
92      return new PIGEMapper(this, cloner);
93    }
94
95
96    /// <summary>
97    /// Maps a genotype (an integer vector) to a phenotype (a symbolic expression tree).
98    /// PIGE approach.
99    /// </summary>
100    /// <param name="random">random number generator</param>
101    /// <param name="bounds">integer number range for genomes (codons) of the nont vector</param>
102    /// <param name="length">length of the nont vector to create</param>
103    /// <param name="grammar">grammar definition</param>
104    /// <param name="genotype">integer vector, which should be mapped to a tree</param>
105    /// <returns>phenotype (a symbolic expression tree)</returns>
106    public override SymbolicExpressionTree Map(IRandom random, IntMatrix bounds, int length,
107                                               ISymbolicExpressionGrammar grammar,
108                                               IntegerVector genotype) {
109
110      SymbolicExpressionTree tree = new SymbolicExpressionTree();
111      var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode();
112      var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode();
113      rootNode.AddSubtree(startNode);
114      tree.Root = rootNode;
115
116      if (NontVector == null) {
117        NontVector = GetNontVector(random, bounds, length);
118      }
119
120      MapPIGEIteratively(startNode, genotype, grammar,
121                         genotype.Length, random);
122
123      return tree;
124    }
125
126
127    /// <summary>
128    /// Genotype-to-Phenotype mapper (iterative 𝜋GE approach, using a list of not expanded nonTerminals).
129    /// </summary>
130    /// <param name="startNode">first node of the tree with arity 1</param>
131    /// <param name="genotype">integer vector, which should be mapped to a tree</param>
132    /// <param name="grammar">grammar to determine the allowed child symbols for each node</param>
133    /// <param name="maxSubtreeCount">maximum allowed subtrees (= number of used genomes)</param>
134    /// <param name="random">random number generator</param>
135    private void MapPIGEIteratively(ISymbolicExpressionTreeNode startNode,
136                                    IntegerVector genotype,
137                                    ISymbolicExpressionGrammar grammar,
138                                    int maxSubtreeCount, IRandom random) {
139
140      List<ISymbolicExpressionTreeNode> nonTerminals = new List<ISymbolicExpressionTreeNode>();
141
142      int genotypeIndex = 0;
143      nonTerminals.Add(startNode);
144
145      while (nonTerminals.Count > 0) {
146
147        if (genotypeIndex >= maxSubtreeCount) {
148          // if all genomes were used, only add terminal nodes to the remaining subtrees
149          ISymbolicExpressionTreeNode current = nonTerminals[0];
150          nonTerminals.RemoveAt(0);
151          current.AddSubtree(GetRandomTerminalNode(current, grammar, random));
152        } else {
153          // Order:   NT   = nont % Num. NT
154          int nt = NontVector[genotypeIndex] % nonTerminals.Count;
155          ISymbolicExpressionTreeNode current = nonTerminals[nt];
156          nonTerminals.RemoveAt(nt);
157
158          // Content: Rule = rule % Num. Rules
159          ISymbolicExpressionTreeNode newNode = GetNewChildNode(current, genotype, grammar, genotypeIndex, random);
160          int arity = SampleArity(random, newNode, grammar);
161
162          current.AddSubtree(newNode);
163          genotypeIndex++;
164          // new node has subtrees, so add "arity" number of copies of this node to the nonTerminals list
165          for (int i = 0; i < arity; ++i) {
166            nonTerminals.Add(newNode);
167          }
168        }
169      }
170    }
171  }
172}
Note: See TracBrowser for help on using the repository browser.