Free cookie consent management tool by TermsFeed Policy Generator

source: addons/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Selector/LexicaseSelector.cs @ 17603

Last change on this file since 17603 was 15366, checked in by pkimmesw, 7 years ago

#2665 Solution Cleanup

File size: 5.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 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
22namespace HeuristicLab.Problems.ProgramSynthesis.Push.Selector {
23  using System;
24  using System.Collections.Generic;
25  using System.Linq;
26
27  using HeuristicLab.Common;
28  using HeuristicLab.Core;
29  using HeuristicLab.Data;
30  using HeuristicLab.Parameters;
31  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
32  using HeuristicLab.Problems.ProgramSynthesis.Push.Problem;
33  using HeuristicLab.Random;
34  using HeuristicLab.Selection;
35
36  /// <summary>
37  /// A lexicase selection operator which considers all successful evaluated training cases for selection.
38  /// </summary>
39  [Item("LexicaseSelector", "A lexicase selection operator which considers all successful evaluated training cases for selection.")]
40  [StorableClass]
41  public sealed class LexicaseSelector : StochasticSingleObjectiveSelector, ICaseSingleObjectiveSelector {
42    public ILookupParameter<ItemArray<DoubleArray>> CaseQualitiesParameter
43    {
44      get { return (ILookupParameter<ItemArray<DoubleArray>>)Parameters[IntegerVectorPushProblem.CaseQualitiesScopeParameterName]; }
45    }
46
47    [StorableConstructor]
48    private LexicaseSelector(bool deserializing) : base(deserializing) { }
49    private LexicaseSelector(LexicaseSelector original, Cloner cloner) : base(original, cloner) { }
50    public override IDeepCloneable Clone(Cloner cloner) {
51      return new LexicaseSelector(this, cloner);
52    }
53
54    public LexicaseSelector() {
55      Parameters.Add(new ScopeTreeLookupParameter<DoubleArray>(
56        IntegerVectorPushProblem.CaseQualitiesScopeParameterName,
57        "The quality of every single training case for each individual."));
58    }
59
60
61    protected override IScope[] Select(List<IScope> scopes) {
62      var count = NumberOfSelectedSubScopesParameter.ActualValue.Value;
63      var copy = CopySelectedParameter.Value.Value;
64      var random = RandomParameter.ActualValue;
65      var maximization = MaximizationParameter.ActualValue.Value;
66      var caseQualities = CaseQualitiesParameter.ActualValue.ToList();
67
68      var selected = Apply(
69        scopes,
70        count,
71        copy,
72        maximization,
73        random,
74        caseQualities);
75
76      return selected;
77    }
78
79    public static IScope[] Apply(
80      List<IScope> scopes,
81      int count,
82      bool copy,
83      bool maximization,
84      IRandom random,
85      List<DoubleArray> caseQualities) {
86
87      for (var i = 0; i < caseQualities.Count; i++) {
88        if (caseQualities[i].Length == 0) {
89          scopes.RemoveAt(i);
90          caseQualities.RemoveAt(i);
91        }
92      }
93
94      var qualitiesLength = caseQualities[0].Length;
95
96      if (caseQualities.Any(x => x.Length != qualitiesLength)) {
97        throw new ArgumentException("Not all case qualities have the same length");
98      }
99
100      var selected = new IScope[count];
101
102      var candidates = new List<int>(caseQualities.Count);
103      for (var i = 0; i < caseQualities.Count; i++) candidates.Add(i);
104
105      var orderSource = new List<int>(qualitiesLength);
106      for (var i = 0; i < qualitiesLength; i++) orderSource.Add(i);
107
108      for (var i = 0; i < count; i++) {
109        var index = LexicaseSelect(
110          caseQualities,
111          candidates,
112          orderSource.Shuffle(random),
113          random,
114          maximization);
115
116        if (copy) {
117          selected[i] = (IScope)scopes[index].Clone();
118        } else {
119          selected[i] = scopes[index];
120          scopes.RemoveAt(index);
121          caseQualities.RemoveAt(index);
122        }
123      }
124
125      return selected;
126    }
127
128    private static int LexicaseSelect(
129      List<DoubleArray> caseQualities,
130      List<int> candidates,
131      IEnumerable<int> order,
132      IRandom random,
133      bool maximization) {
134
135      foreach (var curCase in order) {
136        var nextCandidates = new List<int>();
137
138        var best = maximization
139          ? double.NegativeInfinity
140          : double.PositiveInfinity;
141
142        for (var i = 0; i < candidates.Count; i++) {
143          var candidate = candidates[i];
144          var caseQuality = caseQualities[candidate][curCase];
145
146          if (caseQuality.IsAlmost(best)) {
147            // if the individuals is as good as the best one, add it
148            nextCandidates.Add(candidate);
149          } else if (
150             (maximization && (caseQuality > best)) ||
151             (!maximization && (caseQuality < best))) {
152            // if the individual is better than the best one, remove all previous candidates and add the new one
153            nextCandidates.Clear();
154            nextCandidates.Add(candidate);
155            // also set the next best quality value
156            best = caseQuality;
157          }
158          // else {do nothing}
159        }
160
161        if (nextCandidates.Count == 1) {
162          return nextCandidates[0];
163        }
164
165        if (nextCandidates.Count < 1) {
166          return candidates.SampleRandom(random);
167        }
168
169        candidates = nextCandidates;
170      }
171
172      return candidates.Count == 1
173        ? candidates[0]
174        : candidates.SampleRandom(random);
175    }
176  }
177}
Note: See TracBrowser for help on using the repository browser.