Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2174: Adapted encodings to store its specific parameters in the standard parameter collection.

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