Free cookie consent management tool by TermsFeed Policy Generator

source: branches/Operator Architecture Refactoring/HeuristicLab.Selection.OffspringSelection/3.3/OffspringSelector.cs @ 2584

Last change on this file since 2584 was 1530, checked in by gkronber, 16 years ago

Moved source files of plugins Hive ... Visualization.Test into version-specific sub-folders. #576

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