Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.GP/3.4/BakedFunctionTree.cs @ 2515

Last change on this file since 2515 was 1914, checked in by epitzer, 15 years ago

Migration of DataAnalysis, GP, GP.StructureIdentification and Modeling to new Persistence-3.3 (#603)

File size: 10.0 KB
RevLine 
[645]1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 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 System.Text;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using System.Xml;
29using System.Globalization;
[1914]30using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
[645]31
32namespace HeuristicLab.GP {
33
34  public class LightWeightFunction {
[1914]35
36    [Storable]
[767]37    public byte arity = 0;
[1914]38
39    [Storable]
[645]40    public IFunction functionType;
[1914]41
42    [Storable]
[645]43    public List<double> data = new List<double>();
44
45    public LightWeightFunction Clone() {
46      LightWeightFunction clone = new LightWeightFunction();
47      clone.arity = arity;
48      clone.functionType = functionType;
49      clone.data.AddRange(data);
50      return clone;
51    }
52  }
53
54  public class BakedFunctionTree : ItemBase, IFunctionTree {
[1914]55
[645]56    private List<LightWeightFunction> linearRepresentation;
[1914]57
58    [Storable]
[645]59    public List<LightWeightFunction> LinearRepresentation {
60      get {
61        FlattenVariables();
[1914]62        FlattenTrees();
[645]63        return linearRepresentation;
64      }
[1914]65      private set {
66        linearRepresentation = value;
67        treesExpanded = false;
68        variablesExpanded = false;
69      }
[645]70    }
[1914]71
[645]72    private bool treesExpanded = false;
73    private List<IFunctionTree> subTrees;
74    private bool variablesExpanded = false;
75    private List<IVariable> variables;
76
77    public BakedFunctionTree() {
78      linearRepresentation = new List<LightWeightFunction>();
79    }
80
81    internal BakedFunctionTree(IFunction function)
82      : this() {
83      LightWeightFunction fun = new LightWeightFunction();
84      fun.functionType = function;
85      linearRepresentation.Add(fun);
86      treesExpanded = true;
87      subTrees = new List<IFunctionTree>();
88      variables = new List<IVariable>();
89      variablesExpanded = true;
[1914]90      foreach (IVariableInfo variableInfo in function.VariableInfos) {
91        if (variableInfo.Local) {
[645]92          variables.Add((IVariable)function.GetVariable(variableInfo.FormalName).Clone());
93        }
94      }
95    }
96
97    internal BakedFunctionTree(IFunctionTree tree)
98      : this() {
99      LightWeightFunction fun = new LightWeightFunction();
100      fun.functionType = tree.Function;
101      linearRepresentation.Add(fun);
[1914]102      foreach (IVariable variable in tree.LocalVariables) {
[645]103        IItem value = variable.Value;
104        fun.data.Add(GetDoubleValue(value));
105      }
[1914]106      foreach (IFunctionTree subTree in tree.SubTrees) {
[645]107        AddSubTree(new BakedFunctionTree(subTree));
108      }
109    }
110
111    private double GetDoubleValue(IItem value) {
[1914]112      if (value is DoubleData) {
[645]113        return ((DoubleData)value).Data;
[1914]114      } else if (value is ConstrainedDoubleData) {
[645]115        return ((ConstrainedDoubleData)value).Data;
[1914]116      } else if (value is IntData) {
[645]117        return ((IntData)value).Data;
[1914]118      } else if (value is ConstrainedIntData) {
[645]119        return ((ConstrainedIntData)value).Data;
120      } else throw new NotSupportedException("Invalid datatype of local variable for GP");
121    }
122
123    private int BranchLength(int branchRoot) {
124      int arity = linearRepresentation[branchRoot].arity;
125      int length = 1;
[1914]126      for (int i = 0; i < arity; i++) {
[645]127        length += BranchLength(branchRoot + length);
128      }
129      return length;
130    }
131
132    private void FlattenTrees() {
[1914]133      if (treesExpanded) {
[767]134        linearRepresentation[0].arity = (byte)subTrees.Count;
[1914]135        foreach (BakedFunctionTree subTree in subTrees) {
[645]136          subTree.FlattenVariables();
137          subTree.FlattenTrees();
138          linearRepresentation.AddRange(subTree.linearRepresentation);
139        }
140        treesExpanded = false;
141        subTrees = null;
142      }
143    }
144
145    private void FlattenVariables() {
[1914]146      if (variablesExpanded) {
[645]147        linearRepresentation[0].data.Clear();
[1914]148        foreach (IVariable variable in variables) {
[645]149          linearRepresentation[0].data.Add(GetDoubleValue(variable.Value));
150        }
151        variablesExpanded = false;
152        variables = null;
153      }
154    }
155
156    public int Size {
157      get {
[1914]158        if (treesExpanded) {
[645]159          int size = 1;
[1914]160          foreach (BakedFunctionTree tree in subTrees) {
[645]161            size += tree.Size;
162          }
163          return size;
[1914]164        } else
165          return linearRepresentation.Count;
[645]166      }
167    }
168
169    public int Height {
170      get {
[1914]171        if (treesExpanded) {
[645]172          int height = 0;
[1914]173          foreach (IFunctionTree subTree in subTrees) {
[645]174            int curHeight = subTree.Height;
[1914]175            if (curHeight > height) height = curHeight;
[645]176          }
[1914]177          return height + 1;
[645]178        } else {
179          int nextBranchStart;
180          return BranchHeight(0, out nextBranchStart);
181        }
182      }
183    }
184
185    private int BranchHeight(int branchStart, out int nextBranchStart) {
186      LightWeightFunction f = linearRepresentation[branchStart];
187      int height = 0;
188      branchStart++;
[1914]189      for (int i = 0; i < f.arity; i++) {
[645]190        int curHeight = BranchHeight(branchStart, out nextBranchStart);
[1914]191        if (curHeight > height) height = curHeight;
[645]192        branchStart = nextBranchStart;
193      }
194      nextBranchStart = branchStart;
195      return height + 1;
196    }
197
198    public IList<IFunctionTree> SubTrees {
199      get {
[1914]200        if (!treesExpanded) {
[645]201          subTrees = new List<IFunctionTree>();
202          int arity = linearRepresentation[0].arity;
203          int branchIndex = 1;
[1914]204          for (int i = 0; i < arity; i++) {
[645]205            BakedFunctionTree subTree = new BakedFunctionTree();
206            int length = BranchLength(branchIndex);
[1914]207            for (int j = branchIndex; j < branchIndex + length; j++) {
[645]208              subTree.linearRepresentation.Add(linearRepresentation[j]);
209            }
210            branchIndex += length;
211            subTrees.Add(subTree);
212          }
213          treesExpanded = true;
214          linearRepresentation.RemoveRange(1, linearRepresentation.Count - 1);
215          linearRepresentation[0].arity = 0;
216        }
217        return subTrees;
218      }
219    }
220
221    public ICollection<IVariable> LocalVariables {
222      get {
[1914]223        if (!variablesExpanded) {
[645]224          variables = new List<IVariable>();
225          IFunction function = Function;
226          int localVariableIndex = 0;
[1914]227          foreach (IVariableInfo variableInfo in function.VariableInfos) {
228            if (variableInfo.Local) {
[645]229              IVariable clone = (IVariable)function.GetVariable(variableInfo.FormalName).Clone();
230              IItem value = clone.Value;
[1914]231              if (value is ConstrainedDoubleData) {
[645]232                ((ConstrainedDoubleData)value).Data = linearRepresentation[0].data[localVariableIndex];
[1914]233              } else if (value is ConstrainedIntData) {
[645]234                ((ConstrainedIntData)value).Data = (int)linearRepresentation[0].data[localVariableIndex];
[1914]235              } else if (value is DoubleData) {
[645]236                ((DoubleData)value).Data = linearRepresentation[0].data[localVariableIndex];
[1914]237              } else if (value is IntData) {
[645]238                ((IntData)value).Data = (int)linearRepresentation[0].data[localVariableIndex];
239              } else throw new NotSupportedException("Invalid local variable type for GP.");
240              variables.Add(clone);
241              localVariableIndex++;
242            }
243          }
244          variablesExpanded = true;
245          linearRepresentation[0].data.Clear();
246        }
247        return variables;
248      }
249    }
250
251    public IFunction Function {
252      get { return linearRepresentation[0].functionType; }
253    }
254
255    public IVariable GetLocalVariable(string name) {
[1914]256      foreach (IVariable var in LocalVariables) {
257        if (var.Name == name) return var;
[645]258      }
259      return null;
260    }
261
262    public void AddVariable(IVariable variable) {
263      throw new NotSupportedException();
264    }
265
266    public void RemoveVariable(string name) {
267      throw new NotSupportedException();
268    }
269
270    public void AddSubTree(IFunctionTree tree) {
[1914]271      if (!treesExpanded) throw new InvalidOperationException();
[645]272      subTrees.Add(tree);
273    }
274
275    public void InsertSubTree(int index, IFunctionTree tree) {
[1914]276      if (!treesExpanded) throw new InvalidOperationException();
[645]277      subTrees.Insert(index, tree);
278    }
279
280    public void RemoveSubTree(int index) {
281      // sanity check
[1914]282      if (!treesExpanded) throw new InvalidOperationException();
[645]283      subTrees.RemoveAt(index);
284    }
285
286    public override object Clone(IDictionary<Guid, object> clonedObjects) {
287      BakedFunctionTree clone = new BakedFunctionTree();
288      // in case the user (de)serialized the tree between evaluation and selection we have to flatten the tree again.
[1914]289      if (treesExpanded) FlattenTrees();
290      if (variablesExpanded) FlattenVariables();
291      foreach (LightWeightFunction f in linearRepresentation) {
[645]292        clone.linearRepresentation.Add(f.Clone());
293      }
294      return clone;
295    }
296
297    public override IView CreateView() {
298      return new FunctionTreeView(this);
299    }
300
301    //public override string ToString() {
302    //  SymbolicExpressionExporter exporter = new SymbolicExpressionExporter();
303    //  exporter.Visit(this);
304    //  return exporter.GetStringRepresentation();
305    //}
306  }
307}
Note: See TracBrowser for help on using the repository browser.