Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Algorithms.EvolutionStrategy/3.3/EvolutionStrategy.cs @ 3189

Last change on this file since 3189 was 3189, checked in by abeham, 14 years ago

Prevent starting of algorithm when problem or vital operators are null #933

  • Property svn:mime-type set to application/octet-stream
File size: 43.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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.Linq;
25using HeuristicLab.Core;
26using HeuristicLab.Data;
27using HeuristicLab.Encodings.RealVectorEncoding;
28using HeuristicLab.Operators;
29using HeuristicLab.Optimization;
30using HeuristicLab.Optimization.Operators;
31using HeuristicLab.Parameters;
32using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
33using HeuristicLab.PluginInfrastructure;
34
35namespace HeuristicLab.Algorithms.EvolutionStrategy {
36  /// <summary>
37  /// A standard genetic algorithm.
38  /// </summary>
39  [Item("Evolution Strategy", "An evolution strategy.")]
40  [Creatable("Algorithms")]
41  [StorableClass]
42  public sealed class EvolutionStrategy : EngineAlgorithm {
43    [Storable]
44    private SelfAdaptiveCrossover selfAdaptiveCrossover;
45
46    #region Problem Properties
47    public override Type ProblemType {
48      get { return typeof(ISingleObjectiveProblem); }
49    }
50    public new ISingleObjectiveProblem Problem {
51      get { return (ISingleObjectiveProblem)base.Problem; }
52      set { base.Problem = value; }
53    }
54    #endregion
55
56    #region Parameter Properties
57    private ValueParameter<IntValue> SeedParameter {
58      get { return (ValueParameter<IntValue>)Parameters["Seed"]; }
59    }
60    private ValueParameter<BoolValue> SetSeedRandomlyParameter {
61      get { return (ValueParameter<BoolValue>)Parameters["SetSeedRandomly"]; }
62    }
63    private ValueParameter<IntValue> PopulationSizeParameter {
64      get { return (ValueParameter<IntValue>)Parameters["PopulationSize"]; }
65    }
66    private ValueParameter<IntValue> ParentsPerChildParameter {
67      get { return (ValueParameter<IntValue>)Parameters["ParentsPerChild"]; }
68    }
69    private ValueParameter<IntValue> ChildrenParameter {
70      get { return (ValueParameter<IntValue>)Parameters["Children"]; }
71    }
72    private ValueParameter<IntValue> MaximumGenerationsParameter {
73      get { return (ValueParameter<IntValue>)Parameters["MaximumGenerations"]; }
74    }
75    private ValueParameter<DoubleMatrix> StrategyVectorBoundsParameter {
76      get { return (ValueParameter<DoubleMatrix>)Parameters["StrategyVectorBounds"]; }
77    }
78    private ValueParameter<IntValue> ProblemDimensionParameter {
79      get { return (ValueParameter<IntValue>)Parameters["ProblemDimension"]; }
80    }
81    private ValueParameter<DoubleValue> GeneralLearningRateParameter {
82      get { return (ValueParameter<DoubleValue>)Parameters["GeneralLearningRate"]; }
83    }
84    private ValueParameter<DoubleValue> LearningRateParameter {
85      get { return (ValueParameter<DoubleValue>)Parameters["LearningRate"]; }
86    }
87    private ValueParameter<BoolValue> PlusSelectionParameter {
88      get { return (ValueParameter<BoolValue>)Parameters["PlusSelection"]; }
89    }
90    private ConstrainedValueParameter<IManipulator> MutatorParameter {
91      get { return (ConstrainedValueParameter<IManipulator>)Parameters["Mutator"]; }
92    }
93    private OptionalConstrainedValueParameter<ICrossover> RecombinatorParameter {
94      get { return (OptionalConstrainedValueParameter<ICrossover>)Parameters["Recombinator"]; }
95    }
96    #endregion
97
98    #region Properties
99    public IntValue Seed {
100      get { return SeedParameter.Value; }
101      set { SeedParameter.Value = value; }
102    }
103    public BoolValue SetSeedRandomly {
104      get { return SetSeedRandomlyParameter.Value; }
105      set { SetSeedRandomlyParameter.Value = value; }
106    }
107    public IntValue PopulationSize {
108      get { return PopulationSizeParameter.Value; }
109      set { PopulationSizeParameter.Value = value; }
110    }
111    public IntValue ParentsPerChild {
112      get { return ParentsPerChildParameter.Value; }
113      set { ParentsPerChildParameter.Value = value; }
114    }
115    public IntValue Children {
116      get { return ChildrenParameter.Value; }
117      set { ChildrenParameter.Value = value; }
118    }
119    public IntValue MaximumGenerations {
120      get { return MaximumGenerationsParameter.Value; }
121      set { MaximumGenerationsParameter.Value = value; }
122    }
123    private DoubleMatrix StrategyVectorBounds {
124      get { return StrategyVectorBoundsParameter.Value; }
125      set { StrategyVectorBoundsParameter.Value = value; }
126    }
127    private IntValue ProblemDimension {
128      get { return ProblemDimensionParameter.Value; }
129      set { ProblemDimensionParameter.Value = value; }
130    }
131    private DoubleValue GeneralLearningRate {
132      get { return GeneralLearningRateParameter.Value; }
133      set { GeneralLearningRateParameter.Value = value; }
134    }
135    private DoubleValue LearningRate {
136      get { return LearningRateParameter.Value; }
137      set { LearningRateParameter.Value = value; }
138    }
139    private BoolValue PlusSelection {
140      get { return PlusSelectionParameter.Value; }
141      set { PlusSelectionParameter.Value = value; }
142    }
143    public IManipulator Mutator {
144      get { return MutatorParameter.Value; }
145      set { MutatorParameter.Value = value; }
146    }
147    public ICrossover Recombinator {
148      get { return RecombinatorParameter.Value; }
149      set { RecombinatorParameter.Value = value; }
150    }
151
152    private RandomCreator RandomCreator {
153      get { return (RandomCreator)OperatorGraph.InitialOperator; }
154    }
155    private SolutionsCreator SolutionsCreator {
156      get { return (SolutionsCreator)RandomCreator.Successor; }
157    }
158    private EvolutionStrategyMainLoop MainLoop {
159      get { return (EvolutionStrategyMainLoop)((UniformSequentialSubScopesProcessor)SolutionsCreator.Successor).Successor; }
160    }
161    #endregion
162
163    [StorableConstructor]
164    private EvolutionStrategy(bool deserializing) : base() { }
165    public EvolutionStrategy()
166      : base() {
167      Parameters.Add(new ValueParameter<IntValue>("Seed", "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
168      Parameters.Add(new ValueParameter<BoolValue>("SetSeedRandomly", "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
169      Parameters.Add(new ValueParameter<IntValue>("PopulationSize", "µ (mu) - the size of the population.", new IntValue(5)));
170      Parameters.Add(new ValueParameter<IntValue>("ParentsPerChild", "ρ (rho) - how many parents should be recombined.", new IntValue(1)));
171      Parameters.Add(new ValueParameter<IntValue>("Children", "λ (lambda) - the size of the offspring population.", new IntValue(10)));
172      Parameters.Add(new ValueParameter<IntValue>("MaximumGenerations", "The maximum number of generations which should be processed.", new IntValue(1000)));
173      Parameters.Add(new ValueParameter<DoubleMatrix>("StrategyVectorBounds", "2 column matrix with one row for each dimension specifying upper and lower bound for the strategy vector. If there are less rows than dimensions, the strategy vector will be read in a cycle.", new DoubleMatrix(new double[,] { {0.1, 5} })));
174      Parameters.Add(new ValueParameter<IntValue>("ProblemDimension", "The problem dimension (length of the strategy vector.", new IntValue(1)));
175      Parameters.Add(new ValueParameter<DoubleValue>("GeneralLearningRate", "τ0 (tau0) - the factor with which adjustments in the strategy vector is dampened over all dimensions. Recommendation is to use 1/Sqrt(2*ProblemDimension).", new DoubleValue(0.707106)));
176      Parameters.Add(new ValueParameter<DoubleValue>("LearningRate", "τ (tau) - the factor with which adjustments in the strategy vector are dampened in a single dimension. Recommendation is to use 1/Sqrt(2*Sqrt(ProblemDimension)).", new DoubleValue(0.707106)));
177      Parameters.Add(new ValueParameter<BoolValue>("PlusSelection", "True for plus selection (elitist population), false for comma selection (non-elitist population).", new BoolValue(true)));
178      Parameters.Add(new OptionalConstrainedValueParameter<ICrossover>("Recombinator", "The operator used to cross solutions."));
179      Parameters.Add(new ConstrainedValueParameter<IManipulator>("Mutator", "The operator used to mutate solutions."));
180
181      RandomCreator randomCreator = new RandomCreator();
182      SolutionsCreator solutionsCreator = new SolutionsCreator();
183      UniformSequentialSubScopesProcessor strategyVectorProcessor = new UniformSequentialSubScopesProcessor();
184      UniformRandomRealVectorCreator strategyVectorCreator = new UniformRandomRealVectorCreator();
185      EvolutionStrategyMainLoop mainLoop = new EvolutionStrategyMainLoop();
186      OperatorGraph.InitialOperator = randomCreator;
187
188      randomCreator.RandomParameter.ActualName = "Random";
189      randomCreator.SeedParameter.ActualName = SeedParameter.Name;
190      randomCreator.SeedParameter.Value = null;
191      randomCreator.SetSeedRandomlyParameter.ActualName = SetSeedRandomlyParameter.Name;
192      randomCreator.SetSeedRandomlyParameter.Value = null;
193      randomCreator.Successor = solutionsCreator;
194
195      solutionsCreator.NumberOfSolutionsParameter.ActualName = PopulationSizeParameter.Name;
196      solutionsCreator.Successor = strategyVectorProcessor;
197
198      strategyVectorProcessor.Operator = strategyVectorCreator;
199      strategyVectorProcessor.Successor = mainLoop;
200
201      strategyVectorCreator.BoundsParameter.ActualName = StrategyVectorBoundsParameter.Name;
202      strategyVectorCreator.LengthParameter.ActualName = ProblemDimensionParameter.Name;
203      strategyVectorCreator.RandomParameter.ActualName = "Random";
204      strategyVectorCreator.RealVectorParameter.ActualName = "StrategyVector";
205
206      mainLoop.RandomParameter.ActualName = RandomCreator.RandomParameter.ActualName;
207      mainLoop.PopulationSizeParameter.ActualName = PopulationSizeParameter.Name;
208      mainLoop.ParentsPerChildParameter.ActualName = ParentsPerChildParameter.Name;
209      mainLoop.ChildrenParameter.ActualName = ChildrenParameter.Name;
210      mainLoop.MaximumGenerationsParameter.ActualName = MaximumGenerationsParameter.Name;
211      mainLoop.MutatorParameter.ActualName = MutatorParameter.Name;
212      mainLoop.RecombinatorParameter.ActualName = RecombinatorParameter.Name;
213      mainLoop.ResultsParameter.ActualName = "Results";
214
215      selfAdaptiveCrossover = new SelfAdaptiveCrossover();
216      ParameterizeSelfAdapativeCrossover();
217
218      Initialze();
219    }
220
221    public override IDeepCloneable Clone(Cloner cloner) {
222      EvolutionStrategy clone = (EvolutionStrategy)base.Clone(cloner);
223      clone.Initialze();
224      return clone;
225    }
226
227    protected override void OnPrepared() {
228      base.OnPrepared();
229      if (Engine != null) {
230        if (Problem == null) Engine.Prepare(null);
231      }
232    }
233
234    #region Events
235    protected override void OnProblemChanged() {
236      ParameterizeStochasticOperator(Problem.SolutionCreator);
237      ParameterizeStochasticOperator(Problem.Evaluator);
238      ParameterizeStochasticOperator(Problem.Visualizer);
239      foreach (IOperator op in Problem.Operators) ParameterizeStochasticOperator(op);
240      ParameterizeSolutionsCreator();
241      ParameterizeMainLoop();
242      UpdateRecombinators();
243      UpdateMutators();
244      Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
245      base.OnProblemChanged();
246    }
247    protected override void Problem_SolutionCreatorChanged(object sender, EventArgs e) {
248      ParameterizeStochasticOperator(Problem.SolutionCreator);
249      ParameterizeSolutionsCreator();
250      base.Problem_SolutionCreatorChanged(sender, e);
251    }
252    protected override void Problem_EvaluatorChanged(object sender, EventArgs e) {
253      ParameterizeStochasticOperator(Problem.Evaluator);
254      ParameterizeSolutionsCreator();
255      ParameterizeMainLoop();
256      Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
257      base.Problem_EvaluatorChanged(sender, e);
258    }
259    protected override void Problem_VisualizerChanged(object sender, EventArgs e) {
260      ParameterizeStochasticOperator(Problem.Visualizer);
261      ParameterizeMainLoop();
262      base.Problem_VisualizerChanged(sender, e);
263    }
264    protected override void Problem_OperatorsChanged(object sender, EventArgs e) {
265      foreach (IOperator op in Problem.Operators) ParameterizeStochasticOperator(op);
266      UpdateRecombinators();
267      UpdateMutators();
268      base.Problem_OperatorsChanged(sender, e);
269    }
270    private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
271      ParameterizeMainLoop();
272    }
273    private void PopulationSizeParameter_ValueChanged(object sender, EventArgs e) {
274      PopulationSize.ValueChanged += new EventHandler(PopulationSize_ValueChanged);
275      PopulationSize_ValueChanged(null, EventArgs.Empty);
276    }
277    private void PopulationSize_ValueChanged(object sender, EventArgs e) {
278      if (PopulationSize.Value <= 0) PopulationSize.Value = 1;
279      if (!PlusSelection.Value && Children.Value < PopulationSize.Value)
280        Children.Value = PopulationSize.Value;
281    }
282    private void ParentsPerChildParameter_ValueChanged(object sender, EventArgs e) {
283      ParentsPerChild.ValueChanged += new EventHandler(ParentsPerChild_ValueChanged);
284      ParentsPerChild_ValueChanged(null, EventArgs.Empty);
285    }
286    private void ParentsPerChild_ValueChanged(object sender, EventArgs e) {
287      if (ParentsPerChild.Value < 1 || ParentsPerChild.Value > 1 && RecombinatorParameter.ValidValues.Count == 0)
288        ParentsPerChild.Value = 1;
289      if (ParentsPerChild.Value > 1 && Recombinator == null) Recombinator = RecombinatorParameter.ValidValues.First();
290      if (ParentsPerChild.Value > 1 && ParentsPerChild.Value > PopulationSize.Value)
291        PopulationSize.Value = ParentsPerChild.Value;
292    }
293    private void ChildrenParameter_ValueChanged(object sender, EventArgs e) {
294      Children.ValueChanged += new EventHandler(Children_ValueChanged);
295      Children_ValueChanged(null, EventArgs.Empty);
296    }
297    private void Children_ValueChanged(object sender, EventArgs e) {
298      if (Children.Value <= 0) Children.Value = 1;
299      if (!PlusSelection.Value && Children.Value < PopulationSize.Value)
300        PopulationSize.Value = Children.Value;
301    }
302    private void PlusSelectionParameter_ValueChanged(object sender, EventArgs e) {
303      PlusSelection.ValueChanged += new EventHandler(PlusSelection_ValueChanged);
304      PlusSelection_ValueChanged(null, EventArgs.Empty);
305    }
306    private void PlusSelection_ValueChanged(object sender, EventArgs e) {
307      if (!PlusSelection.Value && Children.Value < PopulationSize.Value)
308        Children.Value = PopulationSize.Value;
309    }
310    private void RecombinatorParameter_ValueChanged(object sender, EventArgs e) {
311      if (Recombinator == null && ParentsPerChild.Value > 1) ParentsPerChild.Value = 1;
312      else if (Recombinator != null && ParentsPerChild.Value == 1) ParentsPerChild.Value = 2;
313      if (Recombinator != null && Mutator is SelfAdaptiveNormalAllPositionsManipulator && !(Recombinator is SelfAdaptiveCrossover)) {
314        if (MutatorParameter.ValidValues.Count > 1)
315          Mutator = MutatorParameter.ValidValues.FirstOrDefault();
316      }
317    }
318    private void MutatorParameter_ValueChanged(object sender, EventArgs e) {
319      if (Mutator is SelfAdaptiveNormalAllPositionsManipulator) {
320        if (Recombinator != null && Recombinator != selfAdaptiveCrossover)
321          Recombinator = selfAdaptiveCrossover;
322      }
323    }
324    private void ProblemDimensionParameter_ValueChanged(object sender, EventArgs e) {
325      ProblemDimension.ValueChanged += new EventHandler(ProblemDimension_ValueChanged);
326      ProblemDimension_ValueChanged(null, EventArgs.Empty);
327    }
328    private void ProblemDimension_ValueChanged(object sender, EventArgs e) {
329      if (ProblemDimension.Value < 1) ProblemDimension.Value = 1;
330      GeneralLearningRate.Value = 1.0 / Math.Sqrt(2 * ProblemDimension.Value);
331      LearningRate.Value = 1.0 / Math.Sqrt(2 * Math.Sqrt(ProblemDimension.Value));
332    }
333    private void selfAdaptiveCrossover_StrategyVectorCrossoverParameter_ValueChanged(object sender, EventArgs e) {
334      ParameterizeSelfAdapativeCrossover();
335    }
336    #endregion
337
338    #region Helpers
339    [StorableHook(HookType.AfterDeserialization)]
340    private void Initialze() {
341      PopulationSizeParameter.ValueChanged += new EventHandler(PopulationSizeParameter_ValueChanged);
342      PopulationSize.ValueChanged += new EventHandler(PopulationSize_ValueChanged);
343      ParentsPerChildParameter.ValueChanged += new EventHandler(ParentsPerChildParameter_ValueChanged);
344      ParentsPerChild.ValueChanged += new EventHandler(ParentsPerChild_ValueChanged);
345      ChildrenParameter.ValueChanged += new EventHandler(ChildrenParameter_ValueChanged);
346      Children.ValueChanged += new EventHandler(Children_ValueChanged);
347      PlusSelectionParameter.ValueChanged += new EventHandler(PlusSelectionParameter_ValueChanged);
348      PlusSelection.ValueChanged += new EventHandler(PlusSelection_ValueChanged);
349      RecombinatorParameter.ValueChanged += new EventHandler(RecombinatorParameter_ValueChanged);
350      MutatorParameter.ValueChanged += new EventHandler(MutatorParameter_ValueChanged);
351      ProblemDimensionParameter.ValueChanged += new EventHandler(ProblemDimensionParameter_ValueChanged);
352      ProblemDimension.ValueChanged += new EventHandler(ProblemDimension_ValueChanged);
353      selfAdaptiveCrossover.StrategyVectorCrossoverParameter.ValueChanged += new EventHandler(selfAdaptiveCrossover_StrategyVectorCrossoverParameter_ValueChanged);
354      if (Problem != null)
355        Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
356    }
357    private void ParameterizeSolutionsCreator() {
358      SolutionsCreator.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
359      SolutionsCreator.SolutionCreatorParameter.ActualName = Problem.SolutionCreatorParameter.Name;
360    }
361    private void ParameterizeMainLoop() {
362      MainLoop.BestKnownQualityParameter.ActualName = Problem.BestKnownQualityParameter.Name;
363      MainLoop.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
364      MainLoop.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
365      MainLoop.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
366      MainLoop.VisualizerParameter.ActualName = Problem.VisualizerParameter.Name;
367      if (Problem.Visualizer != null)
368        MainLoop.VisualizationParameter.ActualName = Problem.Visualizer.VisualizationParameter.ActualName;
369    }
370    private void ParameterizeStochasticOperator(IOperator op) {
371      if (op is IStochasticOperator)
372        ((IStochasticOperator)op).RandomParameter.ActualName = RandomCreator.RandomParameter.ActualName;
373    }
374    private void ParameterizeSelfAdapativeCrossover() {
375      selfAdaptiveCrossover.RandomParameter.ActualName = RandomCreator.RandomParameter.ActualName;
376      selfAdaptiveCrossover.StrategyVectorCrossover.ParentsParameter.ActualName = "StrategyVector";
377      selfAdaptiveCrossover.StrategyVectorCrossover.ChildParameter.ActualName = "StrategyVector";
378      selfAdaptiveCrossover.StrategyVectorCrossover.BoundsParameter.ActualName = "StrategyVectorBounds";
379    }
380    private void UpdateRecombinators() {
381      ICrossover oldRecombinator = RecombinatorParameter.Value;
382      ICrossover oldSARecombinator = selfAdaptiveCrossover.Crossover;
383      selfAdaptiveCrossover.CrossoverParameter.ValidValues.Clear();
384      RecombinatorParameter.ValidValues.Clear();
385      RecombinatorParameter.ValidValues.Add(selfAdaptiveCrossover);
386      foreach (ICrossover recombinator in Problem.Operators.OfType<ICrossover>().OrderBy(x => x.Name)) {
387        RecombinatorParameter.ValidValues.Add(recombinator);
388        selfAdaptiveCrossover.CrossoverParameter.ValidValues.Add(recombinator);
389      }
390      if (oldRecombinator != null) {
391        ICrossover recombinator = RecombinatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldRecombinator.GetType());
392        if (recombinator != null) RecombinatorParameter.Value = recombinator;
393      }
394      if (oldSARecombinator != null) {
395        ICrossover saRecombinator = selfAdaptiveCrossover.CrossoverParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldSARecombinator.GetType());
396        if (saRecombinator != null) selfAdaptiveCrossover.Crossover = saRecombinator;
397      }
398    }
399    private void UpdateMutators() {
400      IManipulator oldMutator = MutatorParameter.Value;
401      MutatorParameter.ValidValues.Clear();
402      foreach (IManipulator mutator in Problem.Operators.OfType<IManipulator>().OrderBy(x => x.Name))
403        MutatorParameter.ValidValues.Add(mutator);
404      if (oldMutator != null) {
405        IManipulator mutator = MutatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMutator.GetType());
406        if (mutator != null) MutatorParameter.Value = mutator;
407      }
408    }
409    #endregion
410  }
411}
Note: See TracBrowser for help on using the repository browser.