Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 11393 was 11393, checked in by abeham, 10 years ago

#2174: enabled possibility to set different problem definitions than just scripted ones

File size: 34.6 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<ISingleObjectiveProblemDefinitionHost> ProblemDefinitionParameter {
58      get { return (IValueParameter<ISingleObjectiveProblemDefinitionHost>)Parameters["ProblemDefinition"]; }
59    }
60
61    protected IValueParameter<Configuration> ConfigurationParameter {
62      get { return (IValueParameter<Configuration>)Parameters["Configuration"]; }
63    }
64
65    public ISingleObjectiveProblemDefinitionHost ProblemDefinition {
66      get { return ProblemDefinitionParameter.Value; }
67      set { ProblemDefinitionParameter.Value = value; }
68    }
69
70    [Storable]
71    protected List<IParameter> DynamicConfigurationParameters;
72
73    [StorableConstructor]
74    protected SingleObjectiveProgrammableProblem(bool deserializing) : base(deserializing) { }
75
76    protected SingleObjectiveProgrammableProblem(SingleObjectiveProgrammableProblem original, Cloner cloner)
77      : base(original, cloner) {
78      DynamicConfigurationParameters = original.DynamicConfigurationParameters.Select(cloner.Clone).ToList();
79      RegisterEventHandlers();
80    }
81    public SingleObjectiveProgrammableProblem()
82      : base(new SingleObjectiveEvaluator(), new ParameterVectorCreater()) {
83      Parameters.Add(new ValueParameter<ISingleObjectiveProblemDefinitionHost>("ProblemDefinition", "Defines the problem.", new SingleObjectiveProblemDefinitionScript() { Name = Name }));
84      Parameters.Add(new ValueParameter<Configuration>("Configuration", "Describes which parameters exist, what they're called, what type they are and their bounds if any."));
85
86      DynamicConfigurationParameters = new List<IParameter>();
87
88      Operators.Add(new BestScopeSolutionAnalyzer());
89      Operators.Add(Evaluator);
90      Operators.Add(SolutionCreator);
91
92      RegisterEventHandlers();
93    }
94
95    public override IDeepCloneable Clone(Cloner cloner) {
96      return new SingleObjectiveProgrammableProblem(this, cloner);
97    }
98
99    [StorableHook(HookType.AfterDeserialization)]
100    // ReSharper disable UnusedMember.Local
101    private void AfterDeserialization() {
102      RegisterEventHandlers();
103    }
104    // ReSharper restore UnusedMember.Local
105
106    private void RegisterEventHandlers() {
107      ProblemDefinitionParameter.ValueChanged += ProblemDefinitionParameterOnValueChanged;
108      RegisterHostInstanceChanges();
109    }
110
111    private void ProblemDefinitionParameterOnValueChanged(object sender, EventArgs eventArgs) {
112      RegisterHostInstanceChanges();
113      Parameterize();
114    }
115
116    private void RegisterHostInstanceChanges() {
117      ProblemDefinitionParameter.Value.InstanceChanged += ProblemDefinitionHostOnInstanceChanged;
118      ProblemDefinitionParameter.Value.NameChanged += ProblemDefinitionHostOnNameChanged;
119    }
120
121    private void ProblemDefinitionHostOnNameChanged(object sender, EventArgs eventArgs) {
122      if (sender != ProblemDefinitionParameter.Value) return;
123      Name = ProblemDefinitionParameter.Value.Name;
124    }
125
126    protected override void OnNameChanged() {
127      base.OnNameChanged();
128      ProblemDefinitionParameter.Value.Name = Name;
129    }
130
131    protected virtual void ProblemDefinitionHostOnInstanceChanged(object sender, EventArgs eventArgs) {
132      Parameterize();
133    }
134
135    protected virtual void Parameterize() {
136      var instance = ProblemDefinitionParameter.Value.Instance;
137      if (instance == null) return;
138
139      Configuration configuration;
140      try {
141        configuration = instance.GetConfiguration();
142      } catch { return; }
143      ConfigurationParameter.Value = configuration;
144      Maximization.Value = instance.IsMaximizationProblem;
145
146      var solutionCreators = UpdateDynamicConfigurationParameters(configuration);
147
148      if (solutionCreators.Count == 1) {
149        UpdateSingleVectorEncodingOperators(solutionCreators);
150      } else {
151        UpdateMultiVectorEncodingOperators(solutionCreators, configuration);
152      }
153      UpdateMoveOperators();
154    }
155
156    protected virtual List<ISolutionCreator> UpdateDynamicConfigurationParameters(Configuration configuration) {
157      foreach (var param in DynamicConfigurationParameters)
158        if (Parameters.Contains(param)) Parameters.Remove(param);
159      DynamicConfigurationParameters.Clear();
160
161      var solutionCreators = new List<ISolutionCreator>();
162      foreach (var param in configuration.Parameters) {
163        /*
164         * Binary Vectors
165         */
166        var binConfig = param.Value as BinaryParameterConfiguration;
167        if (binConfig != null) {
168          var p = new ValueParameter<IntValue>(param.Key + "Length", binConfig.Length);
169          DynamicConfigurationParameters.Add(p);
170
171          var creator = new RandomBinaryVectorCreator();
172          creator.BinaryVectorParameter.ActualName = param.Key;
173          creator.LengthParameter.ActualName = p.Name;
174          solutionCreators.Add(creator);
175        }
176        /*
177         * Integer Vectors
178         */
179        var intConfig = param.Value as IntegerParameterConfiguration;
180        if (intConfig != null) {
181          var l = new ValueParameter<IntValue>(param.Key + "Length", intConfig.Length);
182          var b = new ValueParameter<IntMatrix>(param.Key + "Bounds", intConfig.Bounds);
183          DynamicConfigurationParameters.Add(l);
184          DynamicConfigurationParameters.Add(b);
185
186          var creator = new UniformRandomIntegerVectorCreator();
187          creator.IntegerVectorParameter.ActualName = param.Key;
188          creator.LengthParameter.ActualName = l.Name;
189          creator.BoundsParameter.ActualName = b.Name;
190          solutionCreators.Add(creator);
191        }
192        /*
193         * Real Vectors
194         */
195        var realConfig = param.Value as RealParameterConfiguration;
196        if (realConfig != null) {
197          var l = new ValueParameter<IntValue>(param.Key + "Length", realConfig.Length);
198          var b = new ValueParameter<DoubleMatrix>(param.Key + "Bounds", realConfig.Bounds);
199          DynamicConfigurationParameters.Add(l);
200          DynamicConfigurationParameters.Add(b);
201
202          var creator = new UniformRandomRealVectorCreator();
203          creator.RealVectorParameter.ActualName = param.Key;
204          creator.LengthParameter.ActualName = l.Name;
205          creator.BoundsParameter.ActualName = b.Name;
206          solutionCreators.Add(creator);
207        }
208        /*
209         * Permutations
210         */
211        var permConfig = param.Value as PermutationParameterConfiguration;
212        if (permConfig != null) {
213          var l = new ValueParameter<IntValue>(param.Key + "Length", permConfig.Length);
214          DynamicConfigurationParameters.Add(l);
215
216          var creator = new RandomPermutationCreator();
217          creator.PermutationParameter.ActualName = param.Key;
218          creator.LengthParameter.ActualName = l.Name;
219          creator.PermutationTypeParameter.Value = permConfig.Type;
220          solutionCreators.Add(creator);
221        }
222      }
223
224      foreach (var param in DynamicConfigurationParameters) {
225        param.Hidden = true;
226        Parameters.Add(param);
227      }
228      return solutionCreators;
229    }
230
231    protected virtual void UpdateSingleVectorEncodingOperators(List<ISolutionCreator> solutionCreators) {
232      var newCreator = solutionCreators.Single();
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        Operators.RemoveAll(x => x is ICrossover && !(x is IBinaryVectorCrossover) || x is IBinaryVectorCrossover && ((IBinaryVectorCrossover)x).ChildParameter.ActualName != paramName);
243        Operators.RemoveAll(x => x is IManipulator && !(x is IBinaryVectorManipulator) || x is IBinaryVectorManipulator && ((IBinaryVectorManipulator)x).BinaryVectorParameter.ActualName != paramName);
244        var crossovers = ApplicationManager.Manager.GetInstances<IBinaryVectorCrossover>().ToList();
245        var manipulators = ApplicationManager.Manager.GetInstances<IBinaryVectorManipulator>().ToList();
246        foreach (var xo in crossovers) {
247          xo.ChildParameter.ActualName = binCreator.BinaryVectorParameter.ActualName;
248          xo.ParentsParameter.ActualName = binCreator.BinaryVectorParameter.ActualName;
249        }
250        foreach (var m in manipulators)
251          m.BinaryVectorParameter.ActualName = binCreator.BinaryVectorParameter.ActualName;
252        Operators.AddRange(crossovers.Where(x => Operators.All(y => x.GetType() != y.GetType())));
253        Operators.AddRange(manipulators.Where(x => Operators.All(y => x.GetType() != y.GetType())));
254      }
255      var intCreator = newCreator as IIntegerVectorCreator;
256      if (intCreator != null) {
257        var paramName = intCreator.IntegerVectorParameter.ActualName;
258        // do not replace an integer vector creator that was manually set
259        if (!(SolutionCreator is IIntegerVectorCreator)
260          || ((IIntegerVectorCreator)SolutionCreator).IntegerVectorParameter.ActualName != intCreator.IntegerVectorParameter.ActualName) {
261          Operators.Remove(SolutionCreator);
262          SolutionCreator = newCreator;
263          Operators.Add(SolutionCreator);
264        }
265        Operators.RemoveAll(x => x is ICrossover && !(x is IIntegerVectorCrossover) || x is IIntegerVectorCrossover && ((IIntegerVectorCrossover)x).ChildParameter.ActualName != paramName);
266        Operators.RemoveAll(x => x is IManipulator && !(x is IIntegerVectorManipulator) || x is IIntegerVectorManipulator && ((IIntegerVectorManipulator)x).IntegerVectorParameter.ActualName != paramName);
267        var crossovers = ApplicationManager.Manager.GetInstances<IIntegerVectorCrossover>().ToList();
268        var manipulators = ApplicationManager.Manager.GetInstances<IIntegerVectorManipulator>().ToList();
269        foreach (var xo in crossovers) {
270          xo.ChildParameter.ActualName = intCreator.IntegerVectorParameter.ActualName;
271          xo.ParentsParameter.ActualName = intCreator.IntegerVectorParameter.ActualName;
272        }
273        foreach (var m in manipulators)
274          m.IntegerVectorParameter.ActualName = intCreator.IntegerVectorParameter.ActualName;
275        foreach (var bo in crossovers.OfType<IBoundedIntegerVectorOperator>()
276              .Concat(manipulators.OfType<IBoundedIntegerVectorOperator>())
277              .ToList()) {
278          bo.BoundsParameter.ActualName = intCreator.BoundsParameter.ActualName;
279        }
280        Operators.AddRange(crossovers.Where(x => Operators.All(y => x.GetType() != y.GetType())));
281        Operators.AddRange(manipulators.Where(x => Operators.All(y => x.GetType() != y.GetType())));
282      }
283      var realCreator = newCreator as IRealVectorCreator;
284      if (realCreator != null) {
285        var paramName = realCreator.RealVectorParameter.ActualName;
286        // do not replace a real vector creator that was manually set
287        if (!(SolutionCreator is IRealVectorCreator)
288            || ((IRealVectorCreator)SolutionCreator).RealVectorParameter.ActualName != realCreator.RealVectorParameter.ActualName) {
289          Operators.Remove(SolutionCreator);
290          SolutionCreator = newCreator;
291          Operators.Add(SolutionCreator);
292        }
293        Operators.RemoveAll(x => x is ICrossover && !(x is IRealVectorCrossover) || x is IRealVectorCrossover && ((IRealVectorCrossover)x).ChildParameter.ActualName != paramName);
294        Operators.RemoveAll(x => x is IManipulator && !(x is IRealVectorManipulator) || x is IRealVectorManipulator && ((IRealVectorManipulator)x).RealVectorParameter.ActualName != paramName);
295        var crossovers = ApplicationManager.Manager.GetInstances<IRealVectorCrossover>().ToList();
296        var manipulators = ApplicationManager.Manager.GetInstances<IRealVectorManipulator>().ToList();
297        foreach (var xo in crossovers) {
298          xo.ChildParameter.ActualName = realCreator.RealVectorParameter.ActualName;
299          xo.ParentsParameter.ActualName = realCreator.RealVectorParameter.ActualName;
300          xo.BoundsParameter.ActualName = realCreator.BoundsParameter.ActualName;
301        }
302        foreach (var m in manipulators) {
303          m.RealVectorParameter.ActualName = realCreator.RealVectorParameter.ActualName;
304          m.BoundsParameter.ActualName = realCreator.BoundsParameter.ActualName;
305        }
306        Operators.AddRange(crossovers.Where(x => Operators.All(y => x.GetType() != y.GetType())));
307        Operators.AddRange(manipulators.Where(x => Operators.All(y => x.GetType() != y.GetType())));
308      }
309      var permCreator = newCreator as IPermutationCreator;
310      if (permCreator != null) {
311        var paramName = permCreator.PermutationParameter.ActualName;
312        // do not replace a permutation creator that was manually set
313        if (!(SolutionCreator is IPermutationCreator)
314            || ((IPermutationCreator)SolutionCreator).PermutationParameter.ActualName != permCreator.PermutationParameter.ActualName) {
315          Operators.Remove(SolutionCreator);
316          SolutionCreator = newCreator;
317          Operators.Add(SolutionCreator);
318        }
319        Operators.RemoveAll(x => x is ICrossover && !(x is IPermutationCrossover) || x is IPermutationCrossover && ((IPermutationCrossover)x).ChildParameter.ActualName != paramName);
320        Operators.RemoveAll(x => x is IManipulator && !(x is IPermutationManipulator) || x is IPermutationManipulator && ((IPermutationManipulator)x).PermutationParameter.ActualName != paramName);
321        var crossovers = ApplicationManager.Manager.GetInstances<IPermutationCrossover>().ToList();
322        var manipulators = ApplicationManager.Manager.GetInstances<IPermutationManipulator>().ToList();
323        foreach (var xo in crossovers) {
324          xo.ChildParameter.ActualName = permCreator.PermutationParameter.ActualName;
325          xo.ParentsParameter.ActualName = permCreator.PermutationParameter.ActualName;
326        }
327        foreach (var m in manipulators)
328          m.PermutationParameter.ActualName = permCreator.PermutationParameter.ActualName;
329        Operators.AddRange(crossovers.Where(x => Operators.All(y => x.GetType() != y.GetType())));
330        Operators.AddRange(manipulators.Where(x => Operators.All(y => x.GetType() != y.GetType())));
331      }
332    }
333
334    protected virtual void UpdateMultiVectorEncodingOperators(List<ISolutionCreator> solutionCreators, Configuration configuration) {
335      var oldCreator = SolutionCreator as ParameterVectorCreater;
336      var newCreator = new ParameterVectorCreater();
337
338      /*
339       * Binary Vectors
340       */
341      var newBinParams = new HashSet<string>(solutionCreators.OfType<IBinaryVectorCreator>().Select(x => x.BinaryVectorParameter.ActualName));
342      if (oldCreator != null) {
343        // we want to reuse the old creator
344        var oldParams = new HashSet<string>(oldCreator.Operators.OfType<IBinaryVectorCreator>()
345          .Select(x => x.BinaryVectorParameter.ActualName));
346        foreach (var toAdd in newBinParams.Except(oldParams)) {
347          var paramName = toAdd;
348          oldCreator.Operators.Add(
349            solutionCreators.OfType<IBinaryVectorCreator>().Single(x => x.BinaryVectorParameter.ActualName == paramName));
350        }
351        foreach (var toRemove in oldParams.Except(newBinParams)) {
352          var paramName = toRemove;
353          var op =
354            oldCreator.Operators.OfType<IBinaryVectorCreator>()
355              .SingleOrDefault(x => x.BinaryVectorParameter.ActualName == paramName);
356          if (op != null) oldCreator.Operators.Remove(op);
357        }
358      } else {
359        // we will use the new creator
360        foreach (var binCreator in solutionCreators.OfType<IBinaryVectorCreator>()) {
361          newCreator.Operators.Add(binCreator);
362        }
363      }
364
365      /*
366       * Integer Vectors
367       */
368      var newIntParams = new HashSet<string>(solutionCreators.OfType<IIntegerVectorCreator>().Select(x => x.IntegerVectorParameter.ActualName));
369      if (oldCreator != null) {
370        // we want to reuse the old creator
371        var oldParams = new HashSet<string>(oldCreator
372          .Operators.OfType<IIntegerVectorCreator>()
373          .Select(x => x.IntegerVectorParameter.ActualName));
374        foreach (var toAdd in newIntParams.Except(oldParams)) {
375          var paramName = toAdd;
376          oldCreator.Operators.Add(
377            solutionCreators.OfType<IIntegerVectorCreator>().Single(x => x.IntegerVectorParameter.ActualName == paramName));
378        }
379        foreach (var toRemove in oldParams.Except(newIntParams)) {
380          var paramName = toRemove;
381          var op =
382            oldCreator.Operators.OfType<IIntegerVectorCreator>()
383              .SingleOrDefault(x => x.IntegerVectorParameter.ActualName == paramName);
384          if (op != null) oldCreator.Operators.Remove(op);
385        }
386      } else {
387        // we will use the new creator
388        foreach (var intCreator in solutionCreators.OfType<IIntegerVectorCreator>()) {
389          newCreator.Operators.Add(intCreator);
390        }
391      }
392
393      /*
394       * Real Vectors
395       */
396      var newRealParams = new HashSet<string>(solutionCreators.OfType<IRealVectorCreator>().Select(x => x.RealVectorParameter.ActualName));
397      if (oldCreator != null) {
398        // we want to reuse the old creator
399        var oldParams = new HashSet<string>(oldCreator
400          .Operators.OfType<IRealVectorCreator>()
401          .Select(x => x.RealVectorParameter.ActualName));
402        foreach (var toAdd in newRealParams.Except(oldParams)) {
403          var paramName = toAdd;
404          oldCreator.Operators.Add(
405            solutionCreators.OfType<IRealVectorCreator>().Single(x => x.RealVectorParameter.ActualName == paramName));
406        }
407        foreach (var toRemove in oldParams.Except(newRealParams)) {
408          var paramName = toRemove;
409          var op =
410            oldCreator.Operators.OfType<IRealVectorCreator>()
411              .SingleOrDefault(x => x.RealVectorParameter.ActualName == paramName);
412          if (op != null) oldCreator.Operators.Remove(op);
413        }
414      } else {
415        // we will use the new creator
416        foreach (var realCreator in solutionCreators.OfType<IRealVectorCreator>()) {
417          newCreator.Operators.Add(realCreator);
418        }
419      }
420
421      /*
422       * Permutations
423       */
424      var newPermParams = new HashSet<string>(solutionCreators.OfType<IPermutationCreator>().Select(x => x.PermutationParameter.ActualName));
425      if (oldCreator != null) {
426        // we want to reuse the old creator
427        var oldParams = new HashSet<string>(oldCreator
428          .Operators.OfType<IPermutationCreator>()
429          .Select(x => x.PermutationParameter.ActualName));
430        foreach (var toAdd in newPermParams.Except(oldParams)) {
431          var paramName = toAdd;
432          oldCreator.Operators.Add(
433            solutionCreators.OfType<IPermutationCreator>().Single(x => x.PermutationParameter.ActualName == paramName));
434        }
435        foreach (var toRemove in oldParams.Except(newPermParams)) {
436          var paramName = toRemove;
437          var op =
438            oldCreator.Operators.OfType<IPermutationCreator>()
439              .SingleOrDefault(x => x.PermutationParameter.ActualName == paramName);
440          if (op != null) oldCreator.Operators.Remove(op);
441        }
442        // we also have to sync the permutation type (in case this changes, as it is a value parameter)
443        foreach (var intersect in newPermParams.Intersect(oldParams)) {
444          var paramName = intersect;
445          var oldPermCreator = oldCreator.Operators.OfType<IPermutationCreator>()
446            .Single(x => x.PermutationParameter.ActualName == paramName);
447          var newPermCreator = solutionCreators.OfType<IPermutationCreator>()
448            .Single(x => x.PermutationParameter.ActualName == paramName);
449          oldPermCreator.PermutationTypeParameter.Value = newPermCreator.PermutationTypeParameter.Value;
450        }
451      } else {
452        // we will use the new creator
453        foreach (var permCreator in solutionCreators.OfType<IPermutationCreator>()) {
454          newCreator.Operators.Add(permCreator);
455        }
456      }
457
458      if (oldCreator == null) SolutionCreator = newCreator;
459
460      // crossover and manipulator for multi-vector encoding
461      // the condition checks if a multi-vector encoding is to be updated (there already exists ParameterVectorCrossover and ParameterVectorManipulator)
462      if (Operators.OfType<ParameterVectorCrossover>().Any() && Operators.OfType<ParameterVectorManipulator>().Any()) {
463        // Update the crossovers
464        foreach (var oldXo in Operators.OfType<ParameterVectorCrossover>()) {
465          /*
466           * Binary Vectors
467           */
468          var oldBinParams = new HashSet<string>(oldXo.Operators.OfType<IBinaryVectorCrossover>()
469            .Select(x => x.ChildParameter.ActualName));
470          foreach (var toAdd in newBinParams.Except(oldBinParams))
471            oldXo.Operators.Add(GetDefaultBinaryCrossover(toAdd, configuration));
472          foreach (var toRemove in oldBinParams.Except(newBinParams)) {
473            var op =
474              oldXo.Operators.OfType<IBinaryVectorCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
475            if (op != null) oldXo.Operators.Remove(op);
476          }
477
478          /*
479           * Integer Vectors
480           */
481          var oldIntParams = new HashSet<string>(oldXo.Operators.OfType<IIntegerVectorCrossover>()
482            .Select(x => x.ChildParameter.ActualName));
483          foreach (var toAdd in newIntParams.Except(oldIntParams))
484            oldXo.Operators.Add(GetDefaultIntegerCrossover(toAdd, configuration));
485          foreach (var toRemove in oldIntParams.Except(newIntParams)) {
486            var op =
487              oldXo.Operators.OfType<IIntegerVectorCrossover>()
488                .SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
489            if (op != null) oldXo.Operators.Remove(op);
490          }
491
492          /*
493           * Real Vectors
494           */
495          var oldRealParams = new HashSet<string>(oldXo.Operators.OfType<IRealVectorCrossover>()
496            .Select(x => x.ChildParameter.ActualName));
497          foreach (var toAdd in newRealParams.Except(oldRealParams))
498            oldXo.Operators.Add(GetDefaultRealCrossover(toAdd, configuration));
499          foreach (var toRemove in oldRealParams.Except(newRealParams)) {
500            var op =
501              oldXo.Operators.OfType<IRealVectorCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
502            if (op != null) oldXo.Operators.Remove(op);
503          }
504
505          /*
506           * Permutations
507           */
508          var oldPermParams = new HashSet<string>(oldXo.Operators.OfType<IPermutationCrossover>()
509            .Select(x => x.ChildParameter.ActualName));
510          foreach (var toAdd in newPermParams.Except(oldPermParams))
511            oldXo.Operators.Add(GetDefaultPermutationCrossover(toAdd, configuration));
512          foreach (var toRemove in oldPermParams.Except(newPermParams)) {
513            var op =
514              oldXo.Operators.OfType<IPermutationCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
515            if (op != null) oldXo.Operators.Remove(op);
516          }
517        }
518        // Update the manipulators
519        foreach (var oldM in Operators.OfType<ParameterVectorManipulator>()) {
520          /*
521           * Binary Vectors
522           */
523          var oldBinParams = new HashSet<string>(oldM.Operators.OfType<IBinaryVectorManipulator>()
524            .Select(x => x.BinaryVectorParameter.ActualName));
525          foreach (var toAdd in newBinParams.Except(oldBinParams))
526            oldM.Operators.Add(GetDefaultBinaryManipulator(toAdd, configuration));
527          foreach (var toRemove in oldBinParams.Except(newBinParams)) {
528            var op =
529              oldM.Operators.OfType<IBinaryVectorManipulator>()
530                .SingleOrDefault(x => x.BinaryVectorParameter.ActualName == toRemove);
531            if (op != null) oldM.Operators.Remove(op);
532          }
533
534          /*
535           * Integer Vectors
536           */
537          var oldIntParams = new HashSet<string>(oldM.Operators.OfType<IIntegerVectorManipulator>()
538            .Select(x => x.IntegerVectorParameter.ActualName));
539          foreach (var toAdd in newIntParams.Except(oldIntParams))
540            oldM.Operators.Add(GetDefaultIntegerManipulator(toAdd, configuration));
541          foreach (var toRemove in oldIntParams.Except(newIntParams)) {
542            var op =
543              oldM.Operators.OfType<IIntegerVectorManipulator>()
544                .SingleOrDefault(x => x.IntegerVectorParameter.ActualName == toRemove);
545            if (op != null) oldM.Operators.Remove(op);
546          }
547
548          /*
549           * Real Vectors
550           */
551          var oldRealParams = new HashSet<string>(oldM.Operators.OfType<IRealVectorManipulator>()
552            .Select(x => x.RealVectorParameter.ActualName));
553          foreach (var toAdd in newRealParams.Except(oldRealParams))
554            oldM.Operators.Add(GetDefaultRealManipulator(toAdd, configuration));
555          foreach (var toRemove in oldRealParams.Except(newRealParams)) {
556            var op =
557              oldM.Operators.OfType<IRealVectorManipulator>()
558                .SingleOrDefault(x => x.RealVectorParameter.ActualName == toRemove);
559            if (op != null) oldM.Operators.Remove(op);
560          }
561
562          /*
563           * Permutations
564           */
565          var oldPermParams = new HashSet<string>(oldM.Operators.OfType<IPermutationManipulator>()
566            .Select(x => x.PermutationParameter.ActualName));
567          foreach (var toAdd in newPermParams.Except(oldPermParams))
568            oldM.Operators.Add(GetDefaultPermutationManipulator(toAdd, configuration));
569          foreach (var toRemove in oldPermParams.Except(newPermParams)) {
570            var op =
571              oldM.Operators.OfType<IPermutationManipulator>()
572                .SingleOrDefault(x => x.PermutationParameter.ActualName == toRemove);
573            if (op != null) oldM.Operators.Remove(op);
574          }
575        }
576      } else {
577        // change from single-vector encoding to multi-vector encoding
578        Operators.RemoveAll(x => x is ICrossover);
579        Operators.RemoveAll(x => x is IManipulator);
580        var crossover = new ParameterVectorCrossover();
581        var manipulator = new ParameterVectorManipulator();
582        foreach (var param in configuration.Parameters) {
583          if (param.Value is BinaryParameterConfiguration) {
584            crossover.Operators.Add(GetDefaultBinaryCrossover(param.Key, configuration));
585            manipulator.Operators.Add(GetDefaultBinaryManipulator(param.Key, configuration));
586            continue;
587          }
588          var intConfig = param.Value as IntegerParameterConfiguration;
589          if (intConfig != null) {
590            crossover.Operators.Add(GetDefaultIntegerCrossover(param.Key, configuration));
591            manipulator.Operators.Add(GetDefaultIntegerManipulator(param.Key, configuration));
592            continue;
593          }
594          var realConfig = param.Value as RealParameterConfiguration;
595          if (realConfig != null) {
596            crossover.Operators.Add(GetDefaultRealCrossover(param.Key, configuration));
597            manipulator.Operators.Add(GetDefaultRealManipulator(param.Key, configuration));
598            continue;
599          }
600          var permConfig = param.Value as PermutationParameterConfiguration;
601          if (permConfig != null) {
602            crossover.Operators.Add(GetDefaultPermutationCrossover(param.Key, configuration));
603            manipulator.Operators.Add(GetDefaultPermutationManipulator(param.Key, configuration));
604            continue;
605          }
606          throw new InvalidOperationException("Unknown type for parameter " + param.Key);
607        }
608        Operators.Add(crossover);
609        Operators.Add(manipulator);
610      }
611    }
612
613    protected virtual void UpdateMoveOperators() {
614      Operators.RemoveAll(x => x is IParameterVectorMoveOperator);
615      var generator = new ParameterVectorMoveGenerator();
616      generator.ConfigurationParameter.ActualName = ConfigurationParameter.Name;
617      generator.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name;
618
619      var evaluator = new ParameterVectorMoveEvaluator();
620      evaluator.ConfigurationParameter.ActualName = ConfigurationParameter.Name;
621      evaluator.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
622      evaluator.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name;
623
624      var maker = new ParameterVectorMoveMaker();
625      maker.ConfigurationParameter.ActualName = ConfigurationParameter.Name;
626      maker.MoveQualityParameter.ActualName = evaluator.MoveQualityParameter.ActualName;
627      maker.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
628
629      Operators.AddRange(new IItem[] { generator, evaluator, maker });
630    }
631
632    // ReSharper disable RedundantNameQualifier
633    protected virtual IBinaryVectorCrossover GetDefaultBinaryCrossover(string paramName, Configuration config) {
634      var binConfig = (BinaryParameterConfiguration)config.Parameters[paramName];
635      IBinaryVectorCrossover binXo;
636      if (binConfig.Length.Value > 3) binXo = new Encodings.BinaryVectorEncoding.SinglePointCrossover();
637      else binXo = new Encodings.BinaryVectorEncoding.UniformCrossover();
638      binXo.ChildParameter.ActualName = paramName;
639      binXo.ParentsParameter.ActualName = paramName;
640      return binXo;
641    }
642
643    protected virtual IBinaryVectorManipulator GetDefaultBinaryManipulator(string paramName, Configuration config) {
644      var binM = new Encodings.BinaryVectorEncoding.SomePositionsBitflipManipulator();
645      binM.BinaryVectorParameter.ActualName = paramName;
646      binM.MutationProbabilityParameter.Value = new DoubleValue(0.1);
647      return binM;
648    }
649
650    protected virtual IIntegerVectorCrossover GetDefaultIntegerCrossover(string paramName, Configuration config) {
651      var intXo = new Encodings.IntegerVectorEncoding.RoundedBlendAlphaBetaCrossover();
652      intXo.ChildParameter.ActualName = paramName;
653      intXo.ParentsParameter.ActualName = paramName;
654      intXo.BoundsParameter.ActualName = paramName + "Bounds";
655      intXo.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
656      intXo.MaximizationParameter.ActualName = MaximizationParameter.Name;
657      return intXo;
658    }
659
660    protected virtual IIntegerVectorManipulator GetDefaultIntegerManipulator(string paramName, Configuration configuration) {
661      var intM = new Encodings.IntegerVectorEncoding.UniformSomePositionsManipulator();
662      intM.IntegerVectorParameter.ActualName = paramName;
663      intM.BoundsParameter.ActualName = paramName + "Bounds";
664      intM.ProbabilityParameter.Value = new DoubleValue(0.1);
665      return intM;
666    }
667
668    protected virtual IRealVectorCrossover GetDefaultRealCrossover(string paramName, Configuration configuration) {
669      var realXo = new Encodings.RealVectorEncoding.BlendAlphaBetaCrossover();
670      realXo.ChildParameter.ActualName = paramName;
671      realXo.ParentsParameter.ActualName = paramName;
672      realXo.BoundsParameter.ActualName = paramName + "Bounds";
673      realXo.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
674      realXo.MaximizationParameter.ActualName = MaximizationParameter.Name;
675      return realXo;
676    }
677
678    protected virtual IRealVectorManipulator GetDefaultRealManipulator(string paramName, Configuration configuration) {
679      var realM = new Encodings.RealVectorEncoding.BreederGeneticAlgorithmManipulator();
680      realM.RealVectorParameter.ActualName = paramName;
681      realM.BoundsParameter.ActualName = paramName + "Bounds";
682      return realM;
683    }
684
685    protected virtual IPermutationCrossover GetDefaultPermutationCrossover(string paramName, Configuration configuration) {
686      var permXo = new Encodings.PermutationEncoding.PartiallyMatchedCrossover();
687      permXo.ChildParameter.ActualName = paramName;
688      permXo.ParentsParameter.ActualName = paramName;
689      return permXo;
690    }
691
692    protected virtual IPermutationManipulator GetDefaultPermutationManipulator(string paramName, Configuration configuration) {
693      var permM = new Encodings.PermutationEncoding.Swap2Manipulator();
694      permM.PermutationParameter.ActualName = paramName;
695      return permM;
696    }
697    // ReSharper restore RedundantNameQualifier
698  }
699}
Note: See TracBrowser for help on using the repository browser.