Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/SymbolicExpressionTreeNode.cs @ 4621

Last change on this file since 4621 was 4524, checked in by gkronber, 14 years ago

Fixed #1214. The size of the manipulated tree is checked and only if the new tree fulfills the size requirements it is accepted otherwise the original tree is returned instead. Additionally the calculation of tree sizes is checked for overflows now.

File size: 5.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using HeuristicLab.Core;
26using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
27using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
28
29namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
30  [StorableClass]
31  public class SymbolicExpressionTreeNode : ICloneable {
32    [Storable]
33    private IList<SymbolicExpressionTreeNode> subTrees;
34    [Storable]
35    private Symbol symbol;
36
37    // cached values to prevent unnecessary tree iterations
38    private short size;
39    private short height;
40
41    public Symbol Symbol {
42      get { return symbol; }
43      protected set { symbol = value; }
44    }
45
46    // parent relation is not persisted or cloned (will be set on AddSubtree or RemoveSubtree)
47    private SymbolicExpressionTreeNode parent;
48    internal SymbolicExpressionTreeNode Parent {
49      get { return parent; }
50      set { parent = value; }
51    }
52
53    internal SymbolicExpressionTreeNode() {
54      // don't allocate subtrees list here!
55      // because we don't want to allocate it in terminal nodes
56    }
57
58    public SymbolicExpressionTreeNode(Symbol symbol) {
59      subTrees = new List<SymbolicExpressionTreeNode>(3);
60      this.symbol = symbol;
61    }
62
63    // copy constructor
64    protected SymbolicExpressionTreeNode(SymbolicExpressionTreeNode original) {
65      symbol = original.symbol;
66      subTrees = new List<SymbolicExpressionTreeNode>(original.SubTrees.Count);
67      foreach (var subtree in original.SubTrees) {
68        AddSubTree((SymbolicExpressionTreeNode)subtree.Clone());
69      }
70    }
71
72    [StorableHook(HookType.AfterDeserialization)]
73    private void AfterDeserializationHook() {
74      foreach (var subtree in SubTrees) {
75        subtree.Parent = this;
76      }
77    }
78
79    public virtual bool HasLocalParameters {
80      get { return false; }
81    }
82
83    public virtual IList<SymbolicExpressionTreeNode> SubTrees {
84      get { return subTrees; }
85    }
86
87    public virtual ISymbolicExpressionGrammar Grammar {
88      get { return parent.Grammar; }
89    }
90
91    public int GetSize() {
92      if (size > 0) return size;
93      else {
94        size = 1;
95        if (SubTrees != null) {
96          for (int i = 0; i < SubTrees.Count; i++) {
97            checked { size += (short)SubTrees[i].GetSize(); }
98          }
99        }
100        return size;
101      }
102    }
103
104    public int GetHeight() {
105      if (height > 0) return height;
106      else {
107        if (SubTrees != null) {
108          for (int i = 0; i < SubTrees.Count; i++) height = Math.Max(height, (short)SubTrees[i].GetHeight());
109        }
110        height++;
111        return height;
112      }
113    }
114
115    public virtual void ResetLocalParameters(IRandom random) { }
116    public virtual void ShakeLocalParameters(IRandom random, double shakingFactor) { }
117
118    public virtual void AddSubTree(SymbolicExpressionTreeNode tree) {
119      SubTrees.Add(tree);
120      tree.Parent = this;
121      ResetCachedValues();
122    }
123
124    public virtual void InsertSubTree(int index, SymbolicExpressionTreeNode tree) {
125      SubTrees.Insert(index, tree);
126      tree.Parent = this;
127      ResetCachedValues();
128    }
129
130    public virtual void RemoveSubTree(int index) {
131      SubTrees[index].Parent = null;
132      SubTrees.RemoveAt(index);
133      ResetCachedValues();
134    }
135
136    public IEnumerable<SymbolicExpressionTreeNode> IterateNodesPrefix() {
137      List<SymbolicExpressionTreeNode> list = new List<SymbolicExpressionTreeNode>();
138      ForEachNodePrefix((n) => list.Add(n));
139      return list;
140    }
141
142    public void ForEachNodePrefix(Action<SymbolicExpressionTreeNode> a) {
143      a(this);
144      if (SubTrees != null) {
145        for (int i = 0; i < SubTrees.Count; i++) {
146          SubTrees[i].ForEachNodePrefix(a);
147        }
148      }
149    }
150
151    public IEnumerable<SymbolicExpressionTreeNode> IterateNodesPostfix() {
152      List<SymbolicExpressionTreeNode> list = new List<SymbolicExpressionTreeNode>();
153      ForEachNodePostfix((n) => list.Add(n));
154      return list;
155    }
156
157    public void ForEachNodePostfix(Action<SymbolicExpressionTreeNode> a) {
158      if (SubTrees != null) {
159        for (int i = 0; i < SubTrees.Count; i++) {
160          SubTrees[i].ForEachNodePostfix(a);
161        }
162      }
163      a(this);
164    }
165
166    public IEnumerable<Symbol> GetAllowedSymbols(int argumentIndex) {
167      return Grammar.Symbols.Where(s => Grammar.IsAllowedChild(Symbol, s, argumentIndex));
168    }
169    public int GetMinSubtreeCount() {
170      return Grammar.GetMinSubtreeCount(Symbol);
171    }
172    public int GetMaxSubtreeCount() {
173      return Grammar.GetMaxSubtreeCount(Symbol);
174    }
175
176    #region ICloneable Members
177
178    public virtual object Clone() {
179      return new SymbolicExpressionTreeNode(this);
180    }
181
182    #endregion
183
184    public override string ToString() {
185      return Symbol.Name;
186    }
187
188    private void ResetCachedValues() {
189      size = 0; height = 0;
190      if (parent != null) parent.ResetCachedValues();
191    }
192  }
193}
Note: See TracBrowser for help on using the repository browser.