Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 11559 was 11559, checked in by mkommend, 10 years ago

#2174: Adapted IEncoding and Encoding base class.

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