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

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

#2320: Added simple symbol and grammar for symbolic expression encoding.

File size: 15.5 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
160    [StorableConstructor]
161    private SymbolicExpressionTreeEncoding(bool deserializing) : base(deserializing) { }
162    public SymbolicExpressionTreeEncoding(ISymbolicExpressionGrammar grammar) : this("SymbolicExpressionTree", grammar, 50, 50) { }
163    public SymbolicExpressionTreeEncoding(ISymbolicExpressionGrammar grammar, int maximumLength, int maximumDepth) : this("SymbolicExpressionTree", grammar, maximumLength, maximumDepth) { }
164    public SymbolicExpressionTreeEncoding(string name, ISymbolicExpressionGrammar grammar, int maximumLength, int maximumDepth)
165      : base(name) {
166      treeLengthParameter = new FixedValueParameter<IntValue>("Maximium Tree Length", "Maximal length of the symbolic expression.", new IntValue(maximumLength));
167      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));
168      grammarParameter = new ValueParameter<ISymbolicExpressionGrammar>("Grammar", "The grammar that should be used for symbolic expression tree.", grammar);
169      functionDefinitionsParameter = new FixedValueParameter<IntValue>("Function Definitions", "Maximal number of automatically defined functions", new IntValue(0));
170      functionArgumentsParameter = new FixedValueParameter<IntValue>("Function Arguments", "Maximal number of arguments of automatically defined functions.", new IntValue(0));
171
172      Parameters.Add(treeLengthParameter);
173      Parameters.Add(treeDepthParameter);
174      Parameters.Add(grammarParameter);
175      Parameters.Add(functionDefinitionsParameter);
176      Parameters.Add(functionArgumentsParameter);
177
178      SolutionCreator = new ProbabilisticTreeCreator();
179      RegisterParameterEvents();
180      DiscoverOperators();
181    }
182
183    private SymbolicExpressionTreeEncoding(SymbolicExpressionTreeEncoding original, Cloner cloner)
184      : base(original, cloner) {
185      treeLengthParameter = cloner.Clone(original.TreeLengthParameter);
186      treeDepthParameter = cloner.Clone(original.TreeDepthParameter);
187      grammarParameter = cloner.Clone(original.GrammarParameter);
188      functionDefinitionsParameter = cloner.Clone(original.FunctionDefinitionsParameter);
189      functionArgumentsParameter = cloner.Clone(original.FunctionArgumentsParameter);
190      RegisterParameterEvents();
191    }
192
193    public override IDeepCloneable Clone(Cloner cloner) {
194      return new SymbolicExpressionTreeEncoding(this, cloner);
195    }
196
197    #region changed events
198    private void OnLengthParameterChanged() {
199      RegisterLengthParameterEvents();
200      ConfigureOperators(Operators);
201    }
202    private void OnDepthParameterChanged() {
203      RegisterDepthParameterEvents();
204      ConfigureOperators(Operators);
205    }
206    private void OnGrammarParameterChanged() {
207      RegisterGrammarParameterEvents();
208      FunctionArguments = Grammar.MaximumFunctionArguments;
209      FunctionDefinitions = Grammar.MaximumFunctionDefinitions;
210      ConfigureOperators(Operators);
211    }
212
213    private void OnFunctionDefinitionsParameterChanged() {
214      RegisterFunctionDefinitionsParameterEvents();
215      Grammar.MaximumFunctionDefinitions = FunctionDefinitions;
216    }
217
218    private void OnFunctionArgumentsParameterChanged() {
219      RegisterFunctionArgumentsParameterEvetns();
220      Grammar.MaximumFunctionArguments = FunctionArguments;
221    }
222
223    private void RegisterParameterEvents() {
224      RegisterLengthParameterEvents();
225      RegisterLengthParameterEvents();
226      RegisterGrammarParameterEvents();
227      RegisterFunctionDefinitionsParameterEvents();
228      RegisterFunctionArgumentsParameterEvetns();
229    }
230
231
232    private void RegisterLengthParameterEvents() { }
233    private void RegisterDepthParameterEvents() { }
234
235    private void RegisterGrammarParameterEvents() {
236      GrammarParameter.ValueChanged += (o, s) => {
237        FunctionArguments = Grammar.MaximumFunctionArguments;
238        FunctionDefinitions = Grammar.MaximumFunctionDefinitions;
239        ConfigureOperators(Operators);
240      };
241      GrammarParameter.Value.Changed += (o, s) => {
242        FunctionArguments = Grammar.MaximumFunctionArguments;
243        FunctionDefinitions = Grammar.MaximumFunctionDefinitions;
244        ConfigureOperators(Operators);
245      };
246    }
247
248    private void RegisterFunctionDefinitionsParameterEvents() {
249      FunctionDefinitionsParameter.Value.ValueChanged += (o, s) => Grammar.MaximumFunctionDefinitions = FunctionDefinitions;
250    }
251    private void RegisterFunctionArgumentsParameterEvetns() {
252      FunctionArgumentsParameter.Value.ValueChanged += (o, s) => Grammar.MaximumFunctionArguments = FunctionArguments;
253    }
254    #endregion
255
256    #region Operator discovery
257    private static readonly IEnumerable<Type> encodingSpecificOperatorTypes;
258    static SymbolicExpressionTreeEncoding() {
259      encodingSpecificOperatorTypes = new List<Type>
260      {
261        typeof(ISymbolicExpressionTreeOperator),
262        typeof(ISymbolicExpressionTreeCreator),
263        typeof(ISymbolicExpressionTreeCrossover),
264        typeof(ISymbolicExpressionTreeManipulator),
265        typeof(ISymbolicExpressionTreeArchitectureAlteringOperator),
266        typeof(ISymbolicExpressionTreeAnalyzer),
267      };
268    }
269
270    private void DiscoverOperators() {
271      var assembly = typeof(ISymbolicExpressionTreeOperator).Assembly;
272      var discoveredTypes = ApplicationManager.Manager.GetTypes(encodingSpecificOperatorTypes, assembly, true, false, false);
273      var operators = discoveredTypes.Select(t => (IOperator)Activator.CreateInstance(t));
274      var newOperators = operators.Except(Operators, new TypeEqualityComparer<IOperator>()).ToList();
275
276      ConfigureOperators(newOperators);
277      foreach (var @operator in newOperators)
278        AddOperator(@operator);
279    }
280    #endregion
281
282    #region Specific operator wiring
283
284    public override void ConfigureOperators(IEnumerable<IOperator> operators) {
285      ConfigureTreeOperators(operators.OfType<ISymbolicExpressionTreeOperator>());
286      ConfigureSizeConstraintOperators(operators.OfType<ISymbolicExpressionTreeSizeConstraintOperator>());
287      ConfigureGrammarBaseOperators(operators.OfType<ISymbolicExpressionTreeGrammarBasedOperator>());
288      ConfigureArchitectureAlteringOperators(operators.OfType<ISymbolicExpressionTreeArchitectureAlteringOperator>());
289
290      ConfigureAnalyzers(operators.OfType<ISymbolicExpressionTreeAnalyzer>());
291      ConfigureCreators(operators.OfType<ISymbolicExpressionTreeCreator>());
292      ConfigureCrossovers(operators.OfType<ISymbolicExpressionTreeCrossover>());
293      ConfigureManipulators(operators.OfType<ISymbolicExpressionTreeManipulator>());
294    }
295
296    private void ConfigureTreeOperators(IEnumerable<ISymbolicExpressionTreeOperator> treeOperators) {
297      foreach (var treeOperator in treeOperators) {
298        treeOperator.SymbolicExpressionTreeParameter.ActualName = Name;
299        treeOperator.SymbolicExpressionTreeParameter.Hidden = true;
300      }
301    }
302
303    private void ConfigureSizeConstraintOperators(IEnumerable<ISymbolicExpressionTreeSizeConstraintOperator> sizeConstraintOperators) {
304      foreach (var sizeConstraintOperator in sizeConstraintOperators) {
305        sizeConstraintOperator.MaximumSymbolicExpressionTreeLengthParameter.ActualName = TreeLengthParameter.Name;
306        sizeConstraintOperator.MaximumSymbolicExpressionTreeDepthParameter.ActualName = TreeDepthParameter.Name;
307      }
308    }
309
310    private void ConfigureGrammarBaseOperators(IEnumerable<ISymbolicExpressionTreeGrammarBasedOperator> grammarBasedOperators) {
311      foreach (var grammarBasedOperator in grammarBasedOperators) {
312        grammarBasedOperator.SymbolicExpressionTreeGrammarParameter.ActualName = GrammarParameter.Name;
313      }
314    }
315
316    private void ConfigureArchitectureAlteringOperators(IEnumerable<ISymbolicExpressionTreeArchitectureAlteringOperator> architectureAlteringOperators) {
317      foreach (var architectureAlteringOperator in architectureAlteringOperators) {
318        architectureAlteringOperator.MaximumFunctionDefinitionsParameter.ActualName = FunctionDefinitionsParameter.Name;
319        architectureAlteringOperator.MaximumFunctionArgumentsParameter.ActualName = FunctionArgumentsParameter.Name;
320      }
321
322    }
323
324    private void ConfigureAnalyzers(IEnumerable<ISymbolicExpressionTreeAnalyzer> analyzers) {
325      foreach (var analyzer in analyzers) {
326        analyzer.SymbolicExpressionTreeParameter.ActualName = Name;
327      }
328    }
329
330    private void ConfigureCreators(IEnumerable<ISymbolicExpressionTreeCreator> creators) {
331      //Empty interface
332      foreach (var creator in creators) { }
333    }
334
335    private void ConfigureCrossovers(IEnumerable<ISymbolicExpressionTreeCrossover> crossovers) {
336      foreach (var crossover in crossovers) {
337        crossover.ParentsParameter.ActualName = Name;
338      }
339    }
340
341    private void ConfigureManipulators(IEnumerable<ISymbolicExpressionTreeManipulator> manipulators) {
342      //Empty interface
343      foreach (var manipulator in manipulators) { }
344    }
345    #endregion
346  }
347
348  public static class IndividualExtensionMethods {
349    public static ISymbolicExpressionTree SymbolicExpressionTree(this Individual individual) {
350      var encoding = individual.GetEncoding<SymbolicExpressionTreeEncoding>();
351      return individual.SymbolicExpressionTree(encoding.Name);
352    }
353
354    public static ISymbolicExpressionTree SymbolicExpressionTree(this Individual individual, string name) {
355      return (ISymbolicExpressionTree)individual[name];
356    }
357  }
358}
Note: See TracBrowser for help on using the repository browser.