Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2174: Adapted permutation encoding.

File size: 43.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.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<IEncoding> EncodingParameter {
61      get { return (IValueParameter<IEncoding>)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<IEncoding>("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      IEncoding 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(IEncoding encoding) {
178      #region Configure RealVector Creator
179      var realEnc = encoding as RealEncoding;
180      if (realEnc != null) {
181        DynamicEncodingParameters.AddRange(realEnc.Parameters);
182        return realEnc.DefaultSolutionCreator;
183      }
184      #endregion
185      #region Configure BinaryVector Creator
186      var binEnc = encoding as BinaryEncoding;
187      if (binEnc != null) {
188        DynamicEncodingParameters.AddRange(binEnc.Parameters);
189        return binEnc.DefaultSolutionCreator;
190      }
191      #endregion
192      #region Configure IntegerVector Creator
193      var intEnc = encoding as IntegerEncoding;
194      if (intEnc != null) {
195        DynamicEncodingParameters.AddRange(intEnc.Parameters);
196        return intEnc.DefaultSolutionCreator;
197      }
198      #endregion
199      #region Configure MultiEncoding Creator
200      var multiEncoding = encoding as MultiEncoding;
201      if (multiEncoding != null) {
202        var creator = new MultiEncodingCreator();
203        foreach (var enc in multiEncoding.Encodings) {
204          if (enc is MultiEncoding) throw new InvalidOperationException("MultiEncoding within a MultiEncoding is not supported.");
205          creator.Operators.Add(ConfigureCreator(enc));
206        }
207        return creator;
208      }
209      #endregion
210      #region Configure Permutation Creator
211      var permEnc = encoding as PermutationEncoding;
212      if (permEnc != null) {
213        var l = new ValueParameter<IntValue>(permEnc.Name + "Length", new IntValue(permEnc.Length));
214        DynamicEncodingParameters.Add(l);
215
216        var creator = new RandomPermutationCreator();
217        creator.PermutationParameter.ActualName = permEnc.Name;
218        creator.LengthParameter.ActualName = l.Name;
219        creator.PermutationTypeParameter.Value = new PermutationType(permEnc.Type);
220        return creator;
221      }
222      #endregion
223      throw new ArgumentException(string.Format("Encoding {0} is unknown.", encoding != null ? encoding.GetType().FullName : "(null)"));
224    }
225
226    protected virtual void ConfigureSingleEncodingOperators(ISolutionCreator newCreator, IEncoding encoding) {
227      // remove all multiencoding operators
228      Operators.RemoveAll(x => x is MultiEncodingCrossover
229                            || x is MultiEncodingManipulator
230                            || x is MultiEncodingCreator);
231
232      #region Configure Operators for BinaryVectorEncoding
233      var binCreator = newCreator as IBinaryVectorCreator;
234      if (binCreator != null) {
235        var paramName = binCreator.BinaryVectorParameter.ActualName;
236        // do not replace a binary vector creator that was manually set
237        if (!(SolutionCreator is IBinaryVectorCreator) || ((IBinaryVectorCreator)SolutionCreator).BinaryVectorParameter.ActualName != paramName) {
238          Operators.Remove(SolutionCreator);
239          SolutionCreator = newCreator;
240          Operators.Add(SolutionCreator);
241        }
242
243        #region Wire BinaryVector Crossovers
244        var crossovers = Operators.OfType<IBinaryVectorCrossover>()
245          .Union(ApplicationManager.Manager.GetInstances<IBinaryVectorCrossover>(), new TypeEqualityComparer<IBinaryVectorCrossover>())
246          .ToList();
247        foreach (var xo in crossovers) {
248          xo.ChildParameter.ActualName = binCreator.BinaryVectorParameter.ActualName;
249          xo.ChildParameter.Hidden = true;
250          xo.ParentsParameter.ActualName = binCreator.BinaryVectorParameter.ActualName;
251          xo.ParentsParameter.Hidden = true;
252        }
253        Operators.AddRange(crossovers.Except(Operators.OfType<IBinaryVectorCrossover>()));
254        #endregion
255        #region Wire BinaryVector Manipulators
256        var manipulators = Operators.OfType<IBinaryVectorManipulator>()
257          .Union(ApplicationManager.Manager.GetInstances<IBinaryVectorManipulator>(), new TypeEqualityComparer<IBinaryVectorManipulator>())
258          .ToList();
259        foreach (var m in manipulators) {
260          m.BinaryVectorParameter.ActualName = binCreator.BinaryVectorParameter.ActualName;
261          m.BinaryVectorParameter.Hidden = true;
262        }
263        Operators.AddRange(manipulators.Except(Operators.OfType<IBinaryVectorManipulator>()));
264        #endregion
265        #region Wire BinaryVector ShakingOperators
266        var shakingOperators = Operators.OfType<IBinaryVectorMultiNeighborhoodShakingOperator>()
267          .Union(ApplicationManager.Manager.GetInstances<IBinaryVectorMultiNeighborhoodShakingOperator>(), new TypeEqualityComparer<IBinaryVectorMultiNeighborhoodShakingOperator>())
268          .ToList();
269        foreach (var so in shakingOperators) {
270          so.BinaryVectorParameter.ActualName = paramName;
271          so.BinaryVectorParameter.Hidden = true;
272        }
273        Operators.AddRange(shakingOperators.Except(Operators.OfType<IBinaryVectorMultiNeighborhoodShakingOperator>()));
274        #endregion
275      } else {
276        Operators.RemoveAll(x => x is IBinaryVectorCrossover
277          || x is IBinaryVectorManipulator
278          || x is IBinaryVectorMultiNeighborhoodShakingOperator);
279      }
280      #endregion
281      #region Configure Operators for IntegerVectorEncoding
282      var intCreator = newCreator as IIntegerVectorCreator;
283      if (intCreator != null) {
284        var paramName = intCreator.IntegerVectorParameter.ActualName;
285        // do not replace an integer vector creator that was manually set
286        if (!(SolutionCreator is IIntegerVectorCreator)
287          || ((IIntegerVectorCreator)SolutionCreator).IntegerVectorParameter.ActualName != intCreator.IntegerVectorParameter.ActualName) {
288          Operators.Remove(SolutionCreator);
289          SolutionCreator = newCreator;
290          Operators.Add(SolutionCreator);
291        }
292
293        #region Wire IntegerVector Crossovers
294        var crossovers = Operators.OfType<IIntegerVectorCrossover>()
295          .Union(ApplicationManager.Manager.GetInstances<IIntegerVectorCrossover>(), new TypeEqualityComparer<IIntegerVectorCrossover>())
296          .ToList();
297        foreach (var xo in crossovers) {
298          xo.ChildParameter.ActualName = intCreator.IntegerVectorParameter.ActualName;
299          xo.ChildParameter.Hidden = true;
300          xo.ParentsParameter.ActualName = intCreator.IntegerVectorParameter.ActualName;
301          xo.ParentsParameter.Hidden = true;
302          var bx = xo as IBoundedIntegerVectorOperator;
303          if (bx != null) {
304            bx.BoundsParameter.ActualName = intCreator.BoundsParameter.ActualName;
305            bx.BoundsParameter.Hidden = true;
306          }
307        }
308        Operators.AddRange(crossovers.Except(Operators.OfType<IIntegerVectorCrossover>()));
309        #endregion
310        #region Wire IntegerVector Manipulators
311        var manipulators = Operators.OfType<IIntegerVectorManipulator>()
312          .Union(ApplicationManager.Manager.GetInstances<IIntegerVectorManipulator>(), new TypeEqualityComparer<IIntegerVectorManipulator>())
313          .ToList();
314        foreach (var m in manipulators) {
315          m.IntegerVectorParameter.ActualName = intCreator.IntegerVectorParameter.ActualName;
316          m.IntegerVectorParameter.Hidden = true;
317          var sm = m as ISelfAdaptiveManipulator;
318          if (sm != null) {
319            var p = sm.StrategyParameterParameter as ILookupParameter;
320            if (p != null) {
321              p.ActualName = paramName + "Strategy";
322              p.Hidden = true;
323            }
324          }
325          var bm = m as IBoundedIntegerVectorOperator;
326          if (bm != null) {
327            bm.BoundsParameter.ActualName = intCreator.BoundsParameter.ActualName;
328            bm.BoundsParameter.Hidden = true;
329          }
330        }
331        Operators.AddRange(manipulators.Except(Operators.OfType<IIntegerVectorManipulator>()));
332        #region Wire IntegerVector StrategyParameters for SelfAdaptiveManipulators
333        var strategyOperators = Operators.OfType<IIntegerVectorStdDevStrategyParameterOperator>()
334          .Union(ApplicationManager.Manager.GetInstances<IIntegerVectorStdDevStrategyParameterOperator>(), new TypeEqualityComparer<IIntegerVectorStdDevStrategyParameterOperator>())
335          .ToList();
336        var problemSize = ((IntegerEncoding)encoding).Length;
337        var b = ((IntegerEncoding)encoding).Bounds;
338        var bounds = new DoubleMatrix(b.Rows, b.Columns);
339        for (var i = 0; i < bounds.Rows; i++) {
340          bounds[i, 1] = (int)Math.Ceiling(0.33 * (b[i, 1] - b[i, 0]));
341          bounds[i, 0] = 0;
342          if (bounds.Columns > 2) bounds[i, 2] = b[i, 2];
343        }
344        foreach (var s in strategyOperators) {
345          var c = s as IIntegerVectorStdDevStrategyParameterCreator;
346          if (c != null) {
347            c.BoundsParameter.Value = (DoubleMatrix)bounds.Clone();
348            c.LengthParameter.ActualName = intCreator.LengthParameter.ActualName;
349            c.StrategyParameterParameter.ActualName = paramName + "Strategy";
350          }
351          var m = s as IIntegerVectorStdDevStrategyParameterManipulator;
352          if (m != null) {
353            m.BoundsParameter.Value = (DoubleMatrix)bounds.Clone();
354            m.StrategyParameterParameter.ActualName = paramName + "Strategy";
355          }
356          var mm = s as Encodings.IntegerVectorEncoding.StdDevStrategyVectorManipulator;
357          if (mm != null) {
358            mm.GeneralLearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * problemSize));
359            mm.LearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * Math.Sqrt(problemSize)));
360          }
361          var x = s as IIntegerVectorStdDevStrategyParameterCrossover;
362          if (x != null) {
363            x.ParentsParameter.ActualName = paramName + "Strategy";
364            x.StrategyParameterParameter.ActualName = paramName + "Strategy";
365          }
366        }
367        Operators.AddRange(strategyOperators.Except(Operators.OfType<IIntegerVectorStdDevStrategyParameterOperator>()));
368        #endregion
369        #endregion
370        #region Wire IntegerVector ShakingOperators
371        var shakingOperators = Operators.OfType<IIntegerVectorMultiNeighborhoodShakingOperator>()
372          .Union(ApplicationManager.Manager.GetInstances<IIntegerVectorMultiNeighborhoodShakingOperator>(), new TypeEqualityComparer<IIntegerVectorMultiNeighborhoodShakingOperator>())
373          .ToList();
374        foreach (var so in shakingOperators) {
375          so.IntegerVectorParameter.ActualName = paramName;
376          so.IntegerVectorParameter.Hidden = true;
377        }
378        Operators.AddRange(shakingOperators.Except(Operators.OfType<IIntegerVectorMultiNeighborhoodShakingOperator>()));
379        #endregion
380      } else {
381        Operators.RemoveAll(x => x is IIntegerVectorCrossover
382          || x is IIntegerVectorManipulator
383          || x is IIntegerVectorStdDevStrategyParameterOperator
384          || x is IIntegerVectorMultiNeighborhoodShakingOperator);
385      }
386      #endregion
387      #region Configure Operators for RealVectorEncoding
388      var realCreator = newCreator as IRealVectorCreator;
389      if (realCreator != null) {
390        var paramName = realCreator.RealVectorParameter.ActualName;
391        // do not replace a real vector creator that was manually set
392        if (!(SolutionCreator is IRealVectorCreator)
393            || ((IRealVectorCreator)SolutionCreator).RealVectorParameter.ActualName != realCreator.RealVectorParameter.ActualName) {
394          Operators.Remove(SolutionCreator);
395          SolutionCreator = newCreator;
396          Operators.Add(SolutionCreator);
397        }
398
399        #region Wire RealVector Crossovers
400        var crossovers = Operators.OfType<IRealVectorCrossover>()
401          .Union(ApplicationManager.Manager.GetInstances<IRealVectorCrossover>(), new TypeEqualityComparer<IRealVectorCrossover>())
402          .ToList();
403        foreach (var xo in crossovers) {
404          xo.ChildParameter.ActualName = paramName;
405          xo.ChildParameter.Hidden = true;
406          xo.ParentsParameter.ActualName = paramName;
407          xo.ParentsParameter.Hidden = true;
408          xo.BoundsParameter.ActualName = realCreator.BoundsParameter.ActualName;
409          xo.BoundsParameter.Hidden = true;
410        }
411        Operators.AddRange(crossovers.Except(Operators.OfType<IRealVectorCrossover>()));
412        #endregion
413        #region Wire RealVector Manipulators
414        var manipulators = Operators.OfType<IRealVectorManipulator>()
415          .Union(ApplicationManager.Manager.GetInstances<IRealVectorManipulator>(), new TypeEqualityComparer<IRealVectorManipulator>())
416          .ToList();
417        foreach (var m in manipulators) {
418          m.RealVectorParameter.ActualName = paramName;
419          m.RealVectorParameter.Hidden = true;
420          m.BoundsParameter.ActualName = realCreator.BoundsParameter.ActualName;
421          m.BoundsParameter.Hidden = true;
422          var sm = m as ISelfAdaptiveManipulator;
423          if (sm != null) {
424            var p = sm.StrategyParameterParameter as ILookupParameter;
425            if (p != null) {
426              p.ActualName = paramName + "Strategy";
427              p.Hidden = true;
428            }
429          }
430        }
431        Operators.AddRange(manipulators.Except(Operators.OfType<IRealVectorManipulator>()));
432        #region Wire RealVector Strategy Parameters for SelfAdaptiveManipulators
433        var strategyOperators = Operators.OfType<IRealVectorStdDevStrategyParameterOperator>()
434          .Union(ApplicationManager.Manager.GetInstances<IRealVectorStdDevStrategyParameterOperator>(), new TypeEqualityComparer<IRealVectorStdDevStrategyParameterOperator>())
435          .ToList();
436        var problemSize = ((RealEncoding)encoding).Length;
437        var bounds = (DoubleMatrix)((RealEncoding)encoding).Bounds.Clone();
438        for (var i = 0; i < bounds.Rows; i++) {
439          bounds[i, 1] = 0.1 * (bounds[i, 1] - bounds[i, 0]);
440          bounds[i, 0] = 0;
441        }
442        foreach (var s in strategyOperators) {
443          var c = s as IRealVectorStdDevStrategyParameterCreator;
444          if (c != null) {
445            c.BoundsParameter.Value = (DoubleMatrix)bounds.Clone();
446            c.LengthParameter.ActualName = realCreator.LengthParameter.ActualName;
447            c.StrategyParameterParameter.ActualName = paramName + "Strategy";
448          }
449          var m = s as IRealVectorStdDevStrategyParameterManipulator;
450          if (m != null) {
451            m.BoundsParameter.Value = (DoubleMatrix)bounds.Clone();
452            m.StrategyParameterParameter.ActualName = paramName + "Strategy";
453          }
454          var mm = s as Encodings.RealVectorEncoding.StdDevStrategyVectorManipulator;
455          if (mm != null) {
456            mm.GeneralLearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * problemSize));
457            mm.LearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * Math.Sqrt(problemSize)));
458          }
459          var x = s as IRealVectorStdDevStrategyParameterCrossover;
460          if (x != null) {
461            x.ParentsParameter.ActualName = paramName + "Strategy";
462            x.StrategyParameterParameter.ActualName = paramName + "Strategy";
463          }
464        }
465        Operators.AddRange(strategyOperators.Except(Operators.OfType<IRealVectorStdDevStrategyParameterOperator>()));
466        #endregion
467        #endregion
468        #region Wire RealVector ParticleCreators
469        var particleCreators = Operators.OfType<IRealVectorParticleCreator>()
470          .Union(ApplicationManager.Manager.GetInstances<IRealVectorParticleCreator>(), new TypeEqualityComparer<IRealVectorParticleCreator>())
471          .ToList();
472        foreach (var pc in particleCreators) {
473          pc.RealVectorParameter.ActualName = paramName;
474          pc.RealVectorParameter.Hidden = true;
475          pc.BoundsParameter.ActualName = realCreator.BoundsParameter.ActualName;
476          pc.BoundsParameter.Hidden = true;
477          pc.ProblemSizeParameter.ActualName = realCreator.LengthParameter.ActualName;
478          pc.ProblemSizeParameter.Hidden = true;
479        }
480        Operators.AddRange(particleCreators.Except(Operators.OfType<IRealVectorParticleCreator>()));
481        #endregion
482        #region Wire RealVector ParticleUpdaters
483        var particleUpdaters = Operators.OfType<IRealVectorParticleUpdater>()
484          .Union(ApplicationManager.Manager.GetInstances<IRealVectorParticleUpdater>(), new TypeEqualityComparer<IRealVectorParticleUpdater>())
485          .ToList();
486        foreach (var pu in particleUpdaters) {
487          pu.RealVectorParameter.ActualName = paramName;
488          pu.RealVectorParameter.Hidden = true;
489          pu.BoundsParameter.ActualName = realCreator.BoundsParameter.ActualName;
490          pu.BoundsParameter.Hidden = true;
491        }
492        Operators.AddRange(particleUpdaters.Except(Operators.OfType<IRealVectorParticleUpdater>()));
493        #endregion
494        #region Wire RealVector SwarmUpdaters
495        var swarmUpdaters = Operators.OfType<IRealVectorSwarmUpdater>()
496          .Union(ApplicationManager.Manager.GetInstances<IRealVectorSwarmUpdater>(), new TypeEqualityComparer<IRealVectorSwarmUpdater>())
497          .ToList();
498        foreach (var su in swarmUpdaters) {
499          su.RealVectorParameter.ActualName = paramName;
500          su.RealVectorParameter.Hidden = true;
501          su.MaximizationParameter.ActualName = MaximizationParameter.Name;
502          su.MaximizationParameter.Hidden = true;
503        }
504        Operators.AddRange(swarmUpdaters.Except(Operators.OfType<IRealVectorSwarmUpdater>()));
505        #endregion
506        #region Wire RealVector ShakingOperators
507        var shakingOperators = Operators.OfType<IRealVectorMultiNeighborhoodShakingOperator>()
508          .Union(ApplicationManager.Manager.GetInstances<IRealVectorMultiNeighborhoodShakingOperator>(), new TypeEqualityComparer<IRealVectorMultiNeighborhoodShakingOperator>())
509          .ToList();
510        foreach (var so in shakingOperators) {
511          so.RealVectorParameter.ActualName = paramName;
512          so.RealVectorParameter.Hidden = true;
513        }
514        Operators.AddRange(shakingOperators.Except(Operators.OfType<IRealVectorMultiNeighborhoodShakingOperator>()));
515        #endregion
516      } else {
517        Operators.RemoveAll(x => x is IRealVectorCrossover
518          || x is IRealVectorManipulator
519          || x is IRealVectorStdDevStrategyParameterOperator
520          || x is IRealVectorParticleCreator
521          || x is IRealVectorParticleUpdater
522          || x is IRealVectorSwarmUpdater
523          || x is IRealVectorMultiNeighborhoodShakingOperator);
524      }
525      #endregion
526      #region Configure Operators for PermutationEncoding
527      var permCreator = newCreator as IPermutationCreator;
528      if (permCreator != null) {
529        var paramName = permCreator.PermutationParameter.ActualName;
530        // do not replace a permutation creator that was manually set
531        if (!(SolutionCreator is IPermutationCreator)
532            || ((IPermutationCreator)SolutionCreator).PermutationParameter.ActualName != permCreator.PermutationParameter.ActualName) {
533          Operators.Remove(SolutionCreator);
534          SolutionCreator = newCreator;
535          Operators.Add(SolutionCreator);
536        }
537
538        #region Wire Permutation Crossovers
539        var crossovers = Operators.OfType<IPermutationCrossover>()
540          .Union(ApplicationManager.Manager.GetInstances<IPermutationCrossover>(), new TypeEqualityComparer<IPermutationCrossover>())
541          .ToList();
542        foreach (var xo in crossovers) {
543          xo.ChildParameter.ActualName = permCreator.PermutationParameter.ActualName;
544          xo.ChildParameter.Hidden = true;
545          xo.ParentsParameter.ActualName = permCreator.PermutationParameter.ActualName;
546          xo.ParentsParameter.Hidden = true;
547        }
548        Operators.AddRange(crossovers.Except(Operators.OfType<IPermutationCrossover>()));
549        #endregion
550        #region Wire Permutation Manipulators
551        var manipulators = Operators.OfType<IPermutationManipulator>()
552          .Union(ApplicationManager.Manager.GetInstances<IPermutationManipulator>(), new TypeEqualityComparer<IPermutationManipulator>())
553          .ToList();
554        foreach (var m in manipulators) {
555          m.PermutationParameter.ActualName = permCreator.PermutationParameter.ActualName;
556          m.PermutationParameter.Hidden = true;
557        }
558        Operators.AddRange(manipulators.Except(Operators.OfType<IPermutationManipulator>()));
559        #endregion
560        #region Wire Permutation ShakingOperators
561        var shakingOperators = Operators.OfType<IPermutationMultiNeighborhoodShakingOperator>()
562          .Union(ApplicationManager.Manager.GetInstances<IPermutationMultiNeighborhoodShakingOperator>(), new TypeEqualityComparer<IPermutationMultiNeighborhoodShakingOperator>())
563          .ToList();
564        foreach (var op in shakingOperators) {
565          op.PermutationParameter.ActualName = paramName;
566          op.PermutationParameter.Hidden = true;
567        }
568        Operators.AddRange(shakingOperators.Except(Operators.OfType<IPermutationMultiNeighborhoodShakingOperator>()));
569        #endregion
570      } else {
571        Operators.RemoveAll(x => x is IPermutationCrossover
572          || x is IPermutationManipulator
573          || x is IPermutationMultiNeighborhoodShakingOperator);
574      }
575      #endregion
576    }
577
578    protected virtual void ConfigureMultiVectorEncodingOperators(MultiEncodingCreator newCreator, MultiEncoding encoding) {
579      var newBinParams = new HashSet<string>(newCreator.Operators.OfType<IBinaryVectorCreator>().Select(x => x.BinaryVectorParameter.ActualName));
580      var newIntParams = new HashSet<string>(newCreator.Operators.OfType<IIntegerVectorCreator>().Select(x => x.IntegerVectorParameter.ActualName));
581      var newRealParams = new HashSet<string>(newCreator.Operators.OfType<IRealVectorCreator>().Select(x => x.RealVectorParameter.ActualName));
582      var newPermParams = new HashSet<string>(newCreator.Operators.OfType<IPermutationCreator>().Select(x => x.PermutationParameter.ActualName));
583
584      var oldCreator = SolutionCreator as MultiEncodingCreator;
585      if (oldCreator == null) SolutionCreator = newCreator;
586      else {
587        #region Configure BinaryVector Creator
588        var oldBinParams = new HashSet<string>(oldCreator.Operators.OfType<IBinaryVectorCreator>().Select(x => x.BinaryVectorParameter.ActualName));
589        foreach (var toAdd in newBinParams.Except(oldBinParams)) {
590          oldCreator.Operators.Add(newCreator.Operators.OfType<IBinaryVectorCreator>().Single(x => x.BinaryVectorParameter.ActualName == toAdd));
591        }
592        foreach (var toRemove in oldBinParams.Except(newBinParams)) {
593          var op = oldCreator.Operators.OfType<IBinaryVectorCreator>().SingleOrDefault(x => x.BinaryVectorParameter.ActualName == toRemove);
594          if (op != null) oldCreator.Operators.Remove(op);
595        }
596        #endregion
597
598        #region Configure IntegerVector Creator
599        var oldIntParams = new HashSet<string>(oldCreator.Operators.OfType<IIntegerVectorCreator>().Select(x => x.IntegerVectorParameter.ActualName));
600        foreach (var toAdd in newIntParams.Except(oldIntParams)) {
601          oldCreator.Operators.Add(newCreator.Operators.OfType<IIntegerVectorCreator>().Single(x => x.IntegerVectorParameter.ActualName == toAdd));
602        }
603        foreach (var toRemove in oldIntParams.Except(newIntParams)) {
604          var op = oldCreator.Operators.OfType<IIntegerVectorCreator>().SingleOrDefault(x => x.IntegerVectorParameter.ActualName == toRemove);
605          if (op != null) oldCreator.Operators.Remove(op);
606        }
607        #endregion
608
609        #region Configure RealVector Creator
610        var oldRealParams = new HashSet<string>(oldCreator.Operators.OfType<IRealVectorCreator>().Select(x => x.RealVectorParameter.ActualName));
611        foreach (var toAdd in newRealParams.Except(oldRealParams)) {
612          oldCreator.Operators.Add(newCreator.Operators.OfType<IRealVectorCreator>().Single(x => x.RealVectorParameter.ActualName == toAdd));
613        }
614        foreach (var toRemove in oldRealParams.Except(newRealParams)) {
615          var op = oldCreator.Operators.OfType<IRealVectorCreator>().SingleOrDefault(x => x.RealVectorParameter.ActualName == toRemove);
616          if (op != null) oldCreator.Operators.Remove(op);
617        }
618        #endregion
619
620        #region Configure Permutation Creator
621        var oldPermParams = new HashSet<string>(oldCreator.Operators.OfType<IPermutationCreator>().Select(x => x.PermutationParameter.ActualName));
622        foreach (var toAdd in newPermParams.Except(oldPermParams)) {
623          oldCreator.Operators.Add(newCreator.Operators.OfType<IPermutationCreator>().Single(x => x.PermutationParameter.ActualName == toAdd));
624        }
625        foreach (var toRemove in oldPermParams.Except(newPermParams)) {
626          var op = oldCreator.Operators.OfType<IPermutationCreator>().SingleOrDefault(x => x.PermutationParameter.ActualName == toRemove);
627          if (op != null) oldCreator.Operators.Remove(op);
628        }
629        // we also have to sync the permutation type (in case this changes, as it is a value parameter)
630        foreach (var intersect in newPermParams.Intersect(oldPermParams)) {
631          var oldPermCreator = oldCreator.Operators.OfType<IPermutationCreator>().Single(x => x.PermutationParameter.ActualName == intersect);
632          var newPermCreator = newCreator.Operators.OfType<IPermutationCreator>().Single(x => x.PermutationParameter.ActualName == intersect);
633          oldPermCreator.PermutationTypeParameter.Value = newPermCreator.PermutationTypeParameter.Value;
634        }
635        #endregion
636
637      }
638
639      // crossover and manipulator for multi-vector encoding
640      // the condition checks if a multi-vector encoding is to be updated (there already exists ParameterVectorCrossover and ParameterVectorManipulator)
641      if (Operators.OfType<MultiEncodingCrossover>().Any() && Operators.OfType<MultiEncodingManipulator>().Any()) {
642        #region Update existing multi-vector encoding
643        #region Update ParameterVector Crossover ...
644        foreach (var oldXo in Operators.OfType<MultiEncodingCrossover>()) {
645          #region ... for binary parameters
646          var oldBinParams = new HashSet<string>(oldXo.Operators.OfType<IBinaryVectorCrossover>().Select(x => x.ChildParameter.ActualName));
647          foreach (var toAdd in newBinParams.Except(oldBinParams))
648            oldXo.Operators.Add(GetDefaultBinaryCrossover(toAdd, encoding));
649          foreach (var toRemove in oldBinParams.Except(newBinParams)) {
650            var op = oldXo.Operators.OfType<IBinaryVectorCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
651            if (op != null) oldXo.Operators.Remove(op);
652          }
653          #endregion
654          #region ... for integer parameters
655          var oldIntParams = new HashSet<string>(oldXo.Operators.OfType<IIntegerVectorCrossover>().Select(x => x.ChildParameter.ActualName));
656          foreach (var toAdd in newIntParams.Except(oldIntParams))
657            oldXo.Operators.Add(GetDefaultIntegerCrossover(toAdd, encoding));
658          foreach (var toRemove in oldIntParams.Except(newIntParams)) {
659            var op = oldXo.Operators.OfType<IIntegerVectorCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
660            if (op != null) oldXo.Operators.Remove(op);
661          }
662          #endregion
663          #region ... for real parameters
664          var oldRealParams = new HashSet<string>(oldXo.Operators.OfType<IRealVectorCrossover>().Select(x => x.ChildParameter.ActualName));
665          foreach (var toAdd in newRealParams.Except(oldRealParams))
666            oldXo.Operators.Add(GetDefaultRealCrossover(toAdd, encoding));
667          foreach (var toRemove in oldRealParams.Except(newRealParams)) {
668            var op = oldXo.Operators.OfType<IRealVectorCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
669            if (op != null) oldXo.Operators.Remove(op);
670          }
671          #endregion
672          #region ... for permutation parameters
673          var oldPermParams = new HashSet<string>(oldXo.Operators.OfType<IPermutationCrossover>().Select(x => x.ChildParameter.ActualName));
674          foreach (var toAdd in newPermParams.Except(oldPermParams))
675            oldXo.Operators.Add(GetDefaultPermutationCrossover(toAdd, encoding));
676          foreach (var toRemove in oldPermParams.Except(newPermParams)) {
677            var op = oldXo.Operators.OfType<IPermutationCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
678            if (op != null) oldXo.Operators.Remove(op);
679          }
680          #endregion
681        }
682        #endregion
683        #region Update ParameterVector Manipulator ...
684        foreach (var oldM in Operators.OfType<MultiEncodingManipulator>()) {
685          #region ... for binary parameters
686          var oldBinParams = new HashSet<string>(oldM.Operators.OfType<IBinaryVectorManipulator>().Select(x => x.BinaryVectorParameter.ActualName));
687          foreach (var toAdd in newBinParams.Except(oldBinParams))
688            oldM.Operators.Add(GetDefaultBinaryManipulator(toAdd, encoding));
689          foreach (var toRemove in oldBinParams.Except(newBinParams)) {
690            var op = oldM.Operators.OfType<IBinaryVectorManipulator>().SingleOrDefault(x => x.BinaryVectorParameter.ActualName == toRemove);
691            if (op != null) oldM.Operators.Remove(op);
692          }
693          #endregion
694          #region ... for integer parameters
695          var oldIntParams = new HashSet<string>(oldM.Operators.OfType<IIntegerVectorManipulator>().Select(x => x.IntegerVectorParameter.ActualName));
696          foreach (var toAdd in newIntParams.Except(oldIntParams))
697            oldM.Operators.Add(GetDefaultIntegerManipulator(toAdd, encoding));
698          foreach (var toRemove in oldIntParams.Except(newIntParams)) {
699            var op = oldM.Operators.OfType<IIntegerVectorManipulator>().SingleOrDefault(x => x.IntegerVectorParameter.ActualName == toRemove);
700            if (op != null) oldM.Operators.Remove(op);
701          }
702          #endregion
703          #region ... for real parameters
704          var oldRealParams = new HashSet<string>(oldM.Operators.OfType<IRealVectorManipulator>().Select(x => x.RealVectorParameter.ActualName));
705          foreach (var toAdd in newRealParams.Except(oldRealParams))
706            oldM.Operators.Add(GetDefaultRealManipulator(toAdd, encoding));
707          foreach (var toRemove in oldRealParams.Except(newRealParams)) {
708            var op = oldM.Operators.OfType<IRealVectorManipulator>().SingleOrDefault(x => x.RealVectorParameter.ActualName == toRemove);
709            if (op != null) oldM.Operators.Remove(op);
710          }
711          #endregion
712          #region ... for permutation parameters
713          var oldPermParams = new HashSet<string>(oldM.Operators.OfType<IPermutationManipulator>().Select(x => x.PermutationParameter.ActualName));
714          foreach (var toAdd in newPermParams.Except(oldPermParams))
715            oldM.Operators.Add(GetDefaultPermutationManipulator(toAdd, encoding));
716          foreach (var toRemove in oldPermParams.Except(newPermParams)) {
717            var op = oldM.Operators.OfType<IPermutationManipulator>().SingleOrDefault(x => x.PermutationParameter.ActualName == toRemove);
718            if (op != null) oldM.Operators.Remove(op);
719          }
720          #endregion
721        }
722        #endregion
723        #endregion
724      } else {
725        #region Handle transition from single-vector to multi-vector encoding
726        Operators.RemoveAll(x => x is ICrossover);
727        Operators.RemoveAll(x => x is IManipulator);
728        Operators.RemoveAll(x => x is IStrategyParameterCreator || x is IStrategyParameterManipulator || x is IStrategyParameterCrossover);
729        Operators.RemoveAll(x => x is IParticleCreator);
730        Operators.RemoveAll(x => x is IParticleUpdater);
731        Operators.RemoveAll(x => x is ISwarmUpdater);
732        Operators.RemoveAll(x => x is IMultiNeighborhoodShakingOperator);
733
734        var crossover = new MultiEncodingCrossover();
735        var manipulator = new MultiEncodingManipulator();
736        foreach (var enc in encoding.Encodings) {
737          if (enc is BinaryEncoding) {
738            crossover.Operators.Add(GetDefaultBinaryCrossover(enc.Name, encoding));
739            manipulator.Operators.Add(GetDefaultBinaryManipulator(enc.Name, encoding));
740            continue;
741          }
742          var intConfig = enc as IntegerEncoding;
743          if (intConfig != null) {
744            crossover.Operators.Add(GetDefaultIntegerCrossover(enc.Name, encoding));
745            manipulator.Operators.Add(GetDefaultIntegerManipulator(enc.Name, encoding));
746            continue;
747          }
748          var realConfig = enc as RealEncoding;
749          if (realConfig != null) {
750            crossover.Operators.Add(GetDefaultRealCrossover(enc.Name, encoding));
751            manipulator.Operators.Add(GetDefaultRealManipulator(enc.Name, encoding));
752            continue;
753          }
754          var permConfig = enc as PermutationEncoding;
755          if (permConfig != null) {
756            crossover.Operators.Add(GetDefaultPermutationCrossover(enc.Name, encoding));
757            manipulator.Operators.Add(GetDefaultPermutationManipulator(enc.Name, encoding));
758            continue;
759          }
760          throw new InvalidOperationException("Unknown type for parameter " + enc.Name);
761        }
762        Operators.Add(crossover);
763        Operators.Add(manipulator);
764        #endregion
765      }
766    }
767
768    #region GetDefaultOperators for Crossovers and Manipulators
769    // ReSharper disable RedundantNameQualifier
770    protected virtual IBinaryVectorCrossover GetDefaultBinaryCrossover(string paramName, MultiEncoding config) {
771      var binConfig = (BinaryEncoding)config.Encodings[paramName];
772      IBinaryVectorCrossover binXo;
773      if (binConfig.Length > 3) binXo = new Encodings.BinaryVectorEncoding.SinglePointCrossover();
774      else binXo = new Encodings.BinaryVectorEncoding.UniformCrossover();
775      binXo.ChildParameter.ActualName = paramName;
776      binXo.ParentsParameter.ActualName = paramName;
777      return binXo;
778    }
779
780    protected virtual IBinaryVectorManipulator GetDefaultBinaryManipulator(string paramName, MultiEncoding config) {
781      var binM = new Encodings.BinaryVectorEncoding.SomePositionsBitflipManipulator();
782      binM.BinaryVectorParameter.ActualName = paramName;
783      binM.MutationProbabilityParameter.Value = new DoubleValue(0.1);
784      return binM;
785    }
786
787    protected virtual IIntegerVectorCrossover GetDefaultIntegerCrossover(string paramName, MultiEncoding config) {
788      var intXo = new Encodings.IntegerVectorEncoding.RoundedBlendAlphaCrossover();
789      intXo.ChildParameter.ActualName = paramName;
790      intXo.ParentsParameter.ActualName = paramName;
791      intXo.BoundsParameter.ActualName = paramName + "Bounds";
792      return intXo;
793    }
794
795    protected virtual IIntegerVectorManipulator GetDefaultIntegerManipulator(string paramName, MultiEncoding configuration) {
796      var intM = new Encodings.IntegerVectorEncoding.UniformSomePositionsManipulator();
797      intM.IntegerVectorParameter.ActualName = paramName;
798      intM.BoundsParameter.ActualName = paramName + "Bounds";
799      intM.ProbabilityParameter.Value = new DoubleValue(0.1);
800      return intM;
801    }
802
803    protected virtual IRealVectorCrossover GetDefaultRealCrossover(string paramName, MultiEncoding configuration) {
804      var realXo = new Encodings.RealVectorEncoding.BlendAlphaCrossover();
805      realXo.ChildParameter.ActualName = paramName;
806      realXo.ParentsParameter.ActualName = paramName;
807      realXo.BoundsParameter.ActualName = paramName + "Bounds";
808      return realXo;
809    }
810
811    protected virtual IRealVectorManipulator GetDefaultRealManipulator(string paramName, MultiEncoding configuration) {
812      var realM = new Encodings.RealVectorEncoding.BreederGeneticAlgorithmManipulator();
813      realM.RealVectorParameter.ActualName = paramName;
814      realM.BoundsParameter.ActualName = paramName + "Bounds";
815      return realM;
816    }
817
818    protected virtual IPermutationCrossover GetDefaultPermutationCrossover(string paramName, MultiEncoding configuration) {
819      var permXo = new Encodings.PermutationEncoding.PartiallyMatchedCrossover();
820      permXo.ChildParameter.ActualName = paramName;
821      permXo.ParentsParameter.ActualName = paramName;
822      return permXo;
823    }
824
825    protected virtual IPermutationManipulator GetDefaultPermutationManipulator(string paramName, MultiEncoding configuration) {
826      var permM = new Encodings.PermutationEncoding.Swap2Manipulator();
827      permM.PermutationParameter.ActualName = paramName;
828      return permM;
829    }
830    // ReSharper restore RedundantNameQualifier
831    #endregion
832  }
833}
Note: See TracBrowser for help on using the repository browser.