Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Selection.OffspringSelection/OffspringAnalyzer.cs @ 1352

Last change on this file since 1352 was 1157, checked in by vdorfer, 16 years ago

Created API documentation for HeuristicLab.IntVector namespace and changed some comments in HeuristicLab.Random and HeuristicLab.Selection.Offspring namespace(#331)

File size: 7.2 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  /// Analyzes the offspring in a given scope whether it is successful or not.
31  /// </summary>
32  public class OffspringAnalyzer : 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="OffspringAnalyzer"/> with six variable infos
40    /// (<c>Maximization</c>, <c>Quality</c>, <c>ParentQualities</c>, <c>SuccessfulChild</c>,
41    /// <c>ComparisonFactor</c> and <c>ParentsCount</c>).
42    /// </summary>
43    public OffspringAnalyzer() {
44      AddVariableInfo(new VariableInfo("Maximization", "Problem is a maximization problem", typeof(BoolData), VariableKind.In));
45      AddVariableInfo(new VariableInfo("Quality", "Quality value", typeof(DoubleData), VariableKind.In));
46      AddVariableInfo(new VariableInfo("ParentQualities", "Temporarily store parent qualities", typeof(DoubleArrayData), VariableKind.New | VariableKind.Out | VariableKind.In | VariableKind.Deleted));
47      AddVariableInfo(new VariableInfo("SuccessfulChild", "True if the child was successful", typeof(BoolData), VariableKind.New));
48
49      VariableInfo compFactorInfo = new VariableInfo("ComparisonFactor", "Factor for comparing the quality of a child with the qualities of its parents (0 = better than worst parent, 1 = better than best parent)", typeof(DoubleData), VariableKind.In);
50      compFactorInfo.Local = true;
51      AddVariableInfo(compFactorInfo);
52      AddVariable(new Variable("ComparisonFactor", new DoubleData(0.5)));
53      VariableInfo parentCount = new VariableInfo("ParentsCount", "How many parents created the offspring", typeof(IntData), VariableKind.In);
54      parentCount.Local = true;
55      AddVariableInfo(parentCount);
56      AddVariable(new Variable("ParentsCount", new IntData(2)));
57    }
58
59    /// <summary>
60    /// Analyzes the offspring in the given scope whether the children are successful or not.
61    /// </summary>
62    /// <exception cref="InvalidOperationException">Thrown when <c>ParentsCount</c> smaller than 1.</exception>
63    /// <exception cref="InvalidOperationException">Thrown when the number of children is not constant or
64    /// smaller than 1.</exception>
65    /// <param name="scope">The scope whose offspring should be analyzed.</param>
66    /// <returns>The next operation or <c>null</c>.</returns>
67    public override IOperation Apply(IScope scope) {
68      bool maximize = GetVariableValue<BoolData>("Maximization", scope, true).Data;
69      double compFact = GetVariableValue<DoubleData>("ComparisonFactor", scope, true).Data;
70      int parentsCount = GetVariableValue<IntData>("ParentsCount", scope, true).Data;
71      if (parentsCount < 1) throw new InvalidOperationException("OffspringAnalyzer: ParentsCount must be >= 1");
72
73      DoubleArrayData qualities = GetVariableValue<DoubleArrayData>("ParentQualities", scope, false, false);
74      if (qualities == null) {
75        // fetch and store parent qualities
76        IVariableInfo qualityInfo = GetVariableInfo("Quality");
77        double[] qualitiesArray = new double[scope.SubScopes.Count];
78        for (int i = 0; i < qualitiesArray.Length; i++)
79          qualitiesArray[i] = scope.SubScopes[i].GetVariableValue<DoubleData>(qualityInfo.FormalName, false).Data;
80        qualities = new DoubleArrayData(qualitiesArray);
81        IVariableInfo parentQualitiesInfo = GetVariableInfo("ParentQualities");
82        if (parentQualitiesInfo.Local)
83          AddVariable(new Variable(parentQualitiesInfo.ActualName, qualities));
84        else
85          scope.AddVariable(new Variable(scope.TranslateName(parentQualitiesInfo.FormalName), qualities));
86
87        CompositeOperation next = new CompositeOperation();
88        next.AddOperation(new AtomicOperation(SubOperators[0], scope));
89        next.AddOperation(new AtomicOperation(this, scope));
90        return next;
91      } else {
92        int crossoverEvents = qualities.Data.Length / parentsCount;
93        int childrenPerCrossoverEvent = scope.SubScopes.Count / crossoverEvents;
94        if (scope.SubScopes.Count % crossoverEvents != 0 ||
95          childrenPerCrossoverEvent < 1) throw new InvalidOperationException("OffspringAnalyzer: The number of children per crossover event has to be constant and >= 1");
96        // analyze offspring of all crossoverEvents
97        for (int i = 0; i < crossoverEvents; i++) {
98          double worstParent = double.MaxValue; // lowest quality parent
99          double bestParent = double.MinValue; // highest quality parent
100          for (int y = 0; y < parentsCount; y++) {
101            if (qualities.Data[i * parentsCount + y] < worstParent) worstParent = qualities.Data[i * parentsCount + y];
102            if (qualities.Data[i * parentsCount + y] > bestParent) bestParent = qualities.Data[i * parentsCount + y];
103          }
104          for (int j = 0; j < childrenPerCrossoverEvent; j++) {
105            IVariableInfo qualityInfo = GetVariableInfo("Quality");
106            double child = scope.SubScopes[i * childrenPerCrossoverEvent + j].GetVariableValue<DoubleData>(qualityInfo.FormalName, false).Data;
107            double threshold;
108
109            if (!maximize)
110              threshold = bestParent + (worstParent - bestParent) * compFact;
111            else
112              threshold = worstParent + (bestParent - worstParent) * compFact;
113
114            IVariableInfo successfulInfo = GetVariableInfo("SuccessfulChild");
115            BoolData successful;
116            if (((!maximize) && (child < threshold)) ||
117                ((maximize) && (child > threshold)))
118              successful = new BoolData(true);
119            else
120              successful = new BoolData(false);
121            scope.SubScopes[i * childrenPerCrossoverEvent + j].AddVariable(new Variable(scope.TranslateName(successfulInfo.FormalName), successful));
122          }
123        }
124
125        // remove parent qualities again
126        IVariableInfo parentQualitiesInfo = GetVariableInfo("ParentQualities");
127        if (parentQualitiesInfo.Local)
128          RemoveVariable(parentQualitiesInfo.ActualName);
129        else
130          scope.RemoveVariable(scope.TranslateName(parentQualitiesInfo.FormalName));
131
132        return null;
133      }
134    }
135  }
136}
Note: See TracBrowser for help on using the repository browser.