Free cookie consent management tool by TermsFeed Policy Generator

source: branches/ProgrammableProblem/HeuristicLab.Problems.Programmable/3.3/SingleObjectiveProgrammableProblem.cs @ 11546

Last change on this file since 11546 was 11546, checked in by mkommend, 10 years ago

#2174: Extracted wiring of real vector operators from the single objective programmable problem to the real encoding.

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