Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Symbol.cs @ 3223

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

Added work in progress for the artificial ant problem #952 (Artificial Ant Problem for 3.3) and for the symbolic expression tree encoding #937 (Data types and operators for symbolic expression tree encoding).

File size: 6.8 KB
Line 
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.Text;
25using HeuristicLab.Core;
26using System.Linq;
27using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
28
29namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
30  [StorableClass]
31  [Item("Symbol", "Represents a symbol in a symbolic function tree.")]
32  public abstract class Symbol : Item {
33    private List<List<Symbol>> allowedSubFunctions = new List<List<Symbol>>();
34    private int minArity = -1;
35    private int maxArity = -1;
36    private double tickets = 1.0;
37    private IOperator initializer;
38    private IOperator manipulator;
39    private int minTreeHeight = -1;
40    private int minTreeSize = -1;
41
42    private string name;
43    public virtual string Name {
44      get { return name; }
45      set {
46        if (string.IsNullOrEmpty(value)) throw new ArgumentException();
47        if (value != name) {
48          name = value;
49        }
50      }
51    }
52
53    protected Symbol() {
54      name = this.GetType().Name;
55    }
56
57    public int MinSubTrees {
58      get {
59        return minArity;
60      }
61      protected internal set {
62        if (value < 0) throw new ArgumentException();
63        if (minArity != value) {
64          minArity = value;
65          while (minArity > allowedSubFunctions.Count) allowedSubFunctions.Add(new List<Symbol>());
66          ResetCachedValues();
67        }
68      }
69    }
70
71    public int MaxSubTrees {
72      get {
73        return maxArity;
74      }
75      protected internal set {
76        if (value < 0) throw new ArgumentException();
77        if (value < minArity) throw new ArgumentException();
78        if (value != maxArity) {
79          maxArity = value;
80          while (allowedSubFunctions.Count > maxArity) allowedSubFunctions.RemoveAt(allowedSubFunctions.Count - 1);
81          while (maxArity > allowedSubFunctions.Count) {
82            if (allowedSubFunctions.Count > 0) {
83              // copy the list of allowed sub-functions from the previous slot
84              allowedSubFunctions.Add(new List<Symbol>(allowedSubFunctions[allowedSubFunctions.Count - 1]));
85            } else {
86              // add empty list
87              allowedSubFunctions.Add(new List<Symbol>());
88            }
89          }
90          ResetCachedValues();
91        }
92      }
93    }
94
95
96    public int MinTreeSize {
97      get {
98        if (minTreeSize <= 0) {
99          RecalculateMinimalTreeSize();
100        }
101        // Debug.Assert(minTreeSize > 0);
102        return minTreeSize;
103      }
104    }
105
106    public int MinTreeHeight {
107      get {
108        if (minTreeHeight <= 0) {
109          RecalculateMinimalTreeHeight();
110        }
111        // Debug.Assert(minTreeHeight > 0);
112        return minTreeHeight;
113      }
114    }
115
116    public double Tickets {
117      get { return tickets; }
118      set {
119        if (value < 0.0) throw new ArgumentException("Number of tickets must be positive");
120        if (value != tickets) {
121          tickets = value;
122        }
123      }
124    }
125
126    public IOperator Initializer {
127      get { return initializer; }
128      set {
129        if (initializer != value) {
130          initializer = value;
131        }
132      }
133    }
134
135    public IOperator Manipulator {
136      get { return manipulator; }
137      set {
138        if (manipulator != value) {
139          manipulator = value;
140        }
141      }
142    }
143
144    public virtual SymbolicExpressionTreeNode CreateTreeNode() {
145      return new SymbolicExpressionTreeNode(this);
146    }
147
148    public IEnumerable<Symbol> GetAllowedSubFunctions(int index) {
149      if (index < 0 || index > MaxSubTrees) throw new ArgumentException("Index outside of allowed range. index = " + index);
150      return allowedSubFunctions[index];
151    }
152
153    public void AddAllowedSubFunction(Symbol symbol, int index) {
154      if (index < 0 || index > MaxSubTrees) throw new ArgumentException("Index outside of allowed range. index = " + index);
155      if (allowedSubFunctions[index] == null) {
156        allowedSubFunctions[index] = new List<Symbol>();
157      }
158      if (!allowedSubFunctions[index].Contains(symbol)) {
159        allowedSubFunctions[index].Add(symbol);
160      }
161      ResetCachedValues();
162    }
163    public void RemoveAllowedSubFunction(Symbol symbol, int index) {
164      if (index < 0 || index > MaxSubTrees) throw new ArgumentException("Index outside of allowed range. index = " + index);
165      if (allowedSubFunctions[index].Contains(symbol)) {
166        allowedSubFunctions[index].Remove(symbol);
167        ResetCachedValues();
168      }
169    }
170
171    private void ResetCachedValues() {
172      minTreeHeight = -1;
173      minTreeSize = -1;
174    }
175
176    public bool IsAllowedSubFunction(Symbol symbol, int index) {
177      return GetAllowedSubFunctions(index).Contains(symbol);
178    }
179
180    private void RecalculateMinimalTreeSize() {
181      if (MinSubTrees == 0) minTreeSize = 1;
182      else {
183        minTreeSize = int.MaxValue; // prevent infinite recursion       
184        minTreeSize = 1 + (from slot in Enumerable.Range(0, MinSubTrees)
185                           let minForSlot = (from function in GetAllowedSubFunctions(slot)
186                                             where function != this
187                                             select function.MinTreeSize).DefaultIfEmpty(0).Min()
188                           select minForSlot).Sum();
189      }
190    }
191
192    private void RecalculateMinimalTreeHeight() {
193      if (MinSubTrees == 0) minTreeHeight = 1;
194      else {
195        minTreeHeight = int.MaxValue;
196        minTreeHeight = 1 + (from slot in Enumerable.Range(0, MinSubTrees)
197                             let minForSlot = (from function in GetAllowedSubFunctions(slot)
198                                               where function != this
199                                               select function.MinTreeHeight).DefaultIfEmpty(0).Min()
200                             select minForSlot).Max();
201      }
202    }
203
204    public override string ToString() {
205      return name;
206    }
207  }
208}
Note: See TracBrowser for help on using the repository browser.