Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2174: Worked on operators and programmable problem base classes and scripts.

File size: 14.0 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 (value.Value == null) throw new ArgumentNullException("Length parameter value must not be null.");
46        if (lengthParameter == value) return;
47
48        if (lengthParameter != null) Parameters.Remove(lengthParameter);
49        lengthParameter = value;
50        Parameters.Add(lengthParameter);
51        OnLengthParameterChanged();
52      }
53    }
54    [Storable]
55    private IValueParameter<DoubleMatrix> boundsParameter;
56    public IValueParameter<DoubleMatrix> BoundsParameter {
57      get { return boundsParameter; }
58      set {
59        if (value == null) throw new ArgumentNullException("Bounds parameter must not be null.");
60        if (boundsParameter == value) return;
61
62        if (boundsParameter != null) Parameters.Remove(boundsParameter);
63        boundsParameter = value;
64        Parameters.Add(boundsParameter);
65        OnBoundsParameterChanged();
66      }
67    }
68    #endregion
69
70    public int Length {
71      get { return LengthParameter.Value.Value; }
72      set { LengthParameter.Value.Value = value; }
73    }
74    public DoubleMatrix Bounds {
75      get { return BoundsParameter.Value; }
76      set { BoundsParameter.Value = value; }
77    }
78
79    [StorableConstructor]
80    private RealEncoding(bool deserializing) : base(deserializing) { }
81    [StorableHook(HookType.AfterDeserialization)]
82    private void AfterDeserialization() {
83      RegisterParameterEvents();
84      DiscoverOperators();
85    }
86
87    public override IDeepCloneable Clone(Cloner cloner) { return new RealEncoding(this, cloner); }
88    private RealEncoding(RealEncoding original, Cloner cloner)
89      : base(original, cloner) {
90      lengthParameter = cloner.Clone(original.lengthParameter);
91      boundsParameter = cloner.Clone(original.boundsParameter);
92      RegisterParameterEvents();
93    }
94
95    public RealEncoding() : this("RealVector", 10) { }
96    public RealEncoding(int length) : this("RealVector", length) { }
97    public RealEncoding(string name, int length, double min = double.MinValue, double max = double.MaxValue)
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 RealEncoding(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
129      SolutionCreator = new UniformRandomRealVectorCreator();
130      RegisterParameterEvents();
131      DiscoverOperators();
132    }
133
134    private void OnLengthParameterChanged() {
135      RegisterLengthParameterEvents();
136      ConfigureOperators(Operators);
137    }
138    private void OnBoundsParameterChanged() {
139      RegisterBoundsParameterEvents();
140      ConfigureOperators(Operators);
141    }
142
143    private void RegisterParameterEvents() {
144      RegisterLengthParameterEvents();
145      RegisterBoundsParameterEvents();
146    }
147    private void RegisterLengthParameterEvents() {
148      LengthParameter.ValueChanged += (o, s) => ConfigureOperators(Operators);
149      LengthParameter.Value.ValueChanged += (o, s) => ConfigureOperators(Operators);
150    }
151    private void RegisterBoundsParameterEvents() {
152      BoundsParameter.ValueChanged += (o, s) => ConfigureOperators(Operators);
153      boundsParameter.Value.ToStringChanged += (o, s) => ConfigureOperators(Operators);
154    }
155
156    #region Operator Discovery
157    private static readonly IEnumerable<Type> encodingSpecificOperatorTypes;
158    static RealEncoding() {
159      encodingSpecificOperatorTypes = new List<Type>() {
160          typeof (IRealVectorOperator),
161          typeof (IRealVectorCreator),
162          typeof (IRealVectorCrossover),
163          typeof (IRealVectorManipulator),
164          typeof (IRealVectorStdDevStrategyParameterOperator),
165          typeof (IRealVectorSwarmUpdater),
166          typeof (IRealVectorParticleCreator),
167          typeof (IRealVectorParticleUpdater),
168          typeof (IRealVectorMultiNeighborhoodShakingOperator),
169          typeof (IRealVectorBoundsChecker),
170          typeof (IRealVectorMoveOperator),
171          typeof (IRealVectorMoveGenerator)
172      };
173    }
174    private void DiscoverOperators() {
175      var discoveredTypes = ApplicationManager.Manager.GetTypes(encodingSpecificOperatorTypes, true, false, false);
176      var operators = discoveredTypes.Select(t => (IOperator)Activator.CreateInstance(t));
177      var newOperators = operators.Except(Operators, new TypeEqualityComparer<IOperator>()).ToList();
178
179      ConfigureOperators(newOperators);
180      foreach (var @operator in newOperators)
181        encodingOperators.Add(@operator);
182
183      foreach (var strategyVectorCreator in Operators.OfType<IRealVectorStdDevStrategyParameterCreator>())
184        strategyVectorCreator.BoundsParameter.ValueChanged += strategyVectorCreator_BoundsParameter_ValueChanged;
185    }
186    #endregion
187
188
189    private void strategyVectorCreator_BoundsParameter_ValueChanged(object sender, EventArgs e) {
190      var boundsParameter = (IValueLookupParameter<DoubleMatrix>)sender;
191      if (boundsParameter.Value == null) return;
192      foreach (var strategyVectorManipulator in Operators.OfType<IRealVectorStdDevStrategyParameterManipulator>())
193        strategyVectorManipulator.BoundsParameter.Value = (DoubleMatrix)boundsParameter.Value.Clone();
194    }
195
196    public override void ConfigureOperators(IEnumerable<IOperator> operators) {
197      ConfigureCreators(operators.OfType<IRealVectorCreator>());
198      ConfigureCrossovers(operators.OfType<IRealVectorCrossover>());
199      ConfigureManipulators(operators.OfType<IRealVectorManipulator>());
200      ConfigureStdDevStrategyParameterOperators(operators.OfType<IRealVectorStdDevStrategyParameterOperator>());
201      ConfigureSwarmUpdaters(operators.OfType<IRealVectorSwarmUpdater>());
202      ConfigureParticleCreators(operators.OfType<IRealVectorParticleCreator>());
203      ConfigureParticleUpdaters(operators.OfType<IRealVectorParticleUpdater>());
204      ConfigureShakingOperators(operators.OfType<IRealVectorMultiNeighborhoodShakingOperator>());
205      ConfigureBoundsCheckers(operators.OfType<IRealVectorBoundsChecker>());
206      ConfigureMoveGenerators(operators.OfType<IRealVectorMoveGenerator>());
207      ConfigureMoveOperators(operators.OfType<IRealVectorMoveOperator>());
208      ConfigureAdditiveMoveOperator(operators.OfType<IAdditiveRealVectorMoveOperator>());
209    }
210
211    #region Specific Operator Wiring
212    private void ConfigureCreators(IEnumerable<IRealVectorCreator> creators) {
213      foreach (var creator in creators) {
214        creator.RealVectorParameter.ActualName = Name;
215        creator.LengthParameter.ActualName = LengthParameter.Name;
216        creator.BoundsParameter.ActualName = BoundsParameter.Name;
217      }
218    }
219    private void ConfigureCrossovers(IEnumerable<IRealVectorCrossover> crossovers) {
220      foreach (var crossover in crossovers) {
221        crossover.ChildParameter.ActualName = Name;
222        crossover.ParentsParameter.ActualName = Name;
223        crossover.BoundsParameter.ActualName = BoundsParameter.Name;
224      }
225    }
226    private void ConfigureManipulators(IEnumerable<IRealVectorManipulator> manipulators) {
227      foreach (var manipulator in manipulators) {
228        manipulator.RealVectorParameter.ActualName = Name;
229        manipulator.BoundsParameter.ActualName = BoundsParameter.Name;
230        manipulator.BoundsParameter.Hidden = true;
231        var sm = manipulator as ISelfAdaptiveManipulator;
232        if (sm != null) {
233          var p = sm.StrategyParameterParameter as ILookupParameter;
234          if (p != null) {
235            p.ActualName = Name + ".Strategy";
236          }
237        }
238      }
239    }
240    private void ConfigureStdDevStrategyParameterOperators(IEnumerable<IRealVectorStdDevStrategyParameterOperator> strategyOperators) {
241      var bounds = new DoubleMatrix(Bounds.Rows, Bounds.Columns);
242      for (var i = 0; i < Bounds.Rows; i++) {
243        bounds[i, 0] = 0;
244        bounds[i, 1] = 0.1 * (Bounds[i, 1] - Bounds[i, 0]);
245      }
246      foreach (var s in strategyOperators) {
247        var c = s as IRealVectorStdDevStrategyParameterCreator;
248        if (c != null) {
249          c.BoundsParameter.Value = (DoubleMatrix)bounds.Clone();
250          c.LengthParameter.ActualName = LengthParameter.Name;
251          c.StrategyParameterParameter.ActualName = Name + ".Strategy";
252        }
253        var m = s as IRealVectorStdDevStrategyParameterManipulator;
254        if (m != null) {
255          m.BoundsParameter.Value = (DoubleMatrix)bounds.Clone();
256          m.StrategyParameterParameter.ActualName = Name + ".Strategy";
257        }
258        var mm = s as StdDevStrategyVectorManipulator;
259        if (mm != null) {
260          mm.GeneralLearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * Length));
261          mm.LearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * Math.Sqrt(Length)));
262        }
263        var x = s as IRealVectorStdDevStrategyParameterCrossover;
264        if (x != null) {
265          x.ParentsParameter.ActualName = Name + ".Strategy";
266          x.StrategyParameterParameter.ActualName = Name + ".Strategy";
267        }
268      }
269    }
270    private void ConfigureSwarmUpdaters(IEnumerable<IRealVectorSwarmUpdater> swarmUpdaters) {
271      foreach (var su in swarmUpdaters) {
272        su.RealVectorParameter.ActualName = Name;
273      }
274    }
275    private void ConfigureParticleCreators(IEnumerable<IRealVectorParticleCreator> particleCreators) {
276      foreach (var particleCreator in particleCreators) {
277        particleCreator.RealVectorParameter.ActualName = Name;
278        particleCreator.BoundsParameter.ActualName = BoundsParameter.Name;
279        particleCreator.ProblemSizeParameter.ActualName = LengthParameter.Name;
280      }
281    }
282    private void ConfigureParticleUpdaters(IEnumerable<IRealVectorParticleUpdater> particleUpdaters) {
283      foreach (var particleUpdater in particleUpdaters) {
284        particleUpdater.RealVectorParameter.ActualName = Name;
285        particleUpdater.BoundsParameter.ActualName = BoundsParameter.Name;
286      }
287    }
288    private void ConfigureShakingOperators(IEnumerable<IRealVectorMultiNeighborhoodShakingOperator> shakingOperators) {
289      foreach (var shakingOperator in shakingOperators) {
290        shakingOperator.RealVectorParameter.ActualName = Name;
291      }
292    }
293    private void ConfigureBoundsCheckers(IEnumerable<IRealVectorBoundsChecker> boundsCheckers) {
294      foreach (var boundsChecker in boundsCheckers) {
295        boundsChecker.RealVectorParameter.ActualName = Name;
296        boundsChecker.BoundsParameter.ActualName = BoundsParameter.Name;
297      }
298    }
299    private void ConfigureMoveOperators(IEnumerable<IRealVectorMoveOperator> moveOperators) {
300      foreach (var moveOperator in moveOperators)
301        moveOperator.RealVectorParameter.ActualName = Name;
302    }
303
304    private void ConfigureMoveGenerators(IEnumerable<IRealVectorMoveGenerator> moveGenerators) {
305      foreach (var moveGenerator in moveGenerators)
306        moveGenerator.BoundsParameter.ActualName = BoundsParameter.Name;
307    }
308
309    private void ConfigureAdditiveMoveOperator(IEnumerable<IAdditiveRealVectorMoveOperator> additiveMoveOperators) {
310      foreach (var additiveMoveOperator in additiveMoveOperators) {
311        additiveMoveOperator.AdditiveMoveParameter.ActualName = Name + ".AdditiveMove";
312      }
313    }
314    #endregion
315  }
316}
Note: See TracBrowser for help on using the repository browser.