Ignore:
Timestamp:
11/18/15 19:27:22 (4 years ago)
Author:
gkronber
Message:

#2478:

  • refactoring of ChildrenCopyCreator
  • fixed the bug that EvolutionStrategyOffspringSelector ignored if the problem was a maximization or minimization problem
  • removed unnecessary backwards-compatibility code
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Selection/3.3/EvolutionStrategyOffspringSelector.cs

    r13164 r13261  
    2222using System;
    2323using System.Collections.Generic;
     24using System.Runtime.InteropServices;
    2425using HeuristicLab.Common;
    2526using HeuristicLab.Core;
     
    3435  public class EvolutionStrategyOffspringSelector : SingleSuccessorOperator {
    3536
    36     private class QualityComparer : IComparer<IScope> {
     37    private class FitnessComparer : IComparer<IScope> {
    3738
    3839      #region IComparer<IScope> Member
    3940
    4041      private String qualityParameterName;
    41 
    42       public QualityComparer(String qualityParamName) {
     42      private bool maximization;
     43
     44      public FitnessComparer(String qualityParamName, bool maximization) {
    4345        this.qualityParameterName = qualityParamName;
    44       }
    45 
     46        this.maximization = maximization;
     47      }
     48
     49      // less than zero if x is-better-than y
     50      // larger than zero if y is-better-than x
     51      // zero if both are the same
    4652      public int Compare(IScope x, IScope y) {
    47           IVariable quality1, quality2;
    48 
    49           if (x.Variables.TryGetValue(qualityParameterName, out quality1)
    50             && y.Variables.TryGetValue(qualityParameterName, out quality2)) {
    51             DoubleValue dblVal = quality1.Value as DoubleValue;
    52             DoubleValue dblVal2 = quality2.Value as DoubleValue;
    53             return dblVal.CompareTo(dblVal2);
    54           }
    55           else
    56             throw new Exception("ERROR!!! Quality Param: "+qualityParameterName);
     53        IVariable quality1, quality2;
     54
     55        if (x.Variables.TryGetValue(qualityParameterName, out quality1)
     56          && y.Variables.TryGetValue(qualityParameterName, out quality2)) {
     57          DoubleValue left = quality1.Value as DoubleValue;
     58          DoubleValue right = quality2.Value as DoubleValue;
     59          var res = left.CompareTo(right);
     60          if (maximization) return -res; // in the maximization case the largest value should preceed all others in the sort order
     61          else return res;
     62        } else
     63          throw new ArgumentException("Quality variable " + qualityParameterName + " not found.");
    5764      }
    5865
     
    95102    public ILookupParameter<DoubleValue> QualityParameter {
    96103      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
     104    }
     105    public ILookupParameter<BoolValue> MaximizationParameter {
     106      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
    97107    }
    98108
     
    119129      Parameters.Add(new ScopeTreeLookupParameter<BoolValue>("SuccessfulOffspring", "True if the offspring was more successful than its parents.", 2));
    120130      Parameters.Add(new OperatorParameter("OffspringCreator", "The operator used to create new offspring."));
    121       Parameters.Add(new LookupParameter<IntValue>("EvaluatedSolutions", "The number of times solutions have been evaluated."));
     131      Parameters.Add(new LookupParameter<IntValue>("EvaluatedSolutions", "The number of solution evaluations."));
    122132      Parameters.Add(new LookupParameter<IntValue>("MaximumEvaluatedSolutions", "The maximum number of evaluated solutions (approximately)."));
    123133      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of a child"));
     134      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "Flag that indicates if the problem is a maximization problem"));
    124135    }
    125136
     
    165176      // implement the ActualValue fetch here - otherwise the parent scope would also be included, given that there may be 1000 or more parents, this is quite unnecessary
    166177      string tname = SuccessfulOffspringParameter.TranslatedName;
    167       double tmpSelPress = selectionPressure.Value, tmpSelPressInc = 1.0 / populationSize;
     178      double tmpSelPress = selectionPressure.Value;
     179      double tmpSelPressInc = 1.0 / populationSize;
    168180      for (int i = 0; i < offspring.SubScopes.Count; i++) {
    169181        // fetch value
     
    176188        if (tmp.Value) {
    177189          IScope currentOffspring = offspring.SubScopes[i];
    178           offspring.SubScopes.Remove(currentOffspring);
    179           i--;
     190          offspring.SubScopes.RemoveAt(i);
     191          i--; // next loop should continue with the subscope at index i which replaced currentOffspring
    180192          population.Add(currentOffspring);
    181193          successfulOffspringAdded++;
    182         }
    183         else {
     194        } else {
    184195          IScope currentOffspring = offspring.SubScopes[i];
    185           offspring.SubScopes.Remove(currentOffspring);
     196          offspring.SubScopes.RemoveAt(i);
    186197          i--;
    187           virtual_population.Add(currentOffspring);
     198          virtual_population.Add(currentOffspring); // add to losers pool
    188199        }
    189200        tmpSelPress += tmpSelPressInc;
    190201
    191         double tmpSuccessRatio = (successfulOffspring.Value+successfulOffspringAdded) / ((double)populationSize);
     202        double tmpSuccessRatio = (successfulOffspring.Value + successfulOffspringAdded) / ((double)populationSize);
    192203        if (tmpSuccessRatio >= successRatio && (population.Count + virtual_population.Count) >= populationSize)
    193204          break;
     
    200211
    201212      // check if enough children have been generated (or limit of selection pressure or evaluted solutions is reached)
    202       if (((EvaluatedSolutionsParameter.ActualValue.Value < MaximumEvaluatedSolutionsParameter.ActualValue.Value) 
    203           && (selectionPressure.Value < maxSelPress) 
    204           && (currentSuccessRatio.Value < successRatio)) 
     213      if (((EvaluatedSolutionsParameter.ActualValue.Value < MaximumEvaluatedSolutionsParameter.ActualValue.Value)
     214          && (selectionPressure.Value < maxSelPress)
     215          && (currentSuccessRatio.Value < successRatio))
    205216        || ((population.Count + virtual_population.Count) < populationSize)) {
    206217        // more children required -> reduce left and start children generation again
     
    209220        while (parents.SubScopes.Count > 0) {
    210221          IScope parent = parents.SubScopes[0];
    211           parents.SubScopes.RemoveAt(0);
    212           scope.SubScopes.Add(parent);
    213         }
    214 
    215         IOperator moreOffspring = OffspringCreatorParameter.ActualValue as IOperator;
    216         if (moreOffspring == null) throw new InvalidOperationException(Name + ": More offspring are required, but no operator specified for creating them.");
    217         return ExecutionContext.CreateOperation(moreOffspring);
     222          parents.SubScopes.RemoveAt(0); // TODO: repeated call of RemoveAt(0) is inefficient?
     223          scope.SubScopes.Add(parent); // order of subscopes is reversed
     224        }
     225
     226        IOperator offspringCreator = OffspringCreatorParameter.ActualValue as IOperator;
     227        if (offspringCreator == null) throw new InvalidOperationException(Name + ": More offspring are required, but no operator specified for creating them.");
     228        return ExecutionContext.CreateOperation(offspringCreator); // this assumes that this operator will be called again indirectly or directly
    218229      } else {
    219230        // enough children generated
    220         QualityComparer qualityComparer = new QualityComparer(QualityParameter.TranslatedName);
    221         population.Sort(qualityComparer);
    222 
    223         //only keep minimum best successful children in population
     231        var fitnessComparer = new FitnessComparer(QualityParameter.TranslatedName, MaximizationParameter.ActualValue.Value);
     232        population.Sort(fitnessComparer); // sort individuals by descending fitness
     233
     234        // keeps only the best successRatio * populationSize solutions in the population (the remaining ones are added to the virtual population)
    224235        int removed = 0;
    225236        for (int i = 0; i < population.Count; i++) {
    226237          double tmpSuccessRatio = i / (double)populationSize;
    227238          if (tmpSuccessRatio > successRatio) {
    228               virtual_population.Add(population[i]);
    229               removed++;
     239            virtual_population.Add(population[i]);
     240            removed++;
    230241          }
    231242        }
     
    233244
    234245        //fill up population with best remaining children (successful or unsuccessful)
    235         virtual_population.Sort(qualityComparer);
     246        virtual_population.Sort(fitnessComparer);
    236247        int offspringNeeded = populationSize - population.Count;
    237248        for (int i = 0; i < offspringNeeded && i < virtual_population.Count; i++) {
    238           population.Add(virtual_population[i]);
     249          population.Add(virtual_population[i]); // children are sorted by descending fitness
    239250        }
    240251
Note: See TracChangeset for help on using the changeset viewer.