Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2174: Adapted IntegerEncoding to include the wiring code of operators.

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          }
226        }
227      }
228    }
229    private void ConfigureStdDevStrategyParameterOperators(IEnumerable<IRealVectorStdDevStrategyParameterOperator> strategyOperators) {
230      var bounds = new DoubleMatrix(Bounds.Rows, Bounds.Columns);
231      for (var i = 0; i < Bounds.Rows; i++) {
232        bounds[i, 0] = 0;
233        bounds[i, 1] = 0.1 * (Bounds[i, 1] - Bounds[i, 0]);
234      }
235      foreach (var s in strategyOperators) {
236        var c = s as IRealVectorStdDevStrategyParameterCreator;
237        if (c != null) {
238          c.BoundsParameter.Value = (DoubleMatrix)bounds.Clone();
239          c.LengthParameter.ActualName = LengthParameter.Name;
240          c.StrategyParameterParameter.ActualName = Name + "Strategy";
241        }
242        var m = s as IRealVectorStdDevStrategyParameterManipulator;
243        if (m != null) {
244          m.BoundsParameter.Value = (DoubleMatrix)bounds.Clone();
245          m.StrategyParameterParameter.ActualName = Name + "Strategy";
246        }
247        var mm = s as StdDevStrategyVectorManipulator;
248        if (mm != null) {
249          mm.GeneralLearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * Length));
250          mm.LearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * Math.Sqrt(Length)));
251        }
252        var x = s as IRealVectorStdDevStrategyParameterCrossover;
253        if (x != null) {
254          x.ParentsParameter.ActualName = Name + "Strategy";
255          x.StrategyParameterParameter.ActualName = Name + "Strategy";
256        }
257      }
258    }
259    private void ConfigureSwarmUpdaters(IEnumerable<IRealVectorSwarmUpdater> swarmUpdaters) {
260      foreach (var su in swarmUpdaters) {
261        su.RealVectorParameter.ActualName = Name;
262      }
263    }
264    private void ConfigureParticleCreators(IEnumerable<IRealVectorParticleCreator> particleCreators) {
265      foreach (var particleCreator in particleCreators) {
266        particleCreator.RealVectorParameter.ActualName = Name;
267        particleCreator.BoundsParameter.ActualName = BoundsParameter.Name;
268        particleCreator.ProblemSizeParameter.ActualName = LengthParameter.Name;
269      }
270    }
271    private void ConfigureParticleUpdaters(IEnumerable<IRealVectorParticleUpdater> particleUpdaters) {
272      foreach (var particleUpdater in particleUpdaters) {
273        particleUpdater.RealVectorParameter.ActualName = Name;
274        particleUpdater.BoundsParameter.ActualName = BoundsParameter.Name;
275      }
276    }
277    private void ConfigureShakingOperators(IEnumerable<IRealVectorMultiNeighborhoodShakingOperator> shakingOperators) {
278      foreach (var shakingOperator in shakingOperators) {
279        shakingOperator.RealVectorParameter.ActualName = Name;
280      }
281    }
282    private void ConfigureBoundsCheckers(IEnumerable<IRealVectorBoundsChecker> boundsCheckers) {
283      foreach (var boundsChecker in boundsCheckers) {
284        boundsChecker.RealVectorParameter.ActualName = Name;
285        boundsChecker.BoundsParameter.ActualName = BoundsParameter.Name;
286      }
287    }
288    private void ConfigureMoveOperators(IEnumerable<IRealVectorMoveOperator> moveOperators) {
289      foreach (var moveOperator in moveOperators)
290        moveOperator.RealVectorParameter.ActualName = Name;
291    }
292
293    private void ConfigureMoveGenerators(IEnumerable<IRealVectorMoveGenerator> moveGenerators) {
294      foreach (var moveGenerator in moveGenerators)
295        moveGenerator.BoundsParameter.ActualName = BoundsParameter.Name;
296    }
297
298    private void ConfigureAdditiveMoveOperator(IEnumerable<IAdditiveRealVectorMoveOperator> additiveMoveOperators) {
299      foreach (var additiveMoveOperator in additiveMoveOperators) {
300        additiveMoveOperator.AdditiveMoveParameter.ActualName = Name + "_AdditiveMove";
301      }
302    }
303    #endregion
304  }
305}
Note: See TracBrowser for help on using the repository browser.