Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 3265 was 3265, checked in by swagner, 14 years ago

Continued work on algorithm batch processing (#947).

  • Property svn:mime-type set to application/octet-stream
File size: 42.7 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)((UniformSubScopesProcessor)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      UniformSubScopesProcessor strategyVectorProcessor = new UniformSubScopesProcessor();
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    public override void Prepare() {
228      if (Problem != null) base.Prepare();
229    }
230
231    #region Events
232    protected override void OnProblemChanged() {
233      ParameterizeStochasticOperator(Problem.SolutionCreator);
234      ParameterizeStochasticOperator(Problem.Evaluator);
235      ParameterizeStochasticOperator(Problem.Visualizer);
236      foreach (IOperator op in Problem.Operators) ParameterizeStochasticOperator(op);
237      ParameterizeSolutionsCreator();
238      ParameterizeMainLoop();
239      UpdateRecombinators();
240      UpdateMutators();
241      Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
242      base.OnProblemChanged();
243    }
244    protected override void Problem_SolutionCreatorChanged(object sender, EventArgs e) {
245      ParameterizeStochasticOperator(Problem.SolutionCreator);
246      ParameterizeSolutionsCreator();
247      base.Problem_SolutionCreatorChanged(sender, e);
248    }
249    protected override void Problem_EvaluatorChanged(object sender, EventArgs e) {
250      ParameterizeStochasticOperator(Problem.Evaluator);
251      ParameterizeSolutionsCreator();
252      ParameterizeMainLoop();
253      Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
254      base.Problem_EvaluatorChanged(sender, e);
255    }
256    protected override void Problem_VisualizerChanged(object sender, EventArgs e) {
257      ParameterizeStochasticOperator(Problem.Visualizer);
258      ParameterizeMainLoop();
259      base.Problem_VisualizerChanged(sender, e);
260    }
261    protected override void Problem_OperatorsChanged(object sender, EventArgs e) {
262      foreach (IOperator op in Problem.Operators) ParameterizeStochasticOperator(op);
263      UpdateRecombinators();
264      UpdateMutators();
265      base.Problem_OperatorsChanged(sender, e);
266    }
267    private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
268      ParameterizeMainLoop();
269    }
270    private void PopulationSizeParameter_ValueChanged(object sender, EventArgs e) {
271      PopulationSize.ValueChanged += new EventHandler(PopulationSize_ValueChanged);
272      PopulationSize_ValueChanged(null, EventArgs.Empty);
273    }
274    private void PopulationSize_ValueChanged(object sender, EventArgs e) {
275      if (PopulationSize.Value <= 0) PopulationSize.Value = 1;
276      if (!PlusSelection.Value && Children.Value < PopulationSize.Value)
277        Children.Value = PopulationSize.Value;
278    }
279    private void ParentsPerChildParameter_ValueChanged(object sender, EventArgs e) {
280      ParentsPerChild.ValueChanged += new EventHandler(ParentsPerChild_ValueChanged);
281      ParentsPerChild_ValueChanged(null, EventArgs.Empty);
282    }
283    private void ParentsPerChild_ValueChanged(object sender, EventArgs e) {
284      if (ParentsPerChild.Value < 1 || ParentsPerChild.Value > 1 && RecombinatorParameter.ValidValues.Count == 0)
285        ParentsPerChild.Value = 1;
286      if (ParentsPerChild.Value > 1 && Recombinator == null) Recombinator = RecombinatorParameter.ValidValues.First();
287      if (ParentsPerChild.Value > 1 && ParentsPerChild.Value > PopulationSize.Value)
288        PopulationSize.Value = ParentsPerChild.Value;
289    }
290    private void ChildrenParameter_ValueChanged(object sender, EventArgs e) {
291      Children.ValueChanged += new EventHandler(Children_ValueChanged);
292      Children_ValueChanged(null, EventArgs.Empty);
293    }
294    private void Children_ValueChanged(object sender, EventArgs e) {
295      if (Children.Value <= 0) Children.Value = 1;
296      if (!PlusSelection.Value && Children.Value < PopulationSize.Value)
297        PopulationSize.Value = Children.Value;
298    }
299    private void PlusSelectionParameter_ValueChanged(object sender, EventArgs e) {
300      PlusSelection.ValueChanged += new EventHandler(PlusSelection_ValueChanged);
301      PlusSelection_ValueChanged(null, EventArgs.Empty);
302    }
303    private void PlusSelection_ValueChanged(object sender, EventArgs e) {
304      if (!PlusSelection.Value && Children.Value < PopulationSize.Value)
305        Children.Value = PopulationSize.Value;
306    }
307    private void RecombinatorParameter_ValueChanged(object sender, EventArgs e) {
308      if (Recombinator == null && ParentsPerChild.Value > 1) ParentsPerChild.Value = 1;
309      else if (Recombinator != null && ParentsPerChild.Value == 1) ParentsPerChild.Value = 2;
310      if (Recombinator != null && Mutator is NormalAllPositionsManipulator && !(Recombinator is SelfAdaptiveCrossover)) {
311        if (MutatorParameter.ValidValues.Count > 1)
312          Mutator = MutatorParameter.ValidValues.FirstOrDefault();
313      }
314    }
315    private void MutatorParameter_ValueChanged(object sender, EventArgs e) {
316      if (Mutator is NormalAllPositionsManipulator) {
317        if (Recombinator != null && Recombinator != selfAdaptiveCrossover)
318          Recombinator = selfAdaptiveCrossover;
319      }
320    }
321    private void ProblemDimensionParameter_ValueChanged(object sender, EventArgs e) {
322      ProblemDimension.ValueChanged += new EventHandler(ProblemDimension_ValueChanged);
323      ProblemDimension_ValueChanged(null, EventArgs.Empty);
324    }
325    private void ProblemDimension_ValueChanged(object sender, EventArgs e) {
326      if (ProblemDimension.Value < 1) ProblemDimension.Value = 1;
327      GeneralLearningRate.Value = 1.0 / Math.Sqrt(2 * ProblemDimension.Value);
328      LearningRate.Value = 1.0 / Math.Sqrt(2 * Math.Sqrt(ProblemDimension.Value));
329    }
330    private void selfAdaptiveCrossover_StrategyVectorCrossoverParameter_ValueChanged(object sender, EventArgs e) {
331      ParameterizeSelfAdapativeCrossover();
332    }
333    #endregion
334
335    #region Helpers
336    [StorableHook(HookType.AfterDeserialization)]
337    private void Initialze() {
338      PopulationSizeParameter.ValueChanged += new EventHandler(PopulationSizeParameter_ValueChanged);
339      PopulationSize.ValueChanged += new EventHandler(PopulationSize_ValueChanged);
340      ParentsPerChildParameter.ValueChanged += new EventHandler(ParentsPerChildParameter_ValueChanged);
341      ParentsPerChild.ValueChanged += new EventHandler(ParentsPerChild_ValueChanged);
342      ChildrenParameter.ValueChanged += new EventHandler(ChildrenParameter_ValueChanged);
343      Children.ValueChanged += new EventHandler(Children_ValueChanged);
344      PlusSelectionParameter.ValueChanged += new EventHandler(PlusSelectionParameter_ValueChanged);
345      PlusSelection.ValueChanged += new EventHandler(PlusSelection_ValueChanged);
346      RecombinatorParameter.ValueChanged += new EventHandler(RecombinatorParameter_ValueChanged);
347      MutatorParameter.ValueChanged += new EventHandler(MutatorParameter_ValueChanged);
348      ProblemDimensionParameter.ValueChanged += new EventHandler(ProblemDimensionParameter_ValueChanged);
349      ProblemDimension.ValueChanged += new EventHandler(ProblemDimension_ValueChanged);
350      selfAdaptiveCrossover.StrategyVectorCrossoverParameter.ValueChanged += new EventHandler(selfAdaptiveCrossover_StrategyVectorCrossoverParameter_ValueChanged);
351      if (Problem != null)
352        Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
353    }
354    private void ParameterizeSolutionsCreator() {
355      SolutionsCreator.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
356      SolutionsCreator.SolutionCreatorParameter.ActualName = Problem.SolutionCreatorParameter.Name;
357    }
358    private void ParameterizeMainLoop() {
359      MainLoop.BestKnownQualityParameter.ActualName = Problem.BestKnownQualityParameter.Name;
360      MainLoop.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
361      MainLoop.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
362      MainLoop.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
363      MainLoop.VisualizerParameter.ActualName = Problem.VisualizerParameter.Name;
364      if (Problem.Visualizer != null)
365        MainLoop.VisualizationParameter.ActualName = Problem.Visualizer.VisualizationParameter.ActualName;
366    }
367    private void ParameterizeStochasticOperator(IOperator op) {
368      if (op is IStochasticOperator)
369        ((IStochasticOperator)op).RandomParameter.ActualName = RandomCreator.RandomParameter.ActualName;
370    }
371    private void ParameterizeSelfAdapativeCrossover() {
372      selfAdaptiveCrossover.RandomParameter.ActualName = RandomCreator.RandomParameter.ActualName;
373      selfAdaptiveCrossover.StrategyVectorCrossover.ParentsParameter.ActualName = "StrategyVector";
374      selfAdaptiveCrossover.StrategyVectorCrossover.ChildParameter.ActualName = "StrategyVector";
375      selfAdaptiveCrossover.StrategyVectorCrossover.BoundsParameter.ActualName = "StrategyVectorBounds";
376    }
377    private void UpdateRecombinators() {
378      ICrossover oldRecombinator = RecombinatorParameter.Value;
379      ICrossover oldSARecombinator = selfAdaptiveCrossover.Crossover;
380      selfAdaptiveCrossover.CrossoverParameter.ValidValues.Clear();
381      RecombinatorParameter.ValidValues.Clear();
382      RecombinatorParameter.ValidValues.Add(selfAdaptiveCrossover);
383      foreach (ICrossover recombinator in Problem.Operators.OfType<ICrossover>().OrderBy(x => x.Name)) {
384        RecombinatorParameter.ValidValues.Add(recombinator);
385        selfAdaptiveCrossover.CrossoverParameter.ValidValues.Add(recombinator);
386      }
387      if (oldRecombinator != null) {
388        ICrossover recombinator = RecombinatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldRecombinator.GetType());
389        if (recombinator != null) RecombinatorParameter.Value = recombinator;
390      }
391      if (oldSARecombinator != null) {
392        ICrossover saRecombinator = selfAdaptiveCrossover.CrossoverParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldSARecombinator.GetType());
393        if (saRecombinator != null) selfAdaptiveCrossover.Crossover = saRecombinator;
394      }
395    }
396    private void UpdateMutators() {
397      IManipulator oldMutator = MutatorParameter.Value;
398      MutatorParameter.ValidValues.Clear();
399      foreach (IManipulator mutator in Problem.Operators.OfType<IManipulator>().OrderBy(x => x.Name))
400        MutatorParameter.ValidValues.Add(mutator);
401      if (oldMutator != null) {
402        IManipulator mutator = MutatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMutator.GetType());
403        if (mutator != null) MutatorParameter.Value = mutator;
404      }
405    }
406    #endregion
407  }
408}
Note: See TracBrowser for help on using the repository browser.