Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Optimization.Operators/3.3/OffspringSelector.cs @ 3378

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

Added draft of OSGA #976
MainLoop somewhat finished, wiring not

File size: 8.4 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.Operators;
28using HeuristicLab.Parameters;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30
31namespace HeuristicLab.Optimization.Operators {
32  [Item("OffspringSelector", "Selects among the offspring population those that are designated successful and discards the unsuccessful offspring, except for some lucky losers.")]
33  [StorableClass]
34  public class OffspringSelector : SingleSuccessorOperator {
35
36    public ValueLookupParameter<IntValue> PopulationSizeParameter {
37      get { return (ValueLookupParameter<IntValue>)Parameters["PopulationSize"]; }
38    }
39    public ValueLookupParameter<DoubleValue> MaximumSelectionPressureParameter {
40      get { return (ValueLookupParameter<DoubleValue>)Parameters["MaximiumSelectionPressure"]; }
41    }
42    public ValueLookupParameter<DoubleValue> SuccessRatioParameter {
43      get { return (ValueLookupParameter<DoubleValue>)Parameters["SuccessRatio"]; }
44    }
45    public LookupParameter<DoubleValue> SelectionPressureParameter {
46      get { return (ValueLookupParameter<DoubleValue>)Parameters["SelectionPressure"]; }
47    }
48    public LookupParameter<DoubleValue> CurrentSuccessRatioParameter {
49      get { return (LookupParameter<DoubleValue>)Parameters["CurrentSuccessRatio"]; }
50    }
51    public SubScopesLookupParameter<BoolValue> SuccessfulOffspringParameter {
52      get { return (SubScopesLookupParameter<BoolValue>)Parameters["SuccessfulOffspring"]; }
53    }
54    public LookupParameter<ItemList<IScope>> WinnersParameter {
55      get { return (LookupParameter<ItemList<IScope>>)Parameters["Winners"]; }
56    }
57    public LookupParameter<ItemList<IScope>> LuckyLosersParameter {
58      get { return (LookupParameter<ItemList<IScope>>)Parameters["LuckyLosers"]; }
59    }
60    public OperatorParameter OffspringCreatorParameter {
61      get { return (OperatorParameter)Parameters["OffspringCreator"]; }
62    }
63
64    public IOperator OffspringCreator {
65      get { return OffspringCreatorParameter.Value; }
66      set { OffspringCreatorParameter.Value = value; }
67    }
68
69    public OffspringSelector()
70      : base() {
71      Parameters.Add(new ValueLookupParameter<IntValue>("PopulationSize", "The number of offspring to create."));
72      Parameters.Add(new ValueLookupParameter<DoubleValue>("MaximumSelectionPressure", "The maximum selection pressure which prematurely terminates the offspring selection step."));
73      Parameters.Add(new ValueLookupParameter<DoubleValue>("SuccessRatio", "The ratio of successful offspring that has to be produced."));
74      Parameters.Add(new ValueLookupParameter<DoubleValue>("SelectionPressure", "The amount of selection pressure currently necessary to fulfill the success ratio."));
75      Parameters.Add(new ValueLookupParameter<DoubleValue>("CurrentSuccessRatio", "The current success ratio indicates how much of the successful offspring have already been generated."));
76      Parameters.Add(new SubScopesLookupParameter<BoolValue>("SuccessfulOffspring", "True if the offspring was successful, otherwise false."));
77      Parameters.Add(new LookupParameter<ItemList<IScope>>("Winners", "Temporary store of the successful offspring."));
78      Parameters.Add(new LookupParameter<ItemList<IScope>>("LuckyLosers", "Temporary store of the lucky losers."));
79      Parameters.Add(new OperatorParameter("OffspringCreator", "The operator used to create new offspring."));
80    }
81
82    public override IOperation Apply() {
83      int populationSize = PopulationSizeParameter.ActualValue.Value;
84      double maxSelPress = MaximumSelectionPressureParameter.ActualValue.Value;
85      double successRatio = SuccessRatioParameter.ActualValue.Value;
86      IScope scope = ExecutionContext.Scope;
87      IScope parents = scope.SubScopes[0];
88      IScope children = scope.SubScopes[1];
89
90      // retrieve actual selection pressure and success ratio
91      DoubleValue selectionPressure = SelectionPressureParameter.ActualValue;
92      if (selectionPressure == null) {
93        selectionPressure = new DoubleValue(0);
94        SelectionPressureParameter.ActualValue = selectionPressure;
95      }
96      DoubleValue currentSuccessRatio = CurrentSuccessRatioParameter.ActualValue;
97      if (currentSuccessRatio == null) {
98        currentSuccessRatio = new DoubleValue(0);
99        CurrentSuccessRatioParameter.ActualValue = currentSuccessRatio;
100      }
101
102      // retrieve winners and lucky losers
103      ItemList<IScope> winners = WinnersParameter.ActualValue;
104      if (winners == null) {
105        winners = new ItemList<IScope>();
106        WinnersParameter.ActualValue = winners;
107        selectionPressure.Value = 0; // initialize selection pressure for this round
108        currentSuccessRatio.Value = 0; // initialize current success ratio for this round
109      }
110      ItemList<IScope> luckyLosers = LuckyLosersParameter.ActualValue;
111      if (luckyLosers == null) {
112        luckyLosers = new ItemList<IScope>();
113        LuckyLosersParameter.ActualValue = luckyLosers;
114      }
115
116      // separate new offspring in winners and lucky losers, the unlucky losers are discarded, sorry guys
117      int winnersCount = 0;
118      int losersCount = 0;
119      ItemArray<BoolValue> offspring = SuccessfulOffspringParameter.ActualValue;
120      for (int i = 0; i < offspring.Length; i++) {
121        IScope child = children.SubScopes[0];
122        if (offspring[i].Value) {
123          winnersCount++;
124          winners.Add(child);
125        } else {
126          losersCount++;
127          // only keep the offspring if we have not filled up the pool or if we reached the
128          // selection pressure limit in which case we have to keep more lucky losers than usual
129          if ((1 - successRatio) * populationSize > luckyLosers.Count ||
130            selectionPressure.Value >= maxSelPress) {
131            luckyLosers.Add(child);
132          }
133        }
134        children.SubScopes.RemoveAt(0);
135      }
136
137      // calculate actual selection pressure and success ratio
138      selectionPressure.Value += (winnersCount + losersCount) / ((double)populationSize);
139      currentSuccessRatio.Value = winners.Count / ((double)populationSize);
140
141      // check if enough children have been generated
142      if (((selectionPressure.Value < maxSelPress) && (currentSuccessRatio.Value < successRatio)) ||
143          ((winners.Count + luckyLosers.Count) < populationSize)) {
144        // more children required -> reduce left and start children generation again
145        scope.SubScopes.Remove(parents);
146        scope.SubScopes.Remove(children);
147        for (int i = 0; i < parents.SubScopes.Count; i++)
148          scope.SubScopes.Add(parents.SubScopes[i]);
149
150        IOperator moreOffspring = OffspringCreatorParameter.ActualValue as IOperator;
151        if (moreOffspring == null) throw new InvalidOperationException(Name + ": More offspring are required, but no operator specified for creating them.");
152        return ExecutionContext.CreateOperation(moreOffspring);
153      } else {
154        // enough children generated
155        while (children.SubScopes.Count < populationSize) {
156          if (winners.Count > 0) {
157            children.SubScopes.Add((IScope)winners[0]);
158            winners.RemoveAt(0);
159          } else {
160            children.SubScopes.Add((IScope)luckyLosers[0]);
161            luckyLosers.RemoveAt(0);
162          }
163        }
164
165        scope.Variables.Remove(WinnersParameter.ActualName);
166        scope.Variables.Remove(LuckyLosersParameter.ActualName);
167        return base.Apply();
168      }
169    }
170  }
171}
Note: See TracBrowser for help on using the repository browser.