source: branches/SimSharp/HeuristicLab.Problems.Programmable/3.3/SingleObjectiveProgrammableProblem.cs @ 10754

Last change on this file since 10754 was 10754, checked in by abeham, 6 years ago

#2174: minor refactorings

File size: 14.5 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.Drawing;
24using System.Linq;
25using HeuristicLab.Analysis;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Data;
29using HeuristicLab.Encodings.BinaryVectorEncoding;
30using HeuristicLab.Encodings.IntegerVectorEncoding;
31using HeuristicLab.Encodings.ParameterVectorEncoding;
32using HeuristicLab.Encodings.PermutationEncoding;
33using HeuristicLab.Encodings.RealVectorEncoding;
34using HeuristicLab.Optimization;
35using HeuristicLab.Parameters;
36using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
37
38namespace HeuristicLab.Problems.Programmable {
39  [Item("Programmable Problem (single-objective)", "Represents a single-objective problem that can be programmed.")]
40  [Creatable("Problems")]
41  [StorableClass]
42  public sealed class SingleObjectiveProgrammableProblem : SingleObjectiveHeuristicOptimizationProblem<ISingleObjectiveProgrammableProblemEvaluator, IParameterVectorCreator>, IStorableContent {
43    public string Filename { get; set; }
44
45    public static new Image StaticItemImage {
46      get { return HeuristicLab.Common.Resources.VSImageLibrary.Script; }
47    }
48
49    public IValueParameter<SingleObjectiveScript> ScriptParameter {
50      get { return (IValueParameter<SingleObjectiveScript>)Parameters["Script"]; }
51    }
52
53    private IValueParameter<IntValue> BinaryVectorLengthParameter {
54      get { return (IValueParameter<IntValue>)Parameters["BinaryVectorLength"]; }
55    }
56
57    private IValueParameter<IntValue> IntegerVectorLengthParameter {
58      get { return (IValueParameter<IntValue>)Parameters["IntegerVectorLength"]; }
59    }
60
61    private IValueParameter<IntMatrix> IntegerVectorBoundsParameter {
62      get { return (IValueParameter<IntMatrix>)Parameters["IntegerVectorBounds"]; }
63    }
64
65    private IValueParameter<IntValue> RealVectorLengthParameter {
66      get { return (IValueParameter<IntValue>)Parameters["RealVectorLength"]; }
67    }
68
69    private IValueParameter<DoubleMatrix> RealVectorBoundsParameter {
70      get { return (IValueParameter<DoubleMatrix>)Parameters["RealVectorBounds"]; }
71    }
72
73    private IValueParameter<IntValue> PermutationLengthParameter {
74      get { return (IValueParameter<IntValue>)Parameters["PermutationLength"]; }
75    }
76
77    private IValueParameter<PermutationType> PermutationTypeParameter {
78      get { return (IValueParameter<PermutationType>)Parameters["PermutationType"]; }
79    }
80
81    [Storable]
82    private ParameterVectorCrossover Crossover { get; set; }
83    [Storable]
84    private ParameterVectorManipulator Manipulator { get; set; }
85
86    [StorableConstructor]
87    private SingleObjectiveProgrammableProblem(bool deserializing) : base(deserializing) { }
88
89    private SingleObjectiveProgrammableProblem(SingleObjectiveProgrammableProblem original, Cloner cloner)
90      : base(original, cloner) {
91      Crossover = cloner.Clone(original.Crossover);
92      Manipulator = cloner.Clone(original.Manipulator);
93      RegisterEventHandlers();
94    }
95    public SingleObjectiveProgrammableProblem()
96      : base(new SingleObjectiveEvaluator(), new ParameterVectorCreater()) {
97      Parameters.Add(new ValueParameter<SingleObjectiveScript>("Script", "Defines the problem.", new SingleObjectiveScript() { Name = ItemName }));
98      Parameters.Add(new OptionalValueParameter<IntValue>("BinaryVectorLength", "The length of the binary vector."));
99      Parameters.Add(new OptionalValueParameter<IntValue>("IntegerVectorLength", "The length of the integer vector."));
100      Parameters.Add(new OptionalValueParameter<IntMatrix>("IntegerVectorBounds", "The bounds of the integer vector."));
101      Parameters.Add(new OptionalValueParameter<IntValue>("RealVectorLength", "The length of the real vector."));
102      Parameters.Add(new OptionalValueParameter<DoubleMatrix>("RealVectorBounds", "The bounds of the real vector."));
103      Parameters.Add(new OptionalValueParameter<IntValue>("PermutationLength", "The length of the permutation."));
104      Parameters.Add(new OptionalValueParameter<PermutationType>("PermutationType", "The type of the permutation."));
105
106      Crossover = new ParameterVectorCrossover();
107      Manipulator = new ParameterVectorManipulator();
108
109      Operators.Add(new BestScopeSolutionAnalyzer());
110      Operators.Add(Evaluator);
111      Operators.Add(SolutionCreator);
112      Operators.Add(Crossover);
113      Operators.Add(Manipulator);
114
115      RegisterEventHandlers();
116    }
117
118    public override IDeepCloneable Clone(Cloner cloner) {
119      return new SingleObjectiveProgrammableProblem(this, cloner);
120    }
121
122    [StorableHook(HookType.AfterDeserialization)]
123    private void AfterDeserialization() {
124      RegisterEventHandlers();
125    }
126
127    private void RegisterEventHandlers() {
128      ScriptParameter.ValueChanged += ScriptParameterOnValueChanged;
129      Crossover.BeforeExecutionOperators.CollectionReset += CrossoverBeforeExecutionOperatorsOnChanged;
130      Crossover.BeforeExecutionOperators.ItemsAdded += CrossoverBeforeExecutionOperatorsOnChanged;
131      Crossover.BeforeExecutionOperators.ItemsReplaced += CrossoverBeforeExecutionOperatorsOnChanged;
132      Manipulator.BeforeExecutionOperators.CollectionReset += ManipulatroBeforeExecutionOperatorsOnChanged;
133      Manipulator.BeforeExecutionOperators.ItemsAdded += ManipulatroBeforeExecutionOperatorsOnChanged;
134      Manipulator.BeforeExecutionOperators.ItemsReplaced += ManipulatroBeforeExecutionOperatorsOnChanged;
135      RegisterScriptInstanceChanges();
136    }
137
138    private void ScriptParameterOnValueChanged(object sender, EventArgs eventArgs) {
139      RegisterScriptInstanceChanges();
140    }
141
142    private void CrossoverBeforeExecutionOperatorsOnChanged(object sender, EventArgs e) {
143      ParameterizeCrossover();
144    }
145
146    private void ManipulatroBeforeExecutionOperatorsOnChanged(object sender, EventArgs e) {
147      ParameterizeManipulator();
148    }
149
150    private void RegisterScriptInstanceChanges() {
151      ScriptParameter.Value.InstanceChanged += ScriptOnInstanceChanged;
152      ScriptParameter.Value.NameChanged += ScriptOnNameChanged;
153    }
154
155    private void ScriptOnNameChanged(object sender, EventArgs eventArgs) {
156      if (sender != ScriptParameter.Value) return;
157      if (Name != ScriptParameter.Value.Name)
158        Name = ScriptParameter.Value.Name;
159    }
160
161    protected override void OnNameChanged() {
162      base.OnNameChanged();
163      if (ScriptParameter.Value.Name != Name)
164        ScriptParameter.Value.Name = Name;
165    }
166
167    private void ScriptOnInstanceChanged(object sender, EventArgs eventArgs) {
168
169      var instance = ScriptParameter.Value.Instance;
170      if (instance == null) return;
171
172      Maximization.Value = instance.IsMaximizationProblem;
173      var vector = instance.GetParametersToOptimize();
174      BinaryVectorLengthParameter.Value = vector.BooleanParameters != null ? new IntValue(vector.BooleanParameters.Length) : null;
175      IntegerVectorLengthParameter.Value = vector.IntegerParameters != null ? new IntValue(vector.IntegerParameters.Length) : null;
176      IntegerVectorBoundsParameter.Value = vector.IntegerBounds;
177      RealVectorLengthParameter.Value = vector.RealParameters != null ? new IntValue(vector.RealParameters.Length) : null;
178      RealVectorBoundsParameter.Value = vector.RealBounds;
179      PermutationLengthParameter.Value = vector.PermutationParameter != null ? new IntValue(vector.PermutationParameter.Length) : null;
180      PermutationTypeParameter.Value = vector.PermutationParameter != null ? new PermutationType(vector.PermutationParameter.PermutationType) : null;
181
182      ((IBinaryVectorCreator)SolutionCreator).LengthParameter.ActualName = BinaryVectorLengthParameter.Name;
183      ((IIntegerVectorCreator)SolutionCreator).LengthParameter.ActualName = IntegerVectorLengthParameter.Name;
184      ((IIntegerVectorCreator)SolutionCreator).BoundsParameter.ActualName = IntegerVectorBoundsParameter.Name;
185      ((IRealVectorCreator)SolutionCreator).LengthParameter.ActualName = RealVectorLengthParameter.Name;
186      ((IRealVectorCreator)SolutionCreator).BoundsParameter.ActualName = RealVectorBoundsParameter.Name;
187      ((IPermutationCreator)SolutionCreator).LengthParameter.ActualName = PermutationLengthParameter.Name;
188      ((IPermutationCreator)SolutionCreator).PermutationTypeParameter.Value = new PermutationType(vector.PermutationParameter != null ? vector.PermutationParameter.PermutationType : PermutationTypes.Absolute);
189
190      if (vector.BooleanParameters != null) {
191        if (!Crossover.BeforeExecutionOperators.Any(x => x is IBinaryVectorCrossover))
192          Crossover.BeforeExecutionOperators.Add(new Encodings.BinaryVectorEncoding.SinglePointCrossover());
193        if (!Manipulator.BeforeExecutionOperators.Any(x => x is IBinaryVectorManipulator))
194          Manipulator.BeforeExecutionOperators.Add(new Encodings.BinaryVectorEncoding.SinglePositionBitflipManipulator());
195      } else {
196        Crossover.BeforeExecutionOperators.RemoveAll(x => x is IBinaryVectorCrossover);
197        Manipulator.BeforeExecutionOperators.RemoveAll(x => x is IBinaryVectorManipulator);
198      }
199
200      if (vector.IntegerParameters != null) {
201        if (!Crossover.BeforeExecutionOperators.Any(x => x is IIntegerVectorCrossover))
202          Crossover.BeforeExecutionOperators.Add(new Encodings.IntegerVectorEncoding.SinglePointCrossover());
203        if (!Manipulator.BeforeExecutionOperators.Any(x => x is IIntegerVectorManipulator))
204          Manipulator.BeforeExecutionOperators.Add(new Encodings.IntegerVectorEncoding.UniformOnePositionManipulator());
205      } else {
206        Crossover.BeforeExecutionOperators.RemoveAll(x => x is IIntegerVectorCrossover);
207        Manipulator.BeforeExecutionOperators.RemoveAll(x => x is IIntegerVectorManipulator);
208      }
209
210      if (vector.RealParameters != null) {
211        if (!Crossover.BeforeExecutionOperators.Any(x => x is IRealVectorCrossover))
212          Crossover.BeforeExecutionOperators.Add(new Encodings.RealVectorEncoding.SinglePointCrossover());
213        if (!Manipulator.BeforeExecutionOperators.Any(x => x is IRealVectorManipulator))
214          Manipulator.BeforeExecutionOperators.Add(new Encodings.RealVectorEncoding.BreederGeneticAlgorithmManipulator());
215      } else {
216        Crossover.BeforeExecutionOperators.RemoveAll(x => x is IRealVectorCrossover);
217        Manipulator.BeforeExecutionOperators.RemoveAll(x => x is IRealVectorManipulator);
218      }
219
220      if (vector.PermutationParameter != null) {
221        if (!Crossover.BeforeExecutionOperators.Any(x => x is IPermutationCrossover))
222          Crossover.BeforeExecutionOperators.Add(new Encodings.PermutationEncoding.OrderCrossover2());
223        if (!Manipulator.BeforeExecutionOperators.Any(x => x is IPermutationManipulator))
224          Manipulator.BeforeExecutionOperators.Add(new Encodings.PermutationEncoding.Swap2Manipulator());
225      } else {
226        Crossover.BeforeExecutionOperators.RemoveAll(x => x is IPermutationCrossover);
227        Manipulator.BeforeExecutionOperators.RemoveAll(x => x is IPermutationManipulator);
228      }
229
230      ParameterizeCrossover();
231      ParameterizeManipulator();
232    }
233
234    private void ParameterizeCrossover() {
235      Crossover.ChildParameter.ActualName = SolutionCreator.ParameterVectorParameter.ActualName;
236      Crossover.ParentsParameter.ActualName = SolutionCreator.ParameterVectorParameter.ActualName;
237
238      foreach (var xo in Crossover.BeforeExecutionOperators.OfType<IBinaryVectorCrossover>()) {
239        xo.ChildParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName;
240        xo.ParentsParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName;
241      }
242      foreach (var xo in Crossover.BeforeExecutionOperators.OfType<IIntegerVectorCrossover>()) {
243        xo.ChildParameter.ActualName = SolutionCreator.IntegerVectorParameter.ActualName;
244        xo.ParentsParameter.ActualName = SolutionCreator.IntegerVectorParameter.ActualName;
245        var bxo = xo as IBoundedIntegerVectorOperator;
246        if (bxo != null) bxo.BoundsParameter.ActualName = IntegerVectorBoundsParameter.Name;
247      }
248      foreach (var xo in Crossover.BeforeExecutionOperators.OfType<IRealVectorCrossover>()) {
249        xo.ChildParameter.ActualName = SolutionCreator.RealVectorParameter.ActualName;
250        xo.ParentsParameter.ActualName = SolutionCreator.RealVectorParameter.ActualName;
251        xo.BoundsParameter.ActualName = RealVectorBoundsParameter.Name;
252      }
253      foreach (var xo in Crossover.BeforeExecutionOperators.OfType<IPermutationCrossover>()) {
254        xo.ChildParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
255        xo.ParentsParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
256      }
257    }
258
259    private void ParameterizeManipulator() {
260      foreach (var ma in Manipulator.BeforeExecutionOperators.OfType<IBinaryVectorManipulator>()) {
261        ma.BinaryVectorParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName;
262      }
263      foreach (var ma in Manipulator.BeforeExecutionOperators.OfType<IIntegerVectorManipulator>()) {
264        ma.IntegerVectorParameter.ActualName = SolutionCreator.IntegerVectorParameter.ActualName;
265        var bma = ma as IBoundedIntegerVectorOperator;
266        if (bma != null) bma.BoundsParameter.ActualName = IntegerVectorBoundsParameter.Name;
267      }
268      foreach (var ma in Manipulator.BeforeExecutionOperators.OfType<IRealVectorManipulator>()) {
269        ma.RealVectorParameter.ActualName = SolutionCreator.RealVectorParameter.ActualName;
270        ma.BoundsParameter.ActualName = RealVectorBoundsParameter.Name;
271      }
272      foreach (var ma in Manipulator.BeforeExecutionOperators.OfType<IPermutationManipulator>()) {
273        ma.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
274      }
275    }
276  }
277}
Note: See TracBrowser for help on using the repository browser.