Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3.0/sources/HeuristicLab.Selection.OffspringSelection/OffspringSelector.cs @ 9928

Last change on this file since 9928 was 302, checked in by gkronber, 16 years ago

merged r301 into the HL3 stable branch (ticket #142)

File size: 7.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 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.Text;
25using HeuristicLab.Core;
26using HeuristicLab.Data;
27
28namespace HeuristicLab.Selection.OffspringSelection {
29  public class OffspringSelector : OperatorBase {
30    public override string Description {
31      get { return @"TODO\r\nOperator description still missing ..."; }
32    }
33
34    public OffspringSelector() {
35      AddVariableInfo(new VariableInfo("SuccessfulChild", "True if the child was successful", typeof(BoolData), VariableKind.In));
36      AddVariableInfo(new VariableInfo("SelectionPressureLimit", "Maximum selection pressure", typeof(DoubleData), VariableKind.In));
37      AddVariableInfo(new VariableInfo("SuccessRatioLimit", "Maximum success ratio", typeof(DoubleData), VariableKind.In));
38      AddVariableInfo(new VariableInfo("SelectionPressure", "Current selection pressure", typeof(DoubleData), VariableKind.New | VariableKind.Out));
39      AddVariableInfo(new VariableInfo("SuccessRatio", "Current success ratio", typeof(DoubleData), VariableKind.New | VariableKind.Out));
40      AddVariableInfo(new VariableInfo("GoodChildren", "Temporarily store successful children", typeof(ItemList<IScope>), VariableKind.New | VariableKind.Out | VariableKind.In | VariableKind.Deleted));
41      AddVariableInfo(new VariableInfo("BadChildren", "Temporarily store unsuccessful children", typeof(ItemList<IScope>), VariableKind.New | VariableKind.Out | VariableKind.In | VariableKind.Deleted));
42    }
43
44    public override IOperation Apply(IScope scope) {
45      double selectionPressureLimit = GetVariableValue<DoubleData>("SelectionPressureLimit", scope, true).Data;
46      double successRatioLimit = GetVariableValue<DoubleData>("SuccessRatioLimit", scope, true).Data;
47
48      IScope parents = scope.SubScopes[0];
49      IScope children = scope.SubScopes[1];
50
51      // retrieve actual selection pressure and success ratio
52      DoubleData selectionPressure = GetVariableValue<DoubleData>("SelectionPressure", scope, false, false);
53      if (selectionPressure == null) {
54        IVariableInfo selectionPressureInfo = GetVariableInfo("SelectionPressure");
55        selectionPressure = new DoubleData(0);
56        if (selectionPressureInfo.Local)
57          AddVariable(new Variable(selectionPressureInfo.ActualName, selectionPressure));
58        else
59          scope.AddVariable(new Variable(scope.TranslateName(selectionPressureInfo.FormalName), selectionPressure));
60      }
61      DoubleData successRatio = GetVariableValue<DoubleData>("SuccessRatio", scope, false, false);
62      if (successRatio == null) {
63        IVariableInfo successRatioInfo = GetVariableInfo("SuccessRatio");
64        successRatio = new DoubleData(0);
65        if (successRatioInfo.Local)
66          AddVariable(new Variable(successRatioInfo.ActualName, successRatio));
67        else
68          scope.AddVariable(new Variable(scope.TranslateName(successRatioInfo.FormalName), successRatio));
69      }
70
71      // retrieve good and bad children
72      ItemList<IScope> goodChildren = GetVariableValue<ItemList<IScope>>("GoodChildren", scope, false, false);
73      if (goodChildren == null) {
74        goodChildren = new ItemList<IScope>();
75        IVariableInfo goodChildrenInfo = GetVariableInfo("GoodChildren");
76        if (goodChildrenInfo.Local)
77          AddVariable(new Variable(goodChildrenInfo.ActualName, goodChildren));
78        else
79          scope.AddVariable(new Variable(scope.TranslateName(goodChildrenInfo.FormalName), goodChildren));
80
81        // no good children available -> first iteration of this generation -> initialize selection pressure
82        selectionPressure.Data = 0;
83      }
84      ItemList<IScope> badChildren = GetVariableValue<ItemList<IScope>>("BadChildren", scope, false, false);
85      if (badChildren == null) {
86        badChildren = new ItemList<IScope>();
87        IVariableInfo badChildrenInfo = GetVariableInfo("BadChildren");
88        if (badChildrenInfo.Local)
89          AddVariable(new Variable(badChildrenInfo.ActualName, badChildren));
90        else
91          scope.AddVariable(new Variable(scope.TranslateName(badChildrenInfo.FormalName), badChildren));
92      }
93
94      // separate new children in good and bad children
95      int goodCount = 0;
96      int badCount = 0;
97      IVariableInfo successfulInfo = GetVariableInfo("SuccessfulChild");
98      while (children.SubScopes.Count > 0) {
99        IScope child = children.SubScopes[0];
100        bool successful = child.GetVariableValue<BoolData>(successfulInfo.FormalName, false).Data;
101        if (successful) {
102          goodCount++;
103          goodChildren.Add(child);
104        } else {
105          badCount++;
106          // only keep the child if we have not filled up the pool or if we reached the
107          // selection pressure limit in which case we have to keep more lucky losers than usual
108          if ((1 - successRatioLimit) * parents.SubScopes.Count > badChildren.Count ||
109            selectionPressure.Data >= selectionPressureLimit) {
110            badChildren.Add(child);
111          }
112        }
113        children.RemoveSubScope(child);
114      }
115
116      // calculate actual selection pressure and success ratio
117      selectionPressure.Data += (goodCount + badCount) / ((double)parents.SubScopes.Count);
118      successRatio.Data = goodChildren.Count / ((double)parents.SubScopes.Count);
119
120      // check if enough children have been generated
121      if (((selectionPressure.Data < selectionPressureLimit) && (successRatio.Data < successRatioLimit)) ||
122          ((goodChildren.Count + badChildren.Count) < parents.SubScopes.Count)) {
123        // more children required -> reduce left and start children generation again
124        scope.RemoveSubScope(parents);
125        scope.RemoveSubScope(children);
126        for (int i = 0; i < parents.SubScopes.Count; i++)
127          scope.AddSubScope(parents.SubScopes[i]);
128
129        return new AtomicOperation(SubOperators[0], scope);
130      } else {
131        // enough children generated
132        while (children.SubScopes.Count < parents.SubScopes.Count) {
133          if (goodChildren.Count > 0) {
134            children.AddSubScope((IScope)goodChildren[0]);
135            goodChildren.RemoveAt(0);
136          } else {
137            children.AddSubScope((IScope)badChildren[0]);
138            badChildren.RemoveAt(0);
139          }
140        }
141
142        // remove good and bad children again
143        IVariableInfo goodChildrenInfo = GetVariableInfo("GoodChildren");
144        if (goodChildrenInfo.Local)
145          RemoveVariable(goodChildrenInfo.ActualName);
146        else
147          scope.RemoveVariable(scope.TranslateName(goodChildrenInfo.FormalName));
148        IVariableInfo badChildrenInfo = GetVariableInfo("BadChildren");
149        if (badChildrenInfo.Local)
150          RemoveVariable(badChildrenInfo.ActualName);
151        else
152          scope.RemoveVariable(scope.TranslateName(badChildrenInfo.FormalName));
153        return null;
154      }
155    }
156  }
157}
Note: See TracBrowser for help on using the repository browser.