Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
08/31/17 18:59:39 (7 years ago)
Author:
pkimmesw
Message:

#2665 Fixed Lexicase

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Selector/LexicaseSelector.cs

    r15289 r15345  
    3030  using HeuristicLab.Parameters;
    3131  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    32   using HeuristicLab.Problems.ProgramSynthesis.Push.Extensions;
    3332  using HeuristicLab.Problems.ProgramSynthesis.Push.Problem;
     33  using HeuristicLab.Random;
    3434  using HeuristicLab.Selection;
    35   using Random;
    3635
    3736  /// <summary>
     
    5958    }
    6059
    61     protected override IScope[] Select(List<IScope> population) {
     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
     67      //var qualities = QualityParameter.ActualValue;
     68      //.Where(x => IsValidQuality(x.Value))
     69      //.Select(x => x.Value)
     70      //.ToList();
     71
     72      var caseQualities = CaseQualitiesParameter.ActualValue.ToList();
     73
    6274      var selected = Apply(
    63         population,
    64         NumberOfSelectedSubScopesParameter.ActualValue.Value,
    65         CopySelectedParameter.Value.Value,
    66         MaximizationParameter.ActualValue.Value,
    67         RandomParameter.ActualValue,
    68         CaseQualitiesParameter.ActualValue);
     75        scopes,
     76        count,
     77        copy,
     78        maximization,
     79        random,
     80        caseQualities);
    6981
    7082      return selected;
     
    7284
    7385    public static IScope[] Apply(
    74       List<IScope> population,
     86      List<IScope> scopes,
    7587      int count,
    7688      bool copy,
    7789      bool maximization,
    7890      IRandom random,
    79       ItemArray<DoubleArray> caseQualities) {
     91      List<DoubleArray> caseQualities) {
     92
     93      for (var i = 0; i < caseQualities.Count; i++) {
     94        if (caseQualities[i].Length == 0) {
     95          scopes.RemoveAt(i);
     96          caseQualities.RemoveAt(i);
     97        }
     98      }
     99
     100      if (caseQualities.Any(x => x.Length != caseQualities[0].Length)) {
     101        throw new ArgumentException("Not all case qualities have the same length");
     102      }
     103
    80104      var selected = new IScope[count];
    81       var repeats = (int)Math.Ceiling(count / (double)population.Count);
    82       var caseCount = caseQualities[0].Length;
    83       var source = Enumerable.Range(0, population.Count).ToList();
     105      var candidates = Enumerable.Range(0, caseQualities.Count).ToList();
     106      var orderSource = Enumerable.Range(0, caseQualities[0].Length).ToList();
    84107
    85       for (var k = 0; k < repeats; k++) {
    86         // The fitness cases are shuffled.
    87         var fitnessCaseIndexes = Enumerable.Range(0, caseCount).Shuffle(random).ToList();
     108      for (var i = 0; i < count; i++) {
     109        var index = LexicaseSelect(
     110          caseQualities,
     111          candidates,
     112          orderSource.Shuffle(random),
     113          random,
     114          maximization);
    88115
    89         // copy list if required
    90         var pool = repeats == 1 ? source : new List<int>(source);
    91         var countLimit = Math.Min(count - k * population.Count, population.Count);
    92 
    93         for (var i = 0; i < countLimit; i++) {
    94           var candidates = pool;
    95 
    96           for (var j = 0; j < fitnessCaseIndexes.Count && candidates.Count > 1; j++) {
    97             candidates = GetBestIndividuals(maximization, caseQualities, candidates, fitnessCaseIndexes[j]);
    98           }
    99 
    100           /*  If only one individual remains, it is the chosen parent. If no more fitness cases are left, a parent is
    101               chosen randomly from the remaining individuals */
    102           var bestIndividualIndex = candidates.Count == 1 ? candidates[0] : candidates.Random(random);
    103           var bestIndividual = population[bestIndividualIndex];
    104 
    105           selected[k * population.Count + i] = copy ? (IScope)bestIndividual.Clone() : bestIndividual;
    106 
    107           pool.Remove(bestIndividualIndex);
     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);
    108122        }
    109123      }
     
    112126    }
    113127
    114     private static List<int> GetBestIndividuals(bool maximization, ItemArray<DoubleArray> caseQualities, List<int> bestIndividuals, int index) {
    115       var bestFitness = maximization ? double.NegativeInfinity : double.PositiveInfinity;
    116       var result = new List<int>();
     128    private static int LexicaseSelect(
     129      List<DoubleArray> caseQualities,
     130      List<int> candidates,
     131      IEnumerable<int> order,
     132      IRandom random,
     133      bool maximization) {
    117134
    118       for (var l = 0; l < bestIndividuals.Count; l++) {
    119         var individual = bestIndividuals[l];
    120         var caseQuality = caseQualities[individual][index];
     135      foreach (var curCase in order) {
     136        var nextCandidates = new List<int>();
    121137
    122         if (bestFitness.IsAlmost(caseQuality)) {
    123           result.Add(individual);
    124         } else if (maximization && bestFitness < caseQuality ||
    125                   !maximization && bestFitness > caseQuality) {
    126           bestFitness = caseQuality;
    127           result.Clear();
    128           result.Add(individual);
     138        var best = maximization
     139          ? double.NegativeInfinity
     140          : double.PositiveInfinity;
     141
     142        foreach (var candidate in candidates) {
     143          if (caseQualities[candidate][curCase].IsAlmost(best)) {
     144            // if the individuals is as good as the best one, add it
     145            nextCandidates.Add(candidate);
     146          } else if (
     147             (maximization && (caseQualities[candidate][curCase] > best)) ||
     148             (!maximization && (caseQualities[candidate][curCase] < best))) {
     149            // if the individuals is better than the best one, remove all previous candidates and add the new one
     150            nextCandidates.Clear();
     151            nextCandidates.Add(candidate);
     152            // also set the next best quality value
     153            best = caseQualities[candidate][curCase];
     154          }
     155          // else {do nothing}
    129156        }
    130157
    131         bestIndividuals = result;
     158        if (nextCandidates.Count == 1) {
     159          return nextCandidates[0];
     160        }
     161
     162        if (nextCandidates.Count < 1) {
     163          return candidates.SampleRandom(random);
     164        }
     165
     166        candidates = nextCandidates;
    132167      }
    133168
    134       return bestIndividuals;
     169      return candidates.Count == 1
     170        ? candidates[0]
     171        : candidates.SampleRandom(random);
    135172    }
    136173  }
Note: See TracChangeset for help on using the changeset viewer.