Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2521_ProblemRefactoring/HeuristicLab.Encodings.RealVectorEncoding/3.3/RealVectorEncoding.cs @ 16692

Last change on this file since 16692 was 16692, checked in by abeham, 5 years ago

#2521: merged trunk changes up to r15681 into branch (removal of trunk/sources)

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