source: branches/ProblemRefactoring/HeuristicLab.Encodings.RealVectorEncoding/3.3/RealVectorEncoding.cs @ 13403

Last change on this file since 13403 was 13403, checked in by abeham, 4 years ago

#2521:

  • Adapted single-objective test function problem to new problem infrastructure
  • Added additional interfaces to RealVectorEncoding
  • Fixed IParticleUpdater interface (must implement IStochasticOperator if it contains a Random parameter)
File size: 14.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 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        particleCreator.ProblemSizeParameter.ActualName = LengthParameter.Name;
279      }
280    }
281    private void ConfigureParticleUpdaters(IEnumerable<IRealVectorParticleUpdater> particleUpdaters) {
282      // particle updaters don't have additional parameters besides solution and bounds parameter
283    }
284    private void ConfigureShakingOperators(IEnumerable<IRealVectorMultiNeighborhoodShakingOperator> shakingOperators) {
285      // shaking operators don't have additional parameters besides solution and bounds parameter
286    }
287    private void ConfigureBoundsCheckers(IEnumerable<IRealVectorBoundsChecker> boundsCheckers) {
288      foreach (var boundsChecker in boundsCheckers) {
289        boundsChecker.RealVectorParameter.ActualName = Name;
290        boundsChecker.BoundsParameter.ActualName = BoundsParameter.Name;
291      }
292    }
293    private void ConfigureMoveOperators(IEnumerable<IRealVectorMoveOperator> moveOperators) {
294      // move operators don't have additional parameters besides the solution parameter
295    }
296    private void ConfigureMoveGenerators(IEnumerable<IRealVectorMoveGenerator> moveGenerators) {
297      // move generators don't have additional parameters besides solution and bounds parameter
298    }
299    private void ConfigureAdditiveMoveOperator(IEnumerable<IRealVectorAdditiveMoveOperator> additiveMoveOperators) {
300      foreach (var additiveMoveOperator in additiveMoveOperators) {
301        additiveMoveOperator.AdditiveMoveParameter.ActualName = Name + ".AdditiveMove";
302      }
303    }
304    private void ConfigureRealVectorSolutionOperators(IEnumerable<IRealVectorSolutionOperator> solutionOperators) {
305      foreach (var solutionOperator in solutionOperators)
306        solutionOperator.RealVectorParameter.ActualName = Name;
307    }
308    private void ConfigureRealVectorSolutionsOperators(IEnumerable<IRealVectorSolutionsOperator> solutionsOperators) {
309      foreach (var solutionsOperator in solutionsOperators)
310        solutionsOperator.RealVectorsParameter.ActualName = Name;
311    }
312    private void ConfigureRealVectorBoundedOperators(IEnumerable<IRealVectorBoundedOperator> boundedOperators) {
313      foreach (var boundedOperator in boundedOperators) {
314        boundedOperator.BoundsParameter.ActualName = BoundsParameter.Name;
315      }
316    }
317    #endregion
318  }
319}
Note: See TracBrowser for help on using the repository browser.