Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2174: Adapted binary encoding to new wiring method.

File size: 13.1 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;
24using System.Collections.Generic;
25using System.Linq;
26using System.Runtime.CompilerServices;
27using System.Text;
28using HeuristicLab.Common;
29using HeuristicLab.Core;
30using HeuristicLab.Data;
31using HeuristicLab.Encodings.RealVectorEncoding;
32using HeuristicLab.Optimization;
33using HeuristicLab.Parameters;
34using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
35using HeuristicLab.PluginInfrastructure;
36
37namespace HeuristicLab.Problems.Programmable {
38  [Item("RealEncoding", "Describes a real vector encoding.")]
39  [StorableClass]
40  public sealed class RealEncoding : Encoding {
41    #region Encoding Parameters
42    [Storable]
43    private IFixedValueParameter<IntValue> lengthParameter;
44    public IFixedValueParameter<IntValue> LengthParameter {
45      get { return lengthParameter; }
46      set {
47        if (value == null) throw new ArgumentNullException("Length parameter must not be null.");
48        if (lengthParameter == value) return;
49        lengthParameter = value;
50        OnLengthParameterChanged();
51      }
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        boundsParameter = value;
62        OnBoundsParameterChanged();
63      }
64    }
65
66    public override IEnumerable<IValueParameter> Parameters {
67      get { return base.Parameters.Concat(new IValueParameter[] { LengthParameter, BoundsParameter }); }
68    }
69    #endregion
70
71    private List<IOperator> encodingOperators = new List<IOperator>();
72    [Storable]
73    public override IEnumerable<IOperator> Operators {
74      get { return encodingOperators; }
75      protected set { encodingOperators = new List<IOperator>(value); }
76    }
77
78    public override ISolutionCreator DefaultSolutionCreator {
79      get { return Operators.OfType<UniformRandomRealVectorCreator>().First(); }
80    }
81
82    public int Length {
83      get { return LengthParameter.Value.Value; }
84      set { LengthParameter.Value.Value = value; }
85    }
86    public DoubleMatrix Bounds {
87      get { return BoundsParameter.Value; }
88      set { BoundsParameter.Value = value; }
89    }
90
91
92
93    [StorableConstructor]
94    private RealEncoding(bool deserializing) : base(deserializing) { }
95    [StorableHook(HookType.AfterDeserialization)]
96    private void AfterDeserialization() {
97      RegisterParameterEvents();
98      DiscoverOperators();
99    }
100
101    public override IDeepCloneable Clone(Cloner cloner) { return new RealEncoding(this, cloner); }
102    private RealEncoding(RealEncoding original, Cloner cloner)
103      : base(original, cloner) {
104      lengthParameter = cloner.Clone(original.lengthParameter);
105      boundsParameter = cloner.Clone(original.boundsParameter);
106      encodingOperators = original.Operators.Select(cloner.Clone).ToList();
107      RegisterParameterEvents();
108    }
109
110
111
112    public RealEncoding(string name, int length, double min, double max)
113      : base(name) {
114      if (min >= max) throw new ArgumentException("min must be less than max", "min");
115
116      var bounds = new DoubleMatrix(1, 2);
117      bounds[0, 0] = min;
118      bounds[0, 1] = max;
119
120      lengthParameter = new FixedValueParameter<IntValue>(Name + "Length", new IntValue(length));
121      boundsParameter = new ValueParameter<DoubleMatrix>(Name + "Bounds", bounds);
122      RegisterParameterEvents();
123      DiscoverOperators();
124    }
125
126    public RealEncoding(string name, int length, IList<double> min, IList<double> max)
127      : base(name) {
128      if (min.Count == 0) throw new ArgumentException("Bounds must be given for the real parameters.");
129      if (min.Count != max.Count) throw new ArgumentException("min must be of the same length as max", "min");
130      if (min.Zip(max, (mi, ma) => mi >= ma).Any(x => x)) throw new ArgumentException("min must be less than max in each dimension", "min");
131
132      var bounds = new DoubleMatrix(min.Count, 2);
133      for (int i = 0; i < min.Count; i++) {
134        bounds[i, 0] = min[i];
135        bounds[i, 1] = max[i];
136      }
137      lengthParameter = new FixedValueParameter<IntValue>(Name + "Length", new IntValue(length));
138      boundsParameter = new ValueParameter<DoubleMatrix>(Name + "Bounds", bounds);
139      RegisterParameterEvents();
140      DiscoverOperators();
141    }
142
143    private void OnLengthParameterChanged() {
144      RegisterLengthParameterEvents();
145      ConfigureOperators(Operators);
146    }
147    private void OnBoundsParameterChanged() {
148      RegisterBoundsParameterEvents();
149      ConfigureOperators(Operators);
150    }
151    private void RegisterParameterEvents() {
152      RegisterLengthParameterEvents();
153      RegisterBoundsParameterEvents();
154    }
155    private void RegisterLengthParameterEvents() {
156      LengthParameter.ValueChanged += (o, s) => ConfigureOperators(Operators);
157      LengthParameter.Value.ValueChanged += (o, s) => ConfigureOperators(Operators);
158    }
159    private void RegisterBoundsParameterEvents() {
160      BoundsParameter.ValueChanged += (o, s) => ConfigureOperators(Operators);
161      boundsParameter.Value.ToStringChanged += (o, s) => ConfigureOperators(Operators);
162    }
163
164    #region Operator Discovery
165    private static readonly IEnumerable<Type> encodingSpecificOperatorTypes;
166    static RealEncoding() {
167      encodingSpecificOperatorTypes = new List<Type>() {
168        typeof (IRealVectorOperator),
169        typeof (IRealVectorCreator),
170        typeof (IRealVectorCrossover),
171        typeof (IRealVectorManipulator),
172        typeof (IRealVectorStdDevStrategyParameterOperator),
173        typeof (IRealVectorSwarmUpdater),
174        typeof (IRealVectorParticleCreator),
175        typeof (IRealVectorParticleUpdater),
176        typeof (IRealVectorMultiNeighborhoodShakingOperator),
177        typeof (IRealVectorBoundsChecker),
178        typeof (IRealVectorMoveOperator),
179        typeof (IRealVectorMoveGenerator)
180      };
181    }
182    private void DiscoverOperators() {
183      var pluginDescription = ApplicationManager.Manager.GetDeclaringPlugin(typeof(IRealVectorOperator));
184      var discoveredTypes = ApplicationManager.Manager.GetTypes(encodingSpecificOperatorTypes, pluginDescription, true, false, false);
185      var operators = discoveredTypes.Select(t => (IOperator)Activator.CreateInstance(t));
186      var newOperators = operators.Except(encodingOperators, new TypeEqualityComparer<IOperator>()).ToList();
187
188      ConfigureOperators(newOperators);
189      encodingOperators.AddRange(newOperators);
190    }
191    #endregion
192
193    public void ConfigureOperators(IEnumerable<IOperator> operators) {
194      ConfigureCreators(operators.OfType<IRealVectorCreator>());
195      ConfigureCrossovers(operators.OfType<IRealVectorCrossover>());
196      ConfigureManipulators(operators.OfType<IRealVectorManipulator>());
197      ConfigureStdDevStrategyParameterOperators(operators.OfType<IRealVectorStdDevStrategyParameterOperator>());
198      ConfigureSwarmUpdaters(operators.OfType<IRealVectorSwarmUpdater>());
199      ConfigureParticleCreators(operators.OfType<IRealVectorParticleCreator>());
200      ConfigureParticleUpdaters(operators.OfType<IRealVectorParticleUpdater>());
201      ConfigureShakingOperators(operators.OfType<IRealVectorMultiNeighborhoodShakingOperator>());
202      ConfigureBoundsCheckers(operators.OfType<IRealVectorBoundsChecker>());
203      ConfigureMoveOperators(operators.OfType<IRealVectorMoveOperator>());
204      ConfigureMoveGenerators(operators.OfType<IRealVectorMoveGenerator>());
205    }
206
207    #region Specific Operator Wiring
208    private void ConfigureCreators(IEnumerable<IRealVectorCreator> creators) {
209      foreach (var creator in creators) {
210        creator.RealVectorParameter.ActualName = Name;
211        creator.LengthParameter.ActualName = LengthParameter.Name;
212        creator.BoundsParameter.ActualName = BoundsParameter.Name;
213      }
214    }
215    private void ConfigureCrossovers(IEnumerable<IRealVectorCrossover> crossovers) {
216      foreach (var crossover in crossovers) {
217        crossover.ChildParameter.ActualName = Name;
218        crossover.ParentsParameter.ActualName = Name;
219        crossover.BoundsParameter.ActualName = BoundsParameter.Name;
220      }
221    }
222    private void ConfigureManipulators(IEnumerable<IRealVectorManipulator> manipulators) {
223      foreach (var manipulator in manipulators) {
224        manipulator.RealVectorParameter.ActualName = Name;
225        manipulator.BoundsParameter.ActualName = BoundsParameter.Name;
226        manipulator.BoundsParameter.Hidden = true;
227        var sm = manipulator as ISelfAdaptiveManipulator;
228        if (sm != null) {
229          var p = sm.StrategyParameterParameter as ILookupParameter;
230          if (p != null) {
231            p.ActualName = Name + "Strategy";
232            p.Hidden = true;
233          }
234        }
235      }
236    }
237    private void ConfigureStdDevStrategyParameterOperators(IEnumerable<IRealVectorStdDevStrategyParameterOperator> strategyOperators) {
238      var bounds = (DoubleMatrix)Bounds.Clone();
239      for (var i = 0; i < bounds.Rows; i++) {
240        bounds[i, 1] = 0.1 * (bounds[i, 1] - bounds[i, 0]);
241        bounds[i, 0] = 0;
242      }
243      foreach (var s in strategyOperators) {
244        var c = s as IRealVectorStdDevStrategyParameterCreator;
245        if (c != null) {
246          c.BoundsParameter.Value = (DoubleMatrix)bounds.Clone();
247          c.LengthParameter.ActualName = LengthParameter.Name;
248          c.StrategyParameterParameter.ActualName = Name + "Strategy";
249        }
250        var m = s as IRealVectorStdDevStrategyParameterManipulator;
251        if (m != null) {
252          m.BoundsParameter.Value = (DoubleMatrix)bounds.Clone();
253          m.StrategyParameterParameter.ActualName = Name + "Strategy";
254        }
255        var mm = s as StdDevStrategyVectorManipulator;
256        if (mm != null) {
257          mm.GeneralLearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * Length));
258          mm.LearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * Math.Sqrt(Length)));
259        }
260        var x = s as IRealVectorStdDevStrategyParameterCrossover;
261        if (x != null) {
262          x.ParentsParameter.ActualName = Name + "Strategy";
263          x.StrategyParameterParameter.ActualName = Name + "Strategy";
264        }
265      }
266    }
267    private void ConfigureSwarmUpdaters(IEnumerable<IRealVectorSwarmUpdater> swarmUpdaters) {
268      foreach (var su in swarmUpdaters) {
269        su.RealVectorParameter.ActualName = Name;
270      }
271    }
272    private void ConfigureParticleCreators(IEnumerable<IRealVectorParticleCreator> particleCreators) {
273      foreach (var particleCreator in particleCreators) {
274        particleCreator.RealVectorParameter.ActualName = Name;
275        particleCreator.BoundsParameter.ActualName = BoundsParameter.Name;
276        particleCreator.ProblemSizeParameter.ActualName = LengthParameter.Name;
277      }
278    }
279    private void ConfigureParticleUpdaters(IEnumerable<IRealVectorParticleUpdater> particleUpdaters) {
280      foreach (var particleUpdater in particleUpdaters) {
281        particleUpdater.RealVectorParameter.ActualName = Name;
282        particleUpdater.BoundsParameter.ActualName = BoundsParameter.Name;
283      }
284    }
285    private void ConfigureShakingOperators(IEnumerable<IRealVectorMultiNeighborhoodShakingOperator> shakingOperators) {
286      foreach (var shakingOperator in shakingOperators) {
287        shakingOperator.RealVectorParameter.ActualName = Name;
288      }
289    }
290    private void ConfigureBoundsCheckers(IEnumerable<IRealVectorBoundsChecker> boundsCheckers) {
291      foreach (var boundsChecker in boundsCheckers) {
292        boundsChecker.RealVectorParameter.ActualName = Name;
293        boundsChecker.BoundsParameter.ActualName = BoundsParameter.Name;
294      }
295    }
296    private void ConfigureMoveOperators(IEnumerable<IRealVectorMoveOperator> moveOperators) {
297      foreach (var moveOperator in moveOperators)
298        moveOperator.RealVectorParameter.ActualName = Name;
299    }
300
301    private void ConfigureMoveGenerators(IEnumerable<IRealVectorMoveGenerator> moveGenerators) {
302      foreach (var moveGenerator in moveGenerators)
303        moveGenerator.BoundsParameter.ActualName = BoundsParameter.Name;
304    }
305    #endregion
306  }
307}
Note: See TracBrowser for help on using the repository browser.