source: branches/SymbolicExpressionTreeEncoding/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeEncoding.cs @ 12334

Last change on this file since 12334 was 12334, checked in by mkommend, 5 years ago

#2320: Fixed analyzers and parameter typo in symbolic expression tree encoding.

File size: 15.7 KB
Line 
1#region License Information
2
3/* HeuristicLab
4 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
5 *
6 * This file is part of HeuristicLab.
7 *
8 * HeuristicLab is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * HeuristicLab is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#endregion
23
24using System;
25using System.Collections.Generic;
26using System.Linq;
27using HeuristicLab.Common;
28using HeuristicLab.Core;
29using HeuristicLab.Data;
30using HeuristicLab.Optimization;
31using HeuristicLab.Parameters;
32using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
33using HeuristicLab.PluginInfrastructure;
34
35namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
36  [Item("SymbolicExpressionTreeEncoding", "Describes a symbolic expression tree encoding.")]
37  [StorableClass]
38  public sealed class SymbolicExpressionTreeEncoding : Encoding<ISymbolicExpressionTreeCreator> {
39    #region Encoding Parameters
40    [Storable]
41    private IFixedValueParameter<IntValue> treeLengthParameter;
42    public IFixedValueParameter<IntValue> TreeLengthParameter {
43      get { return treeLengthParameter; }
44      set {
45        if (value == null) throw new ArgumentNullException("Tree length parameter must not be null.");
46        if (value.Value == null) throw new ArgumentNullException("Tree length parameter value must not be null.");
47        if (treeLengthParameter == value) return;
48
49        if (treeLengthParameter != null)
50          Parameters.Remove(treeLengthParameter);
51
52        treeLengthParameter = value;
53        Parameters.Add(treeLengthParameter);
54        OnLengthParameterChanged();
55      }
56    }
57
58    [Storable]
59    private IFixedValueParameter<IntValue> treeDepthParameter;
60    public IFixedValueParameter<IntValue> TreeDepthParameter {
61      get { return treeDepthParameter; }
62      set {
63        if (value == null) throw new ArgumentNullException("Tree length parameter must not be null.");
64        if (value.Value == null) throw new ArgumentNullException("Tree length parameter value must not be null.");
65        if (treeDepthParameter == value) return;
66
67        if (treeDepthParameter != null)
68          Parameters.Remove(treeDepthParameter);
69
70        treeDepthParameter = value;
71        Parameters.Add(treeDepthParameter);
72        OnDepthParameterChanged();
73      }
74    }
75
76    [Storable]
77    private IValueParameter<ISymbolicExpressionGrammar> grammarParameter;
78    public IValueParameter<ISymbolicExpressionGrammar> GrammarParameter {
79      get { return grammarParameter; }
80      set {
81        if (value == null) throw new ArgumentNullException("Grammar parameter must not be null.");
82        if (value.Value == null) throw new ArgumentNullException("Grammar parameter value must not be null.");
83        if (grammarParameter == value) return;
84
85        if (grammarParameter != null)
86          Parameters.Remove(grammarParameter);
87
88        grammarParameter = value;
89        Parameters.Add(grammarParameter);
90        OnGrammarParameterChanged();
91      }
92    }
93
94
95    [Storable]
96    private IFixedValueParameter<IntValue> functionDefinitionsParameter;
97    public IFixedValueParameter<IntValue> FunctionDefinitionsParameter {
98      get { return functionDefinitionsParameter; }
99      set {
100        if (value == null) throw new ArgumentNullException("Function definitions parameter must not be null.");
101        if (value.Value == null) throw new ArgumentNullException("Function definitions parameter value must not be null.");
102        if (functionDefinitionsParameter == value) return;
103
104        if (functionDefinitionsParameter != null)
105          Parameters.Remove(functionDefinitionsParameter);
106
107        functionDefinitionsParameter = value;
108        Parameters.Add(functionDefinitionsParameter);
109        OnFunctionDefinitionsParameterChanged();
110      }
111    }
112
113    [Storable]
114    private IFixedValueParameter<IntValue> functionArgumentsParameter;
115    public IFixedValueParameter<IntValue> FunctionArgumentsParameter {
116      get { return functionArgumentsParameter; }
117      set {
118        if (value == null) throw new ArgumentNullException("Function arguments parameter must not be null.");
119        if (value.Value == null) throw new ArgumentNullException("Function arguments parameter value must not be null.");
120        if (functionArgumentsParameter == value) return;
121
122        if (functionArgumentsParameter != null)
123          Parameters.Remove(functionArgumentsParameter);
124
125        functionArgumentsParameter = value;
126        Parameters.Add(functionArgumentsParameter);
127        OnFunctionArgumentsParameterChanged();
128      }
129    }
130    #endregion
131
132    #region Parameter properties
133    public int TreeLength {
134      get { return TreeLengthParameter.Value.Value; }
135      set { TreeLengthParameter.Value.Value = value; }
136    }
137
138    public int TreeDepth {
139      get { return TreeDepthParameter.Value.Value; }
140      set { TreeDepthParameter.Value.Value = value; }
141    }
142
143    public ISymbolicExpressionGrammar Grammar {
144      get { return GrammarParameter.Value; }
145      set { GrammarParameter.Value = value; }
146    }
147
148    public int FunctionDefinitions {
149      get { return FunctionDefinitionsParameter.Value.Value; }
150      set { FunctionDefinitionsParameter.Value.Value = value; }
151    }
152
153    public int FunctionArguments {
154      get { return FunctionArgumentsParameter.Value.Value; }
155      set { FunctionArgumentsParameter.Value.Value = value; }
156    }
157    #endregion
158
159    [StorableConstructor]
160    private SymbolicExpressionTreeEncoding(bool deserializing) : base(deserializing) { }
161    public SymbolicExpressionTreeEncoding(ISymbolicExpressionGrammar grammar) : this("SymbolicExpressionTree", grammar, 50, 50) { }
162    public SymbolicExpressionTreeEncoding(ISymbolicExpressionGrammar grammar, int maximumLength, int maximumDepth) : this("SymbolicExpressionTree", grammar, maximumLength, maximumDepth) { }
163    public SymbolicExpressionTreeEncoding(string name, ISymbolicExpressionGrammar grammar, int maximumLength, int maximumDepth)
164      : base(name) {
165      treeLengthParameter = new FixedValueParameter<IntValue>("Maximum Tree Length", "Maximal length of the symbolic expression.", new IntValue(maximumLength));
166      treeDepthParameter = new FixedValueParameter<IntValue>("Maximum Tree Depth", "Maximal depth of the symbolic expression. The minimum depth needed for the algorithm is 3 because two levels are reserved for the ProgramRoot and the Start symbol.", new IntValue(maximumDepth));
167      grammarParameter = new ValueParameter<ISymbolicExpressionGrammar>("Grammar", "The grammar that should be used for symbolic expression tree.", grammar);
168      functionDefinitionsParameter = new FixedValueParameter<IntValue>("Function Definitions", "Maximal number of automatically defined functions", new IntValue(0));
169      functionArgumentsParameter = new FixedValueParameter<IntValue>("Function Arguments", "Maximal number of arguments of automatically defined functions.", new IntValue(0));
170
171      Parameters.Add(treeLengthParameter);
172      Parameters.Add(treeDepthParameter);
173      Parameters.Add(grammarParameter);
174      Parameters.Add(functionDefinitionsParameter);
175      Parameters.Add(functionArgumentsParameter);
176
177      SolutionCreator = new ProbabilisticTreeCreator();
178      RegisterParameterEvents();
179      DiscoverOperators();
180    }
181
182    private SymbolicExpressionTreeEncoding(SymbolicExpressionTreeEncoding original, Cloner cloner)
183      : base(original, cloner) {
184      treeLengthParameter = cloner.Clone(original.TreeLengthParameter);
185      treeDepthParameter = cloner.Clone(original.TreeDepthParameter);
186      grammarParameter = cloner.Clone(original.GrammarParameter);
187      functionDefinitionsParameter = cloner.Clone(original.FunctionDefinitionsParameter);
188      functionArgumentsParameter = cloner.Clone(original.FunctionArgumentsParameter);
189      RegisterParameterEvents();
190    }
191
192    public override IDeepCloneable Clone(Cloner cloner) {
193      return new SymbolicExpressionTreeEncoding(this, cloner);
194    }
195
196    #region changed events
197    private void OnLengthParameterChanged() {
198      RegisterLengthParameterEvents();
199      ConfigureOperators(Operators);
200    }
201    private void OnDepthParameterChanged() {
202      RegisterDepthParameterEvents();
203      ConfigureOperators(Operators);
204    }
205    private void OnGrammarParameterChanged() {
206      RegisterGrammarParameterEvents();
207      FunctionArguments = Grammar.MaximumFunctionArguments;
208      FunctionDefinitions = Grammar.MaximumFunctionDefinitions;
209      ConfigureOperators(Operators);
210    }
211
212    private void OnFunctionDefinitionsParameterChanged() {
213      RegisterFunctionDefinitionsParameterEvents();
214      Grammar.MaximumFunctionDefinitions = FunctionDefinitions;
215    }
216
217    private void OnFunctionArgumentsParameterChanged() {
218      RegisterFunctionArgumentsParameterEvetns();
219      Grammar.MaximumFunctionArguments = FunctionArguments;
220    }
221
222    private void RegisterParameterEvents() {
223      RegisterLengthParameterEvents();
224      RegisterLengthParameterEvents();
225      RegisterGrammarParameterEvents();
226      RegisterFunctionDefinitionsParameterEvents();
227      RegisterFunctionArgumentsParameterEvetns();
228    }
229
230
231    private void RegisterLengthParameterEvents() { }
232    private void RegisterDepthParameterEvents() { }
233
234    private void RegisterGrammarParameterEvents() {
235      GrammarParameter.ValueChanged += (o, s) => {
236        FunctionArguments = Grammar.MaximumFunctionArguments;
237        FunctionDefinitions = Grammar.MaximumFunctionDefinitions;
238        ConfigureOperators(Operators);
239      };
240      GrammarParameter.Value.Changed += (o, s) => {
241        FunctionArguments = Grammar.MaximumFunctionArguments;
242        FunctionDefinitions = Grammar.MaximumFunctionDefinitions;
243        ConfigureOperators(Operators);
244      };
245    }
246
247    private void RegisterFunctionDefinitionsParameterEvents() {
248      FunctionDefinitionsParameter.Value.ValueChanged += (o, s) => Grammar.MaximumFunctionDefinitions = FunctionDefinitions;
249    }
250    private void RegisterFunctionArgumentsParameterEvetns() {
251      FunctionArgumentsParameter.Value.ValueChanged += (o, s) => Grammar.MaximumFunctionArguments = FunctionArguments;
252    }
253    #endregion
254
255    #region Operator discovery
256    private static readonly IEnumerable<Type> encodingSpecificOperatorTypes;
257    static SymbolicExpressionTreeEncoding() {
258      encodingSpecificOperatorTypes = new List<Type>
259      {
260        typeof(ISymbolicExpressionTreeOperator),
261        typeof(ISymbolicExpressionTreeCreator),
262        typeof(ISymbolicExpressionTreeCrossover),
263        typeof(ISymbolicExpressionTreeManipulator),
264        typeof(ISymbolicExpressionTreeArchitectureAlteringOperator),
265        typeof(ISymbolicExpressionTreeAnalyzer),
266      };
267    }
268
269    private void DiscoverOperators() {
270      var assembly = typeof(ISymbolicExpressionTreeOperator).Assembly;
271      var discoveredTypes = ApplicationManager.Manager.GetTypes(encodingSpecificOperatorTypes, assembly, true, false, false);
272      var operators = discoveredTypes.Select(t => (IOperator)Activator.CreateInstance(t));
273      var newOperators = operators.Except(Operators, new TypeEqualityComparer<IOperator>()).ToList();
274
275      ConfigureOperators(newOperators);
276      foreach (var @operator in newOperators)
277        AddOperator(@operator);
278    }
279    #endregion
280
281    #region Specific operator wiring
282
283    public override void ConfigureOperators(IEnumerable<IOperator> operators) {
284      ConfigureTreeOperators(operators.OfType<ISymbolicExpressionTreeOperator>());
285      ConfigureSizeConstraintOperators(operators.OfType<ISymbolicExpressionTreeSizeConstraintOperator>());
286      ConfigureGrammarBaseOperators(operators.OfType<ISymbolicExpressionTreeGrammarBasedOperator>());
287      ConfigureArchitectureAlteringOperators(operators.OfType<ISymbolicExpressionTreeArchitectureAlteringOperator>());
288
289      ConfigureAnalyzers(operators.OfType<ISymbolicExpressionTreeAnalyzer>());
290      ConfigureCreators(operators.OfType<ISymbolicExpressionTreeCreator>());
291      ConfigureCrossovers(operators.OfType<ISymbolicExpressionTreeCrossover>());
292      ConfigureManipulators(operators.OfType<ISymbolicExpressionTreeManipulator>());
293    }
294
295    private void ConfigureTreeOperators(IEnumerable<ISymbolicExpressionTreeOperator> treeOperators) {
296      foreach (var treeOperator in treeOperators) {
297        treeOperator.SymbolicExpressionTreeParameter.ActualName = Name;
298        treeOperator.SymbolicExpressionTreeParameter.Hidden = true;
299      }
300    }
301
302    private void ConfigureSizeConstraintOperators(IEnumerable<ISymbolicExpressionTreeSizeConstraintOperator> sizeConstraintOperators) {
303      foreach (var sizeConstraintOperator in sizeConstraintOperators) {
304        sizeConstraintOperator.MaximumSymbolicExpressionTreeLengthParameter.ActualName = TreeLengthParameter.Name;
305        sizeConstraintOperator.MaximumSymbolicExpressionTreeDepthParameter.ActualName = TreeDepthParameter.Name;
306      }
307    }
308
309    private void ConfigureGrammarBaseOperators(IEnumerable<ISymbolicExpressionTreeGrammarBasedOperator> grammarBasedOperators) {
310      foreach (var grammarBasedOperator in grammarBasedOperators) {
311        grammarBasedOperator.SymbolicExpressionTreeGrammarParameter.ActualName = GrammarParameter.Name;
312      }
313    }
314
315    private void ConfigureArchitectureAlteringOperators(IEnumerable<ISymbolicExpressionTreeArchitectureAlteringOperator> architectureAlteringOperators) {
316      foreach (var architectureAlteringOperator in architectureAlteringOperators) {
317        architectureAlteringOperator.MaximumFunctionDefinitionsParameter.ActualName = FunctionDefinitionsParameter.Name;
318        architectureAlteringOperator.MaximumFunctionArgumentsParameter.ActualName = FunctionArgumentsParameter.Name;
319      }
320
321    }
322
323    private void ConfigureAnalyzers(IEnumerable<ISymbolicExpressionTreeAnalyzer> analyzers) {
324      foreach (var analyzer in analyzers) {
325        analyzer.SymbolicExpressionTreeParameter.ActualName = Name;
326      }
327      foreach (var analyzer in analyzers.OfType<SymbolicExpressionTreeLengthAnalyzer>()) {
328        analyzer.MaximumSymbolicExpressionTreeLengthParameter.ActualName = TreeLengthParameter.Name;
329      }
330    }
331
332    private void ConfigureCreators(IEnumerable<ISymbolicExpressionTreeCreator> creators) {
333      //Empty interface
334      foreach (var creator in creators) { }
335    }
336
337    private void ConfigureCrossovers(IEnumerable<ISymbolicExpressionTreeCrossover> crossovers) {
338      foreach (var crossover in crossovers) {
339        crossover.ParentsParameter.ActualName = Name;
340      }
341    }
342
343    private void ConfigureManipulators(IEnumerable<ISymbolicExpressionTreeManipulator> manipulators) {
344      //Empty interface
345      foreach (var manipulator in manipulators) { }
346    }
347    #endregion
348  }
349
350  public static class IndividualExtensionMethods {
351    public static ISymbolicExpressionTree SymbolicExpressionTree(this Individual individual) {
352      var encoding = individual.GetEncoding<SymbolicExpressionTreeEncoding>();
353      return individual.SymbolicExpressionTree(encoding.Name);
354    }
355
356    public static ISymbolicExpressionTree SymbolicExpressionTree(this Individual individual, string name) {
357      return (ISymbolicExpressionTree)individual[name];
358    }
359  }
360}
Note: See TracBrowser for help on using the repository browser.