Free cookie consent management tool by TermsFeed Policy Generator

source: branches/ProgrammableProblem/HeuristicLab.Problems.Programmable/3.3/Encodings/RealEncoding.cs @ 11598

Last change on this file since 11598 was 11598, checked in by mkommend, 9 years ago

#2174: Added first version of refactored individuals.

File size: 13.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2014 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 HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Encodings.RealVectorEncoding;
29using HeuristicLab.Optimization;
30using HeuristicLab.Parameters;
31using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
32using HeuristicLab.PluginInfrastructure;
33
34namespace HeuristicLab.Problems.Programmable {
35  [Item("RealEncoding", "Describes a real vector encoding.")]
36  [StorableClass]
37  public sealed class RealEncoding : Encoding<IRealVectorCreator> {
38    #region Encoding Parameters
39    [Storable]
40    private IFixedValueParameter<IntValue> lengthParameter;
41    public IFixedValueParameter<IntValue> LengthParameter {
42      get { return lengthParameter; }
43      set {
44        if (value == null) throw new ArgumentNullException("Length parameter must not be null.");
45        if (value.Value == null) throw new ArgumentNullException("Length parameter value must not be null.");
46        if (lengthParameter == value) return;
47
48        if (lengthParameter != null) Parameters.Remove(lengthParameter);
49        lengthParameter = value;
50        Parameters.Add(lengthParameter);
51        OnLengthParameterChanged();
52      }
53    }
54    [Storable]
55    private IValueParameter<DoubleMatrix> boundsParameter;
56    public IValueParameter<DoubleMatrix> BoundsParameter {
57      get { return boundsParameter; }
58      set {
59        if (value == null) throw new ArgumentNullException("Bounds parameter must not be null.");
60        if (boundsParameter == value) return;
61
62        if (boundsParameter != null) Parameters.Remove(boundsParameter);
63        boundsParameter = value;
64        Parameters.Add(boundsParameter);
65        OnBoundsParameterChanged();
66      }
67    }
68    #endregion
69
70    public int Length {
71      get { return LengthParameter.Value.Value; }
72      set { LengthParameter.Value.Value = value; }
73    }
74    public DoubleMatrix Bounds {
75      get { return BoundsParameter.Value; }
76      set { BoundsParameter.Value = value; }
77    }
78
79    [StorableConstructor]
80    private RealEncoding(bool deserializing) : base(deserializing) { }
81    [StorableHook(HookType.AfterDeserialization)]
82    private void AfterDeserialization() {
83      RegisterParameterEvents();
84      DiscoverOperators();
85    }
86
87    public override IDeepCloneable Clone(Cloner cloner) { return new RealEncoding(this, cloner); }
88    private RealEncoding(RealEncoding original, Cloner cloner)
89      : base(original, cloner) {
90      lengthParameter = cloner.Clone(original.lengthParameter);
91      boundsParameter = cloner.Clone(original.boundsParameter);
92      RegisterParameterEvents();
93    }
94
95    public RealEncoding(string name, int length, double min, double max)
96      : base(name) {
97      if (min >= max) throw new ArgumentException("min must be less than max", "min");
98
99      var bounds = new DoubleMatrix(1, 2);
100      bounds[0, 0] = min;
101      bounds[0, 1] = max;
102
103      lengthParameter = new FixedValueParameter<IntValue>(Name + ".Length", new IntValue(length));
104      boundsParameter = new ValueParameter<DoubleMatrix>(Name + ".Bounds", bounds);
105      Parameters.Add(lengthParameter);
106      Parameters.Add(boundsParameter);
107
108      SolutionCreator = new UniformRandomRealVectorCreator();
109      RegisterParameterEvents();
110      DiscoverOperators();
111    }
112
113    public RealEncoding(string name, int length, IList<double> min, IList<double> max)
114      : base(name) {
115      if (min.Count == 0) throw new ArgumentException("Bounds must be given for the real parameters.");
116      if (min.Count != max.Count) throw new ArgumentException("min must be of the same length as max", "min");
117      if (min.Zip(max, (mi, ma) => mi >= ma).Any(x => x)) throw new ArgumentException("min must be less than max in each dimension", "min");
118
119      var bounds = new DoubleMatrix(min.Count, 2);
120      for (int i = 0; i < min.Count; i++) {
121        bounds[i, 0] = min[i];
122        bounds[i, 1] = max[i];
123      }
124      LengthParameter = new FixedValueParameter<IntValue>(Name + ".Length", new IntValue(length));
125      BoundsParameter = new ValueParameter<DoubleMatrix>(Name + ".Bounds", bounds);
126
127      SolutionCreator = new UniformRandomRealVectorCreator();
128      RegisterParameterEvents();
129      DiscoverOperators();
130    }
131
132    private void OnLengthParameterChanged() {
133      RegisterLengthParameterEvents();
134      ConfigureOperators(Operators);
135    }
136    private void OnBoundsParameterChanged() {
137      RegisterBoundsParameterEvents();
138      ConfigureOperators(Operators);
139    }
140
141    private void RegisterParameterEvents() {
142      RegisterLengthParameterEvents();
143      RegisterBoundsParameterEvents();
144    }
145    private void RegisterLengthParameterEvents() {
146      LengthParameter.ValueChanged += (o, s) => ConfigureOperators(Operators);
147      LengthParameter.Value.ValueChanged += (o, s) => ConfigureOperators(Operators);
148    }
149    private void RegisterBoundsParameterEvents() {
150      BoundsParameter.ValueChanged += (o, s) => ConfigureOperators(Operators);
151      boundsParameter.Value.ToStringChanged += (o, s) => ConfigureOperators(Operators);
152    }
153
154    #region Operator Discovery
155    private static readonly IEnumerable<Type> encodingSpecificOperatorTypes;
156    static RealEncoding() {
157      encodingSpecificOperatorTypes = new List<Type>() {
158          typeof (IRealVectorOperator),
159          typeof (IRealVectorCreator),
160          typeof (IRealVectorCrossover),
161          typeof (IRealVectorManipulator),
162          typeof (IRealVectorStdDevStrategyParameterOperator),
163          typeof (IRealVectorSwarmUpdater),
164          typeof (IRealVectorParticleCreator),
165          typeof (IRealVectorParticleUpdater),
166          typeof (IRealVectorMultiNeighborhoodShakingOperator),
167          typeof (IRealVectorBoundsChecker),
168          typeof (IRealVectorMoveOperator),
169          typeof (IRealVectorMoveGenerator)
170      };
171    }
172    private void DiscoverOperators() {
173      var discoveredTypes = ApplicationManager.Manager.GetTypes(encodingSpecificOperatorTypes, true, false, false);
174      var operators = discoveredTypes.Select(t => (IOperator)Activator.CreateInstance(t));
175      var newOperators = operators.Except(Operators, new TypeEqualityComparer<IOperator>()).ToList();
176
177      ConfigureOperators(newOperators);
178      foreach (var @operator in newOperators)
179        encodingOperators.Add(@operator);
180
181      foreach (var strategyVectorCreator in Operators.OfType<IRealVectorStdDevStrategyParameterCreator>())
182        strategyVectorCreator.BoundsParameter.ValueChanged += strategyVectorCreator_BoundsParameter_ValueChanged;
183    }
184    #endregion
185
186
187    private void strategyVectorCreator_BoundsParameter_ValueChanged(object sender, EventArgs e) {
188      var boundsParameter = (IValueLookupParameter<DoubleMatrix>)sender;
189      if (boundsParameter.Value == null) return;
190      foreach (var strategyVectorManipulator in Operators.OfType<IRealVectorStdDevStrategyParameterManipulator>())
191        strategyVectorManipulator.BoundsParameter.Value = (DoubleMatrix)boundsParameter.Value.Clone();
192    }
193
194    public override void ConfigureOperators(IEnumerable<IOperator> operators) {
195      ConfigureCreators(operators.OfType<IRealVectorCreator>());
196      ConfigureCrossovers(operators.OfType<IRealVectorCrossover>());
197      ConfigureManipulators(operators.OfType<IRealVectorManipulator>());
198      ConfigureStdDevStrategyParameterOperators(operators.OfType<IRealVectorStdDevStrategyParameterOperator>());
199      ConfigureSwarmUpdaters(operators.OfType<IRealVectorSwarmUpdater>());
200      ConfigureParticleCreators(operators.OfType<IRealVectorParticleCreator>());
201      ConfigureParticleUpdaters(operators.OfType<IRealVectorParticleUpdater>());
202      ConfigureShakingOperators(operators.OfType<IRealVectorMultiNeighborhoodShakingOperator>());
203      ConfigureBoundsCheckers(operators.OfType<IRealVectorBoundsChecker>());
204      ConfigureMoveGenerators(operators.OfType<IRealVectorMoveGenerator>());
205      ConfigureMoveOperators(operators.OfType<IRealVectorMoveOperator>());
206      ConfigureAdditiveMoveOperator(operators.OfType<IAdditiveRealVectorMoveOperator>());
207    }
208
209    #region Specific Operator Wiring
210    private void ConfigureCreators(IEnumerable<IRealVectorCreator> creators) {
211      foreach (var creator in creators) {
212        creator.RealVectorParameter.ActualName = Name;
213        creator.LengthParameter.ActualName = LengthParameter.Name;
214        creator.BoundsParameter.ActualName = BoundsParameter.Name;
215      }
216    }
217    private void ConfigureCrossovers(IEnumerable<IRealVectorCrossover> crossovers) {
218      foreach (var crossover in crossovers) {
219        crossover.ChildParameter.ActualName = Name;
220        crossover.ParentsParameter.ActualName = Name;
221        crossover.BoundsParameter.ActualName = BoundsParameter.Name;
222      }
223    }
224    private void ConfigureManipulators(IEnumerable<IRealVectorManipulator> manipulators) {
225      foreach (var manipulator in manipulators) {
226        manipulator.RealVectorParameter.ActualName = Name;
227        manipulator.BoundsParameter.ActualName = BoundsParameter.Name;
228        manipulator.BoundsParameter.Hidden = true;
229        var sm = manipulator as ISelfAdaptiveManipulator;
230        if (sm != null) {
231          var p = sm.StrategyParameterParameter as ILookupParameter;
232          if (p != null) {
233            p.ActualName = Name + ".Strategy";
234          }
235        }
236      }
237    }
238    private void ConfigureStdDevStrategyParameterOperators(IEnumerable<IRealVectorStdDevStrategyParameterOperator> strategyOperators) {
239      var bounds = new DoubleMatrix(Bounds.Rows, Bounds.Columns);
240      for (var i = 0; i < Bounds.Rows; i++) {
241        bounds[i, 0] = 0;
242        bounds[i, 1] = 0.1 * (Bounds[i, 1] - Bounds[i, 0]);
243      }
244      foreach (var s in strategyOperators) {
245        var c = s as IRealVectorStdDevStrategyParameterCreator;
246        if (c != null) {
247          c.BoundsParameter.Value = (DoubleMatrix)bounds.Clone();
248          c.LengthParameter.ActualName = LengthParameter.Name;
249          c.StrategyParameterParameter.ActualName = Name + ".Strategy";
250        }
251        var m = s as IRealVectorStdDevStrategyParameterManipulator;
252        if (m != null) {
253          m.BoundsParameter.Value = (DoubleMatrix)bounds.Clone();
254          m.StrategyParameterParameter.ActualName = Name + ".Strategy";
255        }
256        var mm = s as StdDevStrategyVectorManipulator;
257        if (mm != null) {
258          mm.GeneralLearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * Length));
259          mm.LearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * Math.Sqrt(Length)));
260        }
261        var x = s as IRealVectorStdDevStrategyParameterCrossover;
262        if (x != null) {
263          x.ParentsParameter.ActualName = Name + ".Strategy";
264          x.StrategyParameterParameter.ActualName = Name + ".Strategy";
265        }
266      }
267    }
268    private void ConfigureSwarmUpdaters(IEnumerable<IRealVectorSwarmUpdater> swarmUpdaters) {
269      foreach (var su in swarmUpdaters) {
270        su.RealVectorParameter.ActualName = Name;
271      }
272    }
273    private void ConfigureParticleCreators(IEnumerable<IRealVectorParticleCreator> particleCreators) {
274      foreach (var particleCreator in particleCreators) {
275        particleCreator.RealVectorParameter.ActualName = Name;
276        particleCreator.BoundsParameter.ActualName = BoundsParameter.Name;
277        particleCreator.ProblemSizeParameter.ActualName = LengthParameter.Name;
278      }
279    }
280    private void ConfigureParticleUpdaters(IEnumerable<IRealVectorParticleUpdater> particleUpdaters) {
281      foreach (var particleUpdater in particleUpdaters) {
282        particleUpdater.RealVectorParameter.ActualName = Name;
283        particleUpdater.BoundsParameter.ActualName = BoundsParameter.Name;
284      }
285    }
286    private void ConfigureShakingOperators(IEnumerable<IRealVectorMultiNeighborhoodShakingOperator> shakingOperators) {
287      foreach (var shakingOperator in shakingOperators) {
288        shakingOperator.RealVectorParameter.ActualName = Name;
289      }
290    }
291    private void ConfigureBoundsCheckers(IEnumerable<IRealVectorBoundsChecker> boundsCheckers) {
292      foreach (var boundsChecker in boundsCheckers) {
293        boundsChecker.RealVectorParameter.ActualName = Name;
294        boundsChecker.BoundsParameter.ActualName = BoundsParameter.Name;
295      }
296    }
297    private void ConfigureMoveOperators(IEnumerable<IRealVectorMoveOperator> moveOperators) {
298      foreach (var moveOperator in moveOperators)
299        moveOperator.RealVectorParameter.ActualName = Name;
300    }
301
302    private void ConfigureMoveGenerators(IEnumerable<IRealVectorMoveGenerator> moveGenerators) {
303      foreach (var moveGenerator in moveGenerators)
304        moveGenerator.BoundsParameter.ActualName = BoundsParameter.Name;
305    }
306
307    private void ConfigureAdditiveMoveOperator(IEnumerable<IAdditiveRealVectorMoveOperator> additiveMoveOperators) {
308      foreach (var additiveMoveOperator in additiveMoveOperators) {
309        additiveMoveOperator.AdditiveMoveParameter.ActualName = Name + ".AdditiveMove";
310      }
311    }
312    #endregion
313  }
314}
Note: See TracBrowser for help on using the repository browser.