Free cookie consent management tool by TermsFeed Policy Generator

source: branches/ProgrammableProblem/HeuristicLab.Problems.Programmable/3.3/MultiObjectiveProgrammableProblem.cs @ 11543

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

#2174: Refactoring of encodings to allow wiring of operators within the encoding instead of the problem (work in progress).

File size: 44.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.Drawing;
25using System.Linq;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Data;
29using HeuristicLab.Encodings.BinaryVectorEncoding;
30using HeuristicLab.Encodings.IntegerVectorEncoding;
31using HeuristicLab.Encodings.PermutationEncoding;
32using HeuristicLab.Encodings.RealVectorEncoding;
33using HeuristicLab.Optimization;
34using HeuristicLab.Parameters;
35using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
36using HeuristicLab.PluginInfrastructure;
37
38namespace HeuristicLab.Problems.Programmable {
39  [Item("Programmable Problem (multi-objective)", "Represents a multi-objective problem that can be programmed.")]
40  [Creatable("Problems")]
41  [StorableClass]
42  public class MultiObjectiveProgrammableProblem : MultiObjectiveHeuristicOptimizationProblem<IMultiObjectiveProgrammableProblemEvaluator, ISolutionCreator>, IParameterizedNamedItem, IStorableContent {
43    public string Filename { get; set; }
44
45    public static new Image StaticItemImage {
46      get { return Common.Resources.VSImageLibrary.Script; }
47    }
48
49    public new ParameterCollection Parameters {
50      get { return base.Parameters; }
51    }
52    IKeyedItemCollection<string, IParameter> IParameterizedItem.Parameters {
53      get { return Parameters; }
54    }
55
56    public IValueParameter<IMultiObjectiveProblemDefinition> ProblemDefinitionParameter {
57      get { return (IValueParameter<IMultiObjectiveProblemDefinition>)Parameters["ProblemDefinition"]; }
58    }
59
60    protected IValueParameter<Encoding> EncodingParameter {
61      get { return (IValueParameter<Encoding>)Parameters["Encoding"]; }
62    }
63
64    public IMultiObjectiveProblemDefinition ProblemDefinition {
65      get { return ProblemDefinitionParameter.Value; }
66      set { ProblemDefinitionParameter.Value = value; }
67    }
68
69    [Storable]
70    protected List<IParameter> DynamicEncodingParameters;
71
72    [StorableConstructor]
73    protected MultiObjectiveProgrammableProblem(bool deserializing) : base(deserializing) { }
74    protected MultiObjectiveProgrammableProblem(MultiObjectiveProgrammableProblem original, Cloner cloner)
75      : base(original, cloner) {
76      DynamicEncodingParameters = original.DynamicEncodingParameters.Select(cloner.Clone).ToList();
77      RegisterEventHandlers();
78    }
79    public MultiObjectiveProgrammableProblem()
80      : base(new MultiObjectiveEvaluator(), new MultiEncodingCreator()) {
81      Parameters.Add(new ValueParameter<IMultiObjectiveProblemDefinition>("ProblemDefinition", "Defines the problem.", new MultiObjectiveProblemScript() { Name = Name }));
82      Parameters.Add(new ValueParameter<Encoding>("Encoding", "Describes which parameters exist, what they're called, what type they are and their bounds if any."));
83
84      DynamicEncodingParameters = new List<IParameter>();
85
86      Operators.Add(new MultiObjectiveAnalyzer());
87      Operators.Add(Evaluator);
88      Operators.Add(SolutionCreator);
89
90      RegisterEventHandlers();
91    }
92
93    public override IDeepCloneable Clone(Cloner cloner) {
94      return new MultiObjectiveProgrammableProblem(this, cloner);
95    }
96
97    [StorableHook(HookType.AfterDeserialization)]
98    // ReSharper disable UnusedMember.Local
99    private void AfterDeserialization() {
100      RegisterEventHandlers();
101    }
102    // ReSharper restore UnusedMember.Local
103
104    private void RegisterEventHandlers() {
105      ProblemDefinitionParameter.ValueChanged += ProblemDefinitionParameterOnValueChanged;
106      RegisterHostInstanceChanges();
107    }
108
109    private void ProblemDefinitionParameterOnValueChanged(object sender, EventArgs eventArgs) {
110      RegisterHostInstanceChanges();
111      Parameterize();
112    }
113
114    private void RegisterHostInstanceChanges() {
115      ProblemDefinitionParameter.Value.ProblemDefinitionChanged += ProblemDefinitionChanged;
116      ProblemDefinitionParameter.Value.NameChanged += ProblemDefinitionHostOnNameChanged;
117    }
118
119    private void ProblemDefinitionHostOnNameChanged(object sender, EventArgs eventArgs) {
120      if (sender != ProblemDefinitionParameter.Value) return;
121      Name = ProblemDefinitionParameter.Value.Name;
122    }
123
124    protected override void OnNameChanged() {
125      base.OnNameChanged();
126      ProblemDefinitionParameter.Value.Name = Name;
127    }
128
129    protected override void OnEvaluatorChanged() {
130      base.OnEvaluatorChanged();
131      Parameterize();
132    }
133
134    protected virtual void ProblemDefinitionChanged(object sender, EventArgs eventArgs) {
135      Parameterize();
136    }
137
138    protected virtual void Parameterize() {
139      var definition = ProblemDefinitionParameter.Value;
140      if (definition == null) return;
141
142      Encoding encoding = definition.Encoding;
143      EncodingParameter.Value = encoding;
144      Maximization = new BoolArray(definition.Maximization);
145
146      Evaluator.EncodingParameter.ActualName = EncodingParameter.Name;
147      Evaluator.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name;
148      foreach (var evalOp in Operators.OfType<IMultiObjectiveProgrammableProblemEvaluator>()) {
149        evalOp.EncodingParameter.ActualName = EncodingParameter.Name;
150        evalOp.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name;
151      }
152      foreach (var analyzeOp in Operators.OfType<IMultiObjectiveProgrammableProblemAnalyzer>()) {
153        analyzeOp.EncodingParameter.ActualName = EncodingParameter.Name;
154        analyzeOp.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name;
155        analyzeOp.QualitiesParameter.ActualName = Evaluator.QualitiesParameter.ActualName;
156      }
157
158      foreach (var param in DynamicEncodingParameters)
159        if (Parameters.Contains(param)) Parameters.Remove(param);
160      DynamicEncodingParameters.Clear();
161
162      var creator = ConfigureCreator(encoding);
163
164      foreach (var param in DynamicEncodingParameters) {
165        param.Hidden = true;
166        Parameters.Add(param);
167      }
168
169      var multiEncoding = encoding as MultiEncoding;
170      if (multiEncoding != null) {
171        ConfigureMultiVectorEncodingOperators((MultiEncodingCreator)creator, multiEncoding);
172      } else {
173        ConfigureSingleEncodingOperators(creator, encoding);
174      }
175    }
176
177    protected virtual ISolutionCreator ConfigureCreator(Encoding encoding) {
178      #region Configure MultiEncoding Creator
179      var multiEncoding = encoding as MultiEncoding;
180      if (multiEncoding != null) {
181        var creator = new MultiEncodingCreator();
182        foreach (var enc in multiEncoding.Encodings) {
183          if (enc is MultiEncoding) throw new InvalidOperationException("MultiEncoding within a MultiEncoding is not supported.");
184          creator.Operators.Add(ConfigureCreator(enc));
185        }
186        return creator;
187      }
188      #endregion
189      #region Configure BinaryVector Creator
190      var binEnc = encoding as BinaryEncoding;
191      if (binEnc != null) {
192        var p = new ValueParameter<IntValue>(binEnc.Name + "Length", binEnc.Length);
193        DynamicEncodingParameters.Add(p);
194
195        var creator = new RandomBinaryVectorCreator();
196        creator.BinaryVectorParameter.ActualName = binEnc.Name;
197        creator.LengthParameter.ActualName = p.Name;
198        return creator;
199      }
200      #endregion
201      #region Configure IntegerVector Creator
202      var intEnc = encoding as IntegerEncoding;
203      if (intEnc != null) {
204        var l = new ValueParameter<IntValue>(intEnc.Name + "Length", intEnc.Length);
205        var b = new ValueParameter<IntMatrix>(intEnc.Name + "Bounds", intEnc.Bounds);
206        DynamicEncodingParameters.Add(l);
207        DynamicEncodingParameters.Add(b);
208
209        var creator = new UniformRandomIntegerVectorCreator();
210        creator.IntegerVectorParameter.ActualName = intEnc.Name;
211        creator.LengthParameter.ActualName = l.Name;
212        creator.BoundsParameter.ActualName = b.Name;
213        return creator;
214      }
215      #endregion
216      #region Configure RealVector Creator
217      var realEnc = encoding as RealEncoding;
218      if (realEnc != null) {
219        DynamicEncodingParameters.AddRange(realEnc.EncodingParameters);
220        return realEnc.SolutionCreator;
221      }
222      #endregion
223      #region Configure Permutation Creator
224      var permEnc = encoding as PermutationEncoding;
225      if (permEnc != null) {
226        var l = new ValueParameter<IntValue>(permEnc.Name + "Length", permEnc.Length);
227        DynamicEncodingParameters.Add(l);
228
229        var creator = new RandomPermutationCreator();
230        creator.PermutationParameter.ActualName = permEnc.Name;
231        creator.LengthParameter.ActualName = l.Name;
232        creator.PermutationTypeParameter.Value = permEnc.Type;
233        return creator;
234      }
235      #endregion
236      throw new ArgumentException(string.Format("Encoding {0} is unknown.", encoding != null ? encoding.GetType().FullName : "(null)"));
237    }
238
239    protected virtual void ConfigureSingleEncodingOperators(ISolutionCreator newCreator, Encoding encoding) {
240      // remove all multiencoding operators
241      Operators.RemoveAll(x => x is MultiEncodingCrossover
242                            || x is MultiEncodingManipulator
243                            || x is MultiEncodingCreator);
244
245      #region Configure Operators for BinaryVectorEncoding
246      var binCreator = newCreator as IBinaryVectorCreator;
247      if (binCreator != null) {
248        var paramName = binCreator.BinaryVectorParameter.ActualName;
249        // do not replace a binary vector creator that was manually set
250        if (!(SolutionCreator is IBinaryVectorCreator) || ((IBinaryVectorCreator)SolutionCreator).BinaryVectorParameter.ActualName != paramName) {
251          Operators.Remove(SolutionCreator);
252          SolutionCreator = newCreator;
253          Operators.Add(SolutionCreator);
254        }
255
256        #region Wire BinaryVector Crossovers
257        var crossovers = Operators.OfType<IBinaryVectorCrossover>()
258          .Union(ApplicationManager.Manager.GetInstances<IBinaryVectorCrossover>(), new TypeEqualityComparer<IBinaryVectorCrossover>())
259          .ToList();
260        foreach (var xo in crossovers) {
261          xo.ChildParameter.ActualName = binCreator.BinaryVectorParameter.ActualName;
262          xo.ChildParameter.Hidden = true;
263          xo.ParentsParameter.ActualName = binCreator.BinaryVectorParameter.ActualName;
264          xo.ParentsParameter.Hidden = true;
265        }
266        Operators.AddRange(crossovers.Except(Operators.OfType<IBinaryVectorCrossover>()));
267        #endregion
268        #region Wire BinaryVector Manipulators
269        var manipulators = Operators.OfType<IBinaryVectorManipulator>()
270          .Union(ApplicationManager.Manager.GetInstances<IBinaryVectorManipulator>(), new TypeEqualityComparer<IBinaryVectorManipulator>())
271          .ToList();
272        foreach (var m in manipulators) {
273          m.BinaryVectorParameter.ActualName = binCreator.BinaryVectorParameter.ActualName;
274          m.BinaryVectorParameter.Hidden = true;
275        }
276        Operators.AddRange(manipulators.Except(Operators.OfType<IBinaryVectorManipulator>()));
277        #endregion
278        #region Wire BinaryVector ShakingOperators
279        var shakingOperators = Operators.OfType<IBinaryVectorMultiNeighborhoodShakingOperator>()
280          .Union(ApplicationManager.Manager.GetInstances<IBinaryVectorMultiNeighborhoodShakingOperator>(), new TypeEqualityComparer<IBinaryVectorMultiNeighborhoodShakingOperator>())
281          .ToList();
282        foreach (var so in shakingOperators) {
283          so.BinaryVectorParameter.ActualName = paramName;
284          so.BinaryVectorParameter.Hidden = true;
285        }
286        Operators.AddRange(shakingOperators.Except(Operators.OfType<IBinaryVectorMultiNeighborhoodShakingOperator>()));
287        #endregion
288      } else {
289        Operators.RemoveAll(x => x is IBinaryVectorCrossover
290          || x is IBinaryVectorManipulator
291          || x is IBinaryVectorMultiNeighborhoodShakingOperator);
292      }
293      #endregion
294      #region Configure Operators for IntegerVectorEncoding
295      var intCreator = newCreator as IIntegerVectorCreator;
296      if (intCreator != null) {
297        var paramName = intCreator.IntegerVectorParameter.ActualName;
298        // do not replace an integer vector creator that was manually set
299        if (!(SolutionCreator is IIntegerVectorCreator)
300          || ((IIntegerVectorCreator)SolutionCreator).IntegerVectorParameter.ActualName != intCreator.IntegerVectorParameter.ActualName) {
301          Operators.Remove(SolutionCreator);
302          SolutionCreator = newCreator;
303          Operators.Add(SolutionCreator);
304        }
305
306        #region Wire IntegerVector Crossovers
307        var crossovers = Operators.OfType<IIntegerVectorCrossover>()
308          .Union(ApplicationManager.Manager.GetInstances<IIntegerVectorCrossover>(), new TypeEqualityComparer<IIntegerVectorCrossover>())
309          .ToList();
310        foreach (var xo in crossovers) {
311          xo.ChildParameter.ActualName = intCreator.IntegerVectorParameter.ActualName;
312          xo.ChildParameter.Hidden = true;
313          xo.ParentsParameter.ActualName = intCreator.IntegerVectorParameter.ActualName;
314          xo.ParentsParameter.Hidden = true;
315          var bx = xo as IBoundedIntegerVectorOperator;
316          if (bx != null) {
317            bx.BoundsParameter.ActualName = intCreator.BoundsParameter.ActualName;
318            bx.BoundsParameter.Hidden = true;
319          }
320        }
321        Operators.AddRange(crossovers.Except(Operators.OfType<IIntegerVectorCrossover>()));
322        #endregion
323        #region Wire IntegerVector Manipulators
324        var manipulators = Operators.OfType<IIntegerVectorManipulator>()
325          .Union(ApplicationManager.Manager.GetInstances<IIntegerVectorManipulator>(), new TypeEqualityComparer<IIntegerVectorManipulator>())
326          .ToList();
327        foreach (var m in manipulators) {
328          m.IntegerVectorParameter.ActualName = intCreator.IntegerVectorParameter.ActualName;
329          m.IntegerVectorParameter.Hidden = true;
330          var sm = m as ISelfAdaptiveManipulator;
331          if (sm != null) {
332            var p = sm.StrategyParameterParameter as ILookupParameter;
333            if (p != null) {
334              p.ActualName = paramName + "Strategy";
335              p.Hidden = true;
336            }
337          }
338          var bm = m as IBoundedIntegerVectorOperator;
339          if (bm != null) {
340            bm.BoundsParameter.ActualName = intCreator.BoundsParameter.ActualName;
341            bm.BoundsParameter.Hidden = true;
342          }
343        }
344        Operators.AddRange(manipulators.Except(Operators.OfType<IIntegerVectorManipulator>()));
345        #region Wire IntegerVector StrategyParameters for SelfAdaptiveManipulators
346        var strategyOperators = Operators.OfType<IIntegerVectorStdDevStrategyParameterOperator>()
347          .Union(ApplicationManager.Manager.GetInstances<IIntegerVectorStdDevStrategyParameterOperator>(), new TypeEqualityComparer<IIntegerVectorStdDevStrategyParameterOperator>())
348          .ToList();
349        var problemSize = ((IntegerEncoding)encoding).Length.Value;
350        var b = ((IntegerEncoding)encoding).Bounds;
351        var bounds = new DoubleMatrix(b.Rows, b.Columns);
352        for (var i = 0; i < bounds.Rows; i++) {
353          bounds[i, 1] = (int)Math.Ceiling(0.33 * (b[i, 1] - b[i, 0]));
354          bounds[i, 0] = 0;
355          if (bounds.Columns > 2) bounds[i, 2] = b[i, 2];
356        }
357        foreach (var s in strategyOperators) {
358          var c = s as IIntegerVectorStdDevStrategyParameterCreator;
359          if (c != null) {
360            c.BoundsParameter.Value = (DoubleMatrix)bounds.Clone();
361            c.LengthParameter.ActualName = intCreator.LengthParameter.ActualName;
362            c.StrategyParameterParameter.ActualName = paramName + "Strategy";
363          }
364          var m = s as IIntegerVectorStdDevStrategyParameterManipulator;
365          if (m != null) {
366            m.BoundsParameter.Value = (DoubleMatrix)bounds.Clone();
367            m.StrategyParameterParameter.ActualName = paramName + "Strategy";
368          }
369          var mm = s as Encodings.IntegerVectorEncoding.StdDevStrategyVectorManipulator;
370          if (mm != null) {
371            mm.GeneralLearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * problemSize));
372            mm.LearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * Math.Sqrt(problemSize)));
373          }
374          var x = s as IIntegerVectorStdDevStrategyParameterCrossover;
375          if (x != null) {
376            x.ParentsParameter.ActualName = paramName + "Strategy";
377            x.StrategyParameterParameter.ActualName = paramName + "Strategy";
378          }
379        }
380        Operators.AddRange(strategyOperators.Except(Operators.OfType<IIntegerVectorStdDevStrategyParameterOperator>()));
381        #endregion
382        #endregion
383        #region Wire IntegerVector ShakingOperators
384        var shakingOperators = Operators.OfType<IIntegerVectorMultiNeighborhoodShakingOperator>()
385          .Union(ApplicationManager.Manager.GetInstances<IIntegerVectorMultiNeighborhoodShakingOperator>(), new TypeEqualityComparer<IIntegerVectorMultiNeighborhoodShakingOperator>())
386          .ToList();
387        foreach (var so in shakingOperators) {
388          so.IntegerVectorParameter.ActualName = paramName;
389          so.IntegerVectorParameter.Hidden = true;
390        }
391        Operators.AddRange(shakingOperators.Except(Operators.OfType<IIntegerVectorMultiNeighborhoodShakingOperator>()));
392        #endregion
393      } else {
394        Operators.RemoveAll(x => x is IIntegerVectorCrossover
395          || x is IIntegerVectorManipulator
396          || x is IIntegerVectorStdDevStrategyParameterOperator
397          || x is IIntegerVectorMultiNeighborhoodShakingOperator);
398      }
399      #endregion
400      #region Configure Operators for RealVectorEncoding
401      var realCreator = newCreator as IRealVectorCreator;
402      if (realCreator != null) {
403        var paramName = realCreator.RealVectorParameter.ActualName;
404        // do not replace a real vector creator that was manually set
405        if (!(SolutionCreator is IRealVectorCreator)
406            || ((IRealVectorCreator)SolutionCreator).RealVectorParameter.ActualName != realCreator.RealVectorParameter.ActualName) {
407          Operators.Remove(SolutionCreator);
408          SolutionCreator = newCreator;
409          Operators.Add(SolutionCreator);
410        }
411
412        #region Wire RealVector Crossovers
413        var crossovers = Operators.OfType<IRealVectorCrossover>()
414          .Union(ApplicationManager.Manager.GetInstances<IRealVectorCrossover>(), new TypeEqualityComparer<IRealVectorCrossover>())
415          .ToList();
416        foreach (var xo in crossovers) {
417          xo.ChildParameter.ActualName = paramName;
418          xo.ChildParameter.Hidden = true;
419          xo.ParentsParameter.ActualName = paramName;
420          xo.ParentsParameter.Hidden = true;
421          xo.BoundsParameter.ActualName = realCreator.BoundsParameter.ActualName;
422          xo.BoundsParameter.Hidden = true;
423        }
424        Operators.AddRange(crossovers.Except(Operators.OfType<IRealVectorCrossover>()));
425        #endregion
426        #region Wire RealVector Manipulators
427        var manipulators = Operators.OfType<IRealVectorManipulator>()
428          .Union(ApplicationManager.Manager.GetInstances<IRealVectorManipulator>(), new TypeEqualityComparer<IRealVectorManipulator>())
429          .ToList();
430        foreach (var m in manipulators) {
431          m.RealVectorParameter.ActualName = paramName;
432          m.RealVectorParameter.Hidden = true;
433          m.BoundsParameter.ActualName = realCreator.BoundsParameter.ActualName;
434          m.BoundsParameter.Hidden = true;
435          var sm = m as ISelfAdaptiveManipulator;
436          if (sm != null) {
437            var p = sm.StrategyParameterParameter as ILookupParameter;
438            if (p != null) {
439              p.ActualName = paramName + "Strategy";
440              p.Hidden = true;
441            }
442          }
443        }
444        Operators.AddRange(manipulators.Except(Operators.OfType<IRealVectorManipulator>()));
445        #region Wire RealVector Strategy Parameters for SelfAdaptiveManipulators
446        var strategyOperators = Operators.OfType<IRealVectorStdDevStrategyParameterOperator>()
447          .Union(ApplicationManager.Manager.GetInstances<IRealVectorStdDevStrategyParameterOperator>(), new TypeEqualityComparer<IRealVectorStdDevStrategyParameterOperator>())
448          .ToList();
449        var problemSize = ((RealEncoding)encoding).Length;
450        var bounds = (DoubleMatrix)((RealEncoding)encoding).Bounds.Clone();
451        for (var i = 0; i < bounds.Rows; i++) {
452          bounds[i, 1] = 0.1 * (bounds[i, 1] - bounds[i, 0]);
453          bounds[i, 0] = 0;
454        }
455        foreach (var s in strategyOperators) {
456          var c = s as IRealVectorStdDevStrategyParameterCreator;
457          if (c != null) {
458            c.BoundsParameter.Value = (DoubleMatrix)bounds.Clone();
459            c.LengthParameter.ActualName = realCreator.LengthParameter.ActualName;
460            c.StrategyParameterParameter.ActualName = paramName + "Strategy";
461          }
462          var m = s as IRealVectorStdDevStrategyParameterManipulator;
463          if (m != null) {
464            m.BoundsParameter.Value = (DoubleMatrix)bounds.Clone();
465            m.StrategyParameterParameter.ActualName = paramName + "Strategy";
466          }
467          var mm = s as Encodings.RealVectorEncoding.StdDevStrategyVectorManipulator;
468          if (mm != null) {
469            mm.GeneralLearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * problemSize));
470            mm.LearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * Math.Sqrt(problemSize)));
471          }
472          var x = s as IRealVectorStdDevStrategyParameterCrossover;
473          if (x != null) {
474            x.ParentsParameter.ActualName = paramName + "Strategy";
475            x.StrategyParameterParameter.ActualName = paramName + "Strategy";
476          }
477        }
478        Operators.AddRange(strategyOperators.Except(Operators.OfType<IRealVectorStdDevStrategyParameterOperator>()));
479        #endregion
480        #endregion
481        #region Wire RealVector ParticleCreators
482        var particleCreators = Operators.OfType<IRealVectorParticleCreator>()
483          .Union(ApplicationManager.Manager.GetInstances<IRealVectorParticleCreator>(), new TypeEqualityComparer<IRealVectorParticleCreator>())
484          .ToList();
485        foreach (var pc in particleCreators) {
486          pc.RealVectorParameter.ActualName = paramName;
487          pc.RealVectorParameter.Hidden = true;
488          pc.BoundsParameter.ActualName = realCreator.BoundsParameter.ActualName;
489          pc.BoundsParameter.Hidden = true;
490          pc.ProblemSizeParameter.ActualName = realCreator.LengthParameter.ActualName;
491          pc.ProblemSizeParameter.Hidden = true;
492        }
493        Operators.AddRange(particleCreators.Except(Operators.OfType<IRealVectorParticleCreator>()));
494        #endregion
495        #region Wire RealVector ParticleUpdaters
496        var particleUpdaters = Operators.OfType<IRealVectorParticleUpdater>()
497          .Union(ApplicationManager.Manager.GetInstances<IRealVectorParticleUpdater>(), new TypeEqualityComparer<IRealVectorParticleUpdater>())
498          .ToList();
499        foreach (var pu in particleUpdaters) {
500          pu.RealVectorParameter.ActualName = paramName;
501          pu.RealVectorParameter.Hidden = true;
502          pu.BoundsParameter.ActualName = realCreator.BoundsParameter.ActualName;
503          pu.BoundsParameter.Hidden = true;
504        }
505        Operators.AddRange(particleUpdaters.Except(Operators.OfType<IRealVectorParticleUpdater>()));
506        #endregion
507        #region Wire RealVector SwarmUpdaters
508        var swarmUpdaters = Operators.OfType<IRealVectorSwarmUpdater>()
509          .Union(ApplicationManager.Manager.GetInstances<IRealVectorSwarmUpdater>(), new TypeEqualityComparer<IRealVectorSwarmUpdater>())
510          .ToList();
511        foreach (var su in swarmUpdaters) {
512          su.RealVectorParameter.ActualName = paramName;
513          su.RealVectorParameter.Hidden = true;
514          su.MaximizationParameter.ActualName = MaximizationParameter.Name;
515          su.MaximizationParameter.Hidden = true;
516        }
517        Operators.AddRange(swarmUpdaters.Except(Operators.OfType<IRealVectorSwarmUpdater>()));
518        #endregion
519        #region Wire RealVector ShakingOperators
520        var shakingOperators = Operators.OfType<IRealVectorMultiNeighborhoodShakingOperator>()
521          .Union(ApplicationManager.Manager.GetInstances<IRealVectorMultiNeighborhoodShakingOperator>(), new TypeEqualityComparer<IRealVectorMultiNeighborhoodShakingOperator>())
522          .ToList();
523        foreach (var so in shakingOperators) {
524          so.RealVectorParameter.ActualName = paramName;
525          so.RealVectorParameter.Hidden = true;
526        }
527        Operators.AddRange(shakingOperators.Except(Operators.OfType<IRealVectorMultiNeighborhoodShakingOperator>()));
528        #endregion
529      } else {
530        Operators.RemoveAll(x => x is IRealVectorCrossover
531          || x is IRealVectorManipulator
532          || x is IRealVectorStdDevStrategyParameterOperator
533          || x is IRealVectorParticleCreator
534          || x is IRealVectorParticleUpdater
535          || x is IRealVectorSwarmUpdater
536          || x is IRealVectorMultiNeighborhoodShakingOperator);
537      }
538      #endregion
539      #region Configure Operators for PermutationEncoding
540      var permCreator = newCreator as IPermutationCreator;
541      if (permCreator != null) {
542        var paramName = permCreator.PermutationParameter.ActualName;
543        // do not replace a permutation creator that was manually set
544        if (!(SolutionCreator is IPermutationCreator)
545            || ((IPermutationCreator)SolutionCreator).PermutationParameter.ActualName != permCreator.PermutationParameter.ActualName) {
546          Operators.Remove(SolutionCreator);
547          SolutionCreator = newCreator;
548          Operators.Add(SolutionCreator);
549        }
550
551        #region Wire Permutation Crossovers
552        var crossovers = Operators.OfType<IPermutationCrossover>()
553          .Union(ApplicationManager.Manager.GetInstances<IPermutationCrossover>(), new TypeEqualityComparer<IPermutationCrossover>())
554          .ToList();
555        foreach (var xo in crossovers) {
556          xo.ChildParameter.ActualName = permCreator.PermutationParameter.ActualName;
557          xo.ChildParameter.Hidden = true;
558          xo.ParentsParameter.ActualName = permCreator.PermutationParameter.ActualName;
559          xo.ParentsParameter.Hidden = true;
560        }
561        Operators.AddRange(crossovers.Except(Operators.OfType<IPermutationCrossover>()));
562        #endregion
563        #region Wire Permutation Manipulators
564        var manipulators = Operators.OfType<IPermutationManipulator>()
565          .Union(ApplicationManager.Manager.GetInstances<IPermutationManipulator>(), new TypeEqualityComparer<IPermutationManipulator>())
566          .ToList();
567        foreach (var m in manipulators) {
568          m.PermutationParameter.ActualName = permCreator.PermutationParameter.ActualName;
569          m.PermutationParameter.Hidden = true;
570        }
571        Operators.AddRange(manipulators.Except(Operators.OfType<IPermutationManipulator>()));
572        #endregion
573        #region Wire Permutation ShakingOperators
574        var shakingOperators = Operators.OfType<IPermutationMultiNeighborhoodShakingOperator>()
575          .Union(ApplicationManager.Manager.GetInstances<IPermutationMultiNeighborhoodShakingOperator>(), new TypeEqualityComparer<IPermutationMultiNeighborhoodShakingOperator>())
576          .ToList();
577        foreach (var op in shakingOperators) {
578          op.PermutationParameter.ActualName = paramName;
579          op.PermutationParameter.Hidden = true;
580        }
581        Operators.AddRange(shakingOperators.Except(Operators.OfType<IPermutationMultiNeighborhoodShakingOperator>()));
582        #endregion
583      } else {
584        Operators.RemoveAll(x => x is IPermutationCrossover
585          || x is IPermutationManipulator
586          || x is IPermutationMultiNeighborhoodShakingOperator);
587      }
588      #endregion
589    }
590
591    protected virtual void ConfigureMultiVectorEncodingOperators(MultiEncodingCreator newCreator, MultiEncoding encoding) {
592      var newBinParams = new HashSet<string>(newCreator.Operators.OfType<IBinaryVectorCreator>().Select(x => x.BinaryVectorParameter.ActualName));
593      var newIntParams = new HashSet<string>(newCreator.Operators.OfType<IIntegerVectorCreator>().Select(x => x.IntegerVectorParameter.ActualName));
594      var newRealParams = new HashSet<string>(newCreator.Operators.OfType<IRealVectorCreator>().Select(x => x.RealVectorParameter.ActualName));
595      var newPermParams = new HashSet<string>(newCreator.Operators.OfType<IPermutationCreator>().Select(x => x.PermutationParameter.ActualName));
596
597      var oldCreator = SolutionCreator as MultiEncodingCreator;
598      if (oldCreator == null) SolutionCreator = newCreator;
599      else {
600        #region Configure BinaryVector Creator
601        var oldBinParams = new HashSet<string>(oldCreator.Operators.OfType<IBinaryVectorCreator>().Select(x => x.BinaryVectorParameter.ActualName));
602        foreach (var toAdd in newBinParams.Except(oldBinParams)) {
603          oldCreator.Operators.Add(newCreator.Operators.OfType<IBinaryVectorCreator>().Single(x => x.BinaryVectorParameter.ActualName == toAdd));
604        }
605        foreach (var toRemove in oldBinParams.Except(newBinParams)) {
606          var op = oldCreator.Operators.OfType<IBinaryVectorCreator>().SingleOrDefault(x => x.BinaryVectorParameter.ActualName == toRemove);
607          if (op != null) oldCreator.Operators.Remove(op);
608        }
609        #endregion
610
611        #region Configure IntegerVector Creator
612        var oldIntParams = new HashSet<string>(oldCreator.Operators.OfType<IIntegerVectorCreator>().Select(x => x.IntegerVectorParameter.ActualName));
613        foreach (var toAdd in newIntParams.Except(oldIntParams)) {
614          oldCreator.Operators.Add(newCreator.Operators.OfType<IIntegerVectorCreator>().Single(x => x.IntegerVectorParameter.ActualName == toAdd));
615        }
616        foreach (var toRemove in oldIntParams.Except(newIntParams)) {
617          var op = oldCreator.Operators.OfType<IIntegerVectorCreator>().SingleOrDefault(x => x.IntegerVectorParameter.ActualName == toRemove);
618          if (op != null) oldCreator.Operators.Remove(op);
619        }
620        #endregion
621
622        #region Configure RealVector Creator
623        var oldRealParams = new HashSet<string>(oldCreator.Operators.OfType<IRealVectorCreator>().Select(x => x.RealVectorParameter.ActualName));
624        foreach (var toAdd in newRealParams.Except(oldRealParams)) {
625          oldCreator.Operators.Add(newCreator.Operators.OfType<IRealVectorCreator>().Single(x => x.RealVectorParameter.ActualName == toAdd));
626        }
627        foreach (var toRemove in oldRealParams.Except(newRealParams)) {
628          var op = oldCreator.Operators.OfType<IRealVectorCreator>().SingleOrDefault(x => x.RealVectorParameter.ActualName == toRemove);
629          if (op != null) oldCreator.Operators.Remove(op);
630        }
631        #endregion
632
633        #region Configure Permutation Creator
634        var oldPermParams = new HashSet<string>(oldCreator.Operators.OfType<IPermutationCreator>().Select(x => x.PermutationParameter.ActualName));
635        foreach (var toAdd in newPermParams.Except(oldPermParams)) {
636          oldCreator.Operators.Add(newCreator.Operators.OfType<IPermutationCreator>().Single(x => x.PermutationParameter.ActualName == toAdd));
637        }
638        foreach (var toRemove in oldPermParams.Except(newPermParams)) {
639          var op = oldCreator.Operators.OfType<IPermutationCreator>().SingleOrDefault(x => x.PermutationParameter.ActualName == toRemove);
640          if (op != null) oldCreator.Operators.Remove(op);
641        }
642        // we also have to sync the permutation type (in case this changes, as it is a value parameter)
643        foreach (var intersect in newPermParams.Intersect(oldPermParams)) {
644          var oldPermCreator = oldCreator.Operators.OfType<IPermutationCreator>().Single(x => x.PermutationParameter.ActualName == intersect);
645          var newPermCreator = newCreator.Operators.OfType<IPermutationCreator>().Single(x => x.PermutationParameter.ActualName == intersect);
646          oldPermCreator.PermutationTypeParameter.Value = newPermCreator.PermutationTypeParameter.Value;
647        }
648        #endregion
649
650      }
651
652      // crossover and manipulator for multi-vector encoding
653      // the condition checks if a multi-vector encoding is to be updated (there already exists ParameterVectorCrossover and ParameterVectorManipulator)
654      if (Operators.OfType<MultiEncodingCrossover>().Any() && Operators.OfType<MultiEncodingManipulator>().Any()) {
655        #region Update existing multi-vector encoding
656        #region Update ParameterVector Crossover ...
657        foreach (var oldXo in Operators.OfType<MultiEncodingCrossover>()) {
658          #region ... for binary parameters
659          var oldBinParams = new HashSet<string>(oldXo.Operators.OfType<IBinaryVectorCrossover>().Select(x => x.ChildParameter.ActualName));
660          foreach (var toAdd in newBinParams.Except(oldBinParams))
661            oldXo.Operators.Add(GetDefaultBinaryCrossover(toAdd, encoding));
662          foreach (var toRemove in oldBinParams.Except(newBinParams)) {
663            var op = oldXo.Operators.OfType<IBinaryVectorCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
664            if (op != null) oldXo.Operators.Remove(op);
665          }
666          #endregion
667          #region ... for integer parameters
668          var oldIntParams = new HashSet<string>(oldXo.Operators.OfType<IIntegerVectorCrossover>().Select(x => x.ChildParameter.ActualName));
669          foreach (var toAdd in newIntParams.Except(oldIntParams))
670            oldXo.Operators.Add(GetDefaultIntegerCrossover(toAdd, encoding));
671          foreach (var toRemove in oldIntParams.Except(newIntParams)) {
672            var op = oldXo.Operators.OfType<IIntegerVectorCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
673            if (op != null) oldXo.Operators.Remove(op);
674          }
675          #endregion
676          #region ... for real parameters
677          var oldRealParams = new HashSet<string>(oldXo.Operators.OfType<IRealVectorCrossover>().Select(x => x.ChildParameter.ActualName));
678          foreach (var toAdd in newRealParams.Except(oldRealParams))
679            oldXo.Operators.Add(GetDefaultRealCrossover(toAdd, encoding));
680          foreach (var toRemove in oldRealParams.Except(newRealParams)) {
681            var op = oldXo.Operators.OfType<IRealVectorCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
682            if (op != null) oldXo.Operators.Remove(op);
683          }
684          #endregion
685          #region ... for permutation parameters
686          var oldPermParams = new HashSet<string>(oldXo.Operators.OfType<IPermutationCrossover>().Select(x => x.ChildParameter.ActualName));
687          foreach (var toAdd in newPermParams.Except(oldPermParams))
688            oldXo.Operators.Add(GetDefaultPermutationCrossover(toAdd, encoding));
689          foreach (var toRemove in oldPermParams.Except(newPermParams)) {
690            var op = oldXo.Operators.OfType<IPermutationCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
691            if (op != null) oldXo.Operators.Remove(op);
692          }
693          #endregion
694        }
695        #endregion
696        #region Update ParameterVector Manipulator ...
697        foreach (var oldM in Operators.OfType<MultiEncodingManipulator>()) {
698          #region ... for binary parameters
699          var oldBinParams = new HashSet<string>(oldM.Operators.OfType<IBinaryVectorManipulator>().Select(x => x.BinaryVectorParameter.ActualName));
700          foreach (var toAdd in newBinParams.Except(oldBinParams))
701            oldM.Operators.Add(GetDefaultBinaryManipulator(toAdd, encoding));
702          foreach (var toRemove in oldBinParams.Except(newBinParams)) {
703            var op = oldM.Operators.OfType<IBinaryVectorManipulator>().SingleOrDefault(x => x.BinaryVectorParameter.ActualName == toRemove);
704            if (op != null) oldM.Operators.Remove(op);
705          }
706          #endregion
707          #region ... for integer parameters
708          var oldIntParams = new HashSet<string>(oldM.Operators.OfType<IIntegerVectorManipulator>().Select(x => x.IntegerVectorParameter.ActualName));
709          foreach (var toAdd in newIntParams.Except(oldIntParams))
710            oldM.Operators.Add(GetDefaultIntegerManipulator(toAdd, encoding));
711          foreach (var toRemove in oldIntParams.Except(newIntParams)) {
712            var op = oldM.Operators.OfType<IIntegerVectorManipulator>().SingleOrDefault(x => x.IntegerVectorParameter.ActualName == toRemove);
713            if (op != null) oldM.Operators.Remove(op);
714          }
715          #endregion
716          #region ... for real parameters
717          var oldRealParams = new HashSet<string>(oldM.Operators.OfType<IRealVectorManipulator>().Select(x => x.RealVectorParameter.ActualName));
718          foreach (var toAdd in newRealParams.Except(oldRealParams))
719            oldM.Operators.Add(GetDefaultRealManipulator(toAdd, encoding));
720          foreach (var toRemove in oldRealParams.Except(newRealParams)) {
721            var op = oldM.Operators.OfType<IRealVectorManipulator>().SingleOrDefault(x => x.RealVectorParameter.ActualName == toRemove);
722            if (op != null) oldM.Operators.Remove(op);
723          }
724          #endregion
725          #region ... for permutation parameters
726          var oldPermParams = new HashSet<string>(oldM.Operators.OfType<IPermutationManipulator>().Select(x => x.PermutationParameter.ActualName));
727          foreach (var toAdd in newPermParams.Except(oldPermParams))
728            oldM.Operators.Add(GetDefaultPermutationManipulator(toAdd, encoding));
729          foreach (var toRemove in oldPermParams.Except(newPermParams)) {
730            var op = oldM.Operators.OfType<IPermutationManipulator>().SingleOrDefault(x => x.PermutationParameter.ActualName == toRemove);
731            if (op != null) oldM.Operators.Remove(op);
732          }
733          #endregion
734        }
735        #endregion
736        #endregion
737      } else {
738        #region Handle transition from single-vector to multi-vector encoding
739        Operators.RemoveAll(x => x is ICrossover);
740        Operators.RemoveAll(x => x is IManipulator);
741        Operators.RemoveAll(x => x is IStrategyParameterCreator || x is IStrategyParameterManipulator || x is IStrategyParameterCrossover);
742        Operators.RemoveAll(x => x is IParticleCreator);
743        Operators.RemoveAll(x => x is IParticleUpdater);
744        Operators.RemoveAll(x => x is ISwarmUpdater);
745        Operators.RemoveAll(x => x is IMultiNeighborhoodShakingOperator);
746
747        var crossover = new MultiEncodingCrossover();
748        var manipulator = new MultiEncodingManipulator();
749        foreach (var enc in encoding.Encodings) {
750          if (enc is BinaryEncoding) {
751            crossover.Operators.Add(GetDefaultBinaryCrossover(enc.Name, encoding));
752            manipulator.Operators.Add(GetDefaultBinaryManipulator(enc.Name, encoding));
753            continue;
754          }
755          var intConfig = enc as IntegerEncoding;
756          if (intConfig != null) {
757            crossover.Operators.Add(GetDefaultIntegerCrossover(enc.Name, encoding));
758            manipulator.Operators.Add(GetDefaultIntegerManipulator(enc.Name, encoding));
759            continue;
760          }
761          var realConfig = enc as RealEncoding;
762          if (realConfig != null) {
763            crossover.Operators.Add(GetDefaultRealCrossover(enc.Name, encoding));
764            manipulator.Operators.Add(GetDefaultRealManipulator(enc.Name, encoding));
765            continue;
766          }
767          var permConfig = enc as PermutationEncoding;
768          if (permConfig != null) {
769            crossover.Operators.Add(GetDefaultPermutationCrossover(enc.Name, encoding));
770            manipulator.Operators.Add(GetDefaultPermutationManipulator(enc.Name, encoding));
771            continue;
772          }
773          throw new InvalidOperationException("Unknown type for parameter " + enc.Name);
774        }
775        Operators.Add(crossover);
776        Operators.Add(manipulator);
777        #endregion
778      }
779    }
780
781    #region GetDefaultOperators for Crossovers and Manipulators
782    // ReSharper disable RedundantNameQualifier
783    protected virtual IBinaryVectorCrossover GetDefaultBinaryCrossover(string paramName, MultiEncoding config) {
784      var binConfig = (BinaryEncoding)config.Encodings[paramName];
785      IBinaryVectorCrossover binXo;
786      if (binConfig.Length.Value > 3) binXo = new Encodings.BinaryVectorEncoding.SinglePointCrossover();
787      else binXo = new Encodings.BinaryVectorEncoding.UniformCrossover();
788      binXo.ChildParameter.ActualName = paramName;
789      binXo.ParentsParameter.ActualName = paramName;
790      return binXo;
791    }
792
793    protected virtual IBinaryVectorManipulator GetDefaultBinaryManipulator(string paramName, MultiEncoding config) {
794      var binM = new Encodings.BinaryVectorEncoding.SomePositionsBitflipManipulator();
795      binM.BinaryVectorParameter.ActualName = paramName;
796      binM.MutationProbabilityParameter.Value = new DoubleValue(0.1);
797      return binM;
798    }
799
800    protected virtual IIntegerVectorCrossover GetDefaultIntegerCrossover(string paramName, MultiEncoding config) {
801      var intXo = new Encodings.IntegerVectorEncoding.RoundedBlendAlphaCrossover();
802      intXo.ChildParameter.ActualName = paramName;
803      intXo.ParentsParameter.ActualName = paramName;
804      intXo.BoundsParameter.ActualName = paramName + "Bounds";
805      return intXo;
806    }
807
808    protected virtual IIntegerVectorManipulator GetDefaultIntegerManipulator(string paramName, MultiEncoding configuration) {
809      var intM = new Encodings.IntegerVectorEncoding.UniformSomePositionsManipulator();
810      intM.IntegerVectorParameter.ActualName = paramName;
811      intM.BoundsParameter.ActualName = paramName + "Bounds";
812      intM.ProbabilityParameter.Value = new DoubleValue(0.1);
813      return intM;
814    }
815
816    protected virtual IRealVectorCrossover GetDefaultRealCrossover(string paramName, MultiEncoding configuration) {
817      var realXo = new Encodings.RealVectorEncoding.BlendAlphaCrossover();
818      realXo.ChildParameter.ActualName = paramName;
819      realXo.ParentsParameter.ActualName = paramName;
820      realXo.BoundsParameter.ActualName = paramName + "Bounds";
821      return realXo;
822    }
823
824    protected virtual IRealVectorManipulator GetDefaultRealManipulator(string paramName, MultiEncoding configuration) {
825      var realM = new Encodings.RealVectorEncoding.BreederGeneticAlgorithmManipulator();
826      realM.RealVectorParameter.ActualName = paramName;
827      realM.BoundsParameter.ActualName = paramName + "Bounds";
828      return realM;
829    }
830
831    protected virtual IPermutationCrossover GetDefaultPermutationCrossover(string paramName, MultiEncoding configuration) {
832      var permXo = new Encodings.PermutationEncoding.PartiallyMatchedCrossover();
833      permXo.ChildParameter.ActualName = paramName;
834      permXo.ParentsParameter.ActualName = paramName;
835      return permXo;
836    }
837
838    protected virtual IPermutationManipulator GetDefaultPermutationManipulator(string paramName, MultiEncoding configuration) {
839      var permM = new Encodings.PermutationEncoding.Swap2Manipulator();
840      permM.PermutationParameter.ActualName = paramName;
841      return permM;
842    }
843    // ReSharper restore RedundantNameQualifier
844    #endregion
845  }
846}
Note: See TracBrowser for help on using the repository browser.