Free cookie consent management tool by TermsFeed Policy Generator

Ticket #2320: SymbolicExpressionTreeEncoding.cs

File SymbolicExpressionTreeEncoding.cs, 6.9 KB (added by mkommend, 9 years ago)
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.Persistence.Default.CompositeSerializers.Storable;
32using HeuristicLab.PluginInfrastructure;
33
34namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
35  [Item("SymbolicExpressionTreeEncoding", "Describes a symbolic expression tree encoding.")]
36  [StorableClass]
37  public class SymbolicExpressionTreeEncoding : Encoding<ISymbolicExpressionTreeCreator> {
38    #region Encoding Parameters
39    [Storable]
40    private IFixedValueParameter<IntValue> treeLengthParameter;
41    public IFixedValueParameter<IntValue> TreeLengthParameter {
42      get { return treeLengthParameter; }
43      set {
44        if (value == null) throw new ArgumentNullException("Tree length parameter must not be null.");
45        if (value.Value == null) throw new ArgumentNullException("Tree length parameter value must not be null.");
46        if (treeLengthParameter == value) return;
47
48        if (treeLengthParameter != null)
49          Parameters.Remove(treeLengthParameter);
50
51        treeLengthParameter = value;
52        Parameters.Add(treeLengthParameter);
53      }
54    }
55
56    [Storable]
57    private IFixedValueParameter<IntValue> treeDepthParameter;
58    public IFixedValueParameter<IntValue> TreeDepthParameter {
59      get { return treeDepthParameter; }
60      set {
61        if (value == null) throw new ArgumentNullException("Tree length parameter must not be null.");
62        if (value.Value == null) throw new ArgumentNullException("Tree length parameter value must not be null.");
63        if (treeDepthParameter == value) return;
64
65        if (treeDepthParameter != null)
66          Parameters.Remove(treeDepthParameter);
67
68        treeDepthParameter = value;
69        Parameters.Add(treeDepthParameter);
70      }
71    }
72    #endregion
73
74
75    [StorableConstructor]
76    public SymbolicExpressionTreeEncoding(bool deserializing) : base(deserializing) { }
77
78    public SymbolicExpressionTreeEncoding(Encoding<ISymbolicExpressionTreeCreator> original, Cloner cloner)
79      : base(original, cloner) {
80    }
81
82    public SymbolicExpressionTreeEncoding() : this("SymbolicExpressionTree") { }
83    public SymbolicExpressionTreeEncoding(string name) : base(name) { }
84
85    private SymbolicExpressionTreeEncoding(SymbolicExpressionTreeEncoding original, Cloner cloner)
86      : base(original, cloner) {
87    }
88
89    public override IDeepCloneable Clone(Cloner cloner) {
90      return new SymbolicExpressionTreeEncoding(this, cloner);
91    }
92
93    public override void ConfigureOperators(IEnumerable<IOperator> operators) {
94      ConfigureCreators(operators.OfType<ISymbolicExpressionTreeCreator>());
95      ConfigureCrossovers(operators.OfType<ISymbolicExpressionTreeCrossover>());
96      ConfigureManipulators(operators.OfType<ISymbolicExpressionTreeManipulator>());
97    }
98
99    private void OnLengthParameterChanged() {
100      RegisterLengthParameterEvents();
101      ConfigureOperators(Operators);
102    }
103
104    private void OnDepthParameterChanged() {
105      RegisterDepthParameterEvents();
106      ConfigureOperators(Operators);
107    }
108
109    private void RegisterLengthParameterEvents() {
110      TreeLengthParameter.ValueChanged += (o, s) => ConfigureOperators(Operators);
111      TreeLengthParameter.Value.ValueChanged += (o, s) => ConfigureOperators(Operators);
112    }
113
114    private void RegisterDepthParameterEvents() {
115      TreeDepthParameter.ValueChanged += (o, s) => ConfigureOperators(Operators);
116      TreeDepthParameter.Value.ValueChanged += (o, s) => ConfigureOperators(Operators);
117    }
118
119    #region Operator discovery
120    private static readonly IEnumerable<Type> encodingSpecificOperatorTypes;
121
122    static SymbolicExpressionTreeEncoding() {
123      encodingSpecificOperatorTypes = new List<Type>
124      {
125        typeof(ISymbolicExpressionTreeOperator),
126        typeof(ISymbolicExpressionTreeCreator),
127        typeof(ISymbolicExpressionTreeCrossover),
128        typeof(ISymbolicExpressionTreeManipulator)
129      };
130    }
131
132    private void DiscoverOperators() {
133      var assembly = typeof(ISymbolicExpressionTreeOperator).Assembly;
134      var discoveredTypes = ApplicationManager.Manager.GetTypes(encodingSpecificOperatorTypes, assembly, true, false, false);
135      var operators = discoveredTypes.Select(t => (IOperator)Activator.CreateInstance(t));
136      var newOperators = operators.Except(Operators, new TypeEqualityComparer<IOperator>()).ToList();
137
138      ConfigureOperators(newOperators);
139      foreach (var @operator in newOperators)
140        AddOperator(@operator);
141    }
142    #endregion
143
144    #region Specific operator wiring
145    private void ConfigureCreators(IEnumerable<ISymbolicExpressionTreeCreator> creators) {
146      foreach (var creator in creators) {
147        creator.SymbolicExpressionTreeParameter.ActualName = Name;
148        // creator should have depth and length parameters?
149      }
150    }
151
152    private void ConfigureCrossovers(IEnumerable<ISymbolicExpressionTreeCrossover> crossovers) {
153      foreach (var crossover in crossovers) {
154        crossover.ParentsParameter.ActualName = Name;
155        crossover.ChildParameter.ActualName = Name;
156      }
157    }
158
159    private void ConfigureManipulators(IEnumerable<ISymbolicExpressionTreeManipulator> manipulators) {
160      foreach (var manipulator in manipulators) {
161        manipulator.SymbolicExpressionTreeParameter.ActualName = Name;
162        manipulator.SymbolicExpressionTreeParameter.Hidden = true;
163      }
164    }
165    #endregion
166  }
167
168  public static class IndividualExtensionMethods {
169    public static ISymbolicExpressionTree SymbolicExpressionTree(this Individual individual) {
170      var encoding = individual.GetEncoding<SymbolicExpressionTreeEncoding>();
171      return individual.SymbolicExpressionTree(encoding.Name);
172    }
173
174    public static ISymbolicExpressionTree SymbolicExpressionTree(this Individual individual, string name) {
175      return (ISymbolicExpressionTree)individual[name];
176    }
177  }
178}