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

Last change on this file since 11587 was 11587, checked in by mkommend, 8 years ago

#2174: Implemented multi-encoding operators and adapated wiring of operators in the programmable problems.

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