Changeset 4222


Ignore:
Timestamp:
08/16/10 09:58:29 (12 years ago)
Author:
gkronber
Message:

Changed operator to adapt the target distribution for dynamic operator equalization to use scaled (0..1) qualities and treat minimization problem correctly. #1142

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Operators/DynOpEqHistogramInitializer.cs

    r4193 r4222  
    6060      get { return (ILookupParameter<ItemList<IntValue>>)Parameters["TotalCounts"]; }
    6161    }
     62    public ILookupParameter<BoolValue> MaximizationParameter {
     63      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
     64    }
    6265
    6366    public DynOpEqHistogramInitializer()
     
    7174      Parameters.Add(new LookupParameter<ItemList<IntValue>>("AcceptedCounts"));
    7275      Parameters.Add(new LookupParameter<ItemList<IntValue>>("TotalCounts"));
     76      Parameters.Add(new LookupParameter<BoolValue>("Maximization"));
    7377    }
    7478
     
    7680      if (BinCapacityParameter.ActualValue == null) {
    7781        InitDefaultCapacityHistogram();
    78       }
    79       ItemList<ItemList<DoubleValue>> acceptedBinQualities = AcceptedBinQualitiesParameter.ActualValue;
    80       ItemList<IntValue> acceptedCounts = AcceptedCountsParameter.ActualValue;
    81       ItemList<IntValue> totalCounts = TotalCountsParameter.ActualValue;
    82 
    83       int popSize = PopulationSizeParameter.ActualValue.Value;
    84       //double minQuality = (from binAccepted in acceptedBinQualities
    85       //                     where binAccepted.Count > 0
    86       //                     select binAccepted.Min(x => x.Value)).Min();
    87       //double maxQuality = (from binAccepted in acceptedBinQualities
    88       //                     where binAccepted.Count > 0
    89       //                     select binAccepted.Max(x => x.Value)).Max();
    90       //double range = maxQuality - minQuality;
    91       double avgQualitySum = (from binAccepted in acceptedBinQualities
    92                               //select binAccepted.Count)
    93                               where binAccepted.Count > 0
    94                               select (from quality in binAccepted
    95                                       select quality.Value).Average())
    96                                     .Sum();
    97       ItemList<IntValue> binCapacity = BinCapacityParameter.ActualValue;
    98       for (int i = 0; i < binCapacity.Count; i++) {
    99         double avgBinQuality = (from quality in acceptedBinQualities[i]
    100                                 select quality.Value)
    101                                .DefaultIfEmpty(0.0)
    102                                .Average();
    103 
    104         //double avgBinQuality = acceptedBinQualities[i].Count;
    105         binCapacity[i].Value = (int)Math.Ceiling(popSize * (avgBinQuality / avgQualitySum));
    106         acceptedBinQualities[i].Clear();
    107         acceptedCounts[i].Value = 0;
    108       }
    109       for (int i = 0; i < totalCounts.Count; i++)
    110         totalCounts[i].Value = 0;
     82      } else {
     83        ItemList<ItemList<DoubleValue>> acceptedBinQualities = AcceptedBinQualitiesParameter.ActualValue;
     84        ItemList<IntValue> acceptedCounts = AcceptedCountsParameter.ActualValue;
     85        ItemList<IntValue> totalCounts = TotalCountsParameter.ActualValue;
     86
     87        int popSize = PopulationSizeParameter.ActualValue.Value;
     88
     89        ScaleBinQualities(acceptedBinQualities, 0, 1, MaximizationParameter.ActualValue.Value);
     90
     91        double avgQualitySum = (from binAccepted in acceptedBinQualities
     92                                where binAccepted.Count > 0
     93                                select (from quality in binAccepted
     94                                        select quality.Value).Average())
     95                                      .Sum();
     96        ItemList<IntValue> binCapacity = BinCapacityParameter.ActualValue;
     97        int totalCapacity = 0;
     98        for (int i = 0; i < binCapacity.Count; i++) {
     99          double avgBinQuality = (from quality in acceptedBinQualities[i]
     100                                  select quality.Value)
     101                                 .DefaultIfEmpty(0.0)
     102                                 .Average();
     103
     104          binCapacity[i].Value = Math.Max(1, (int)Math.Round(popSize * (avgBinQuality / avgQualitySum)));
     105          // rounding can lead to loss of capacity
     106          // this is problematic if the bin capacities are strict
     107          totalCapacity += binCapacity[i].Value;
     108          acceptedBinQualities[i].Clear();
     109          acceptedCounts[i].Value = 0;
     110        }
     111        // distribute the remaining slots starting with the largest bins
     112        IEnumerator<IntValue> orderedBinCapacities = binCapacity.OrderBy(x => -x.Value).GetEnumerator();
     113
     114        while (totalCapacity < popSize & orderedBinCapacities.MoveNext()) {
     115          orderedBinCapacities.Current.Value = orderedBinCapacities.Current.Value + 1;
     116          totalCapacity++;
     117        }
     118        if (totalCapacity < popSize) throw new InvalidProgramException("The sum of bin capacities doesn't match the population size");
     119        for (int i = 0; i < totalCounts.Count; i++)
     120          totalCounts[i].Value = 0;
     121      }
    111122      return base.Apply();
     123    }
     124
     125    public static void ScaleBinQualities(ItemList<ItemList<DoubleValue>> acceptedBinQualities, double min, double max, bool maximization) {
     126      double minValue = (from bin in acceptedBinQualities
     127                         from value in bin
     128                         select value.Value).Min();
     129      double maxValue = (from bin in acceptedBinQualities
     130                         from value in bin
     131                         select value.Value).Max();
     132
     133      if (!maximization) {
     134        double tmp = minValue;
     135        minValue = maxValue;
     136        maxValue = tmp;
     137      }
     138
     139      double valuesRange = maxValue - minValue;
     140      double targetRange = max - min;
     141
     142      foreach (var bin in acceptedBinQualities) {
     143        foreach (var value in bin) {
     144          double unitScaledValue = (value.Value - minValue) / valuesRange;
     145          double targetScaledValue = unitScaledValue * targetRange + min;
     146          value.Value = targetScaledValue;
     147        }
     148      }
    112149    }
    113150
     
    129166        } else {
    130167          CreateNewBin(binIndex);
    131           AddToBin(binIndex, quality[i].Value);
    132168        }
    133169      }
     
    148184
    149185    private void AddToBin(int binIndex, double quality) {
    150       ItemList<ItemList<DoubleValue>> acceptedQualities = AcceptedBinQualitiesParameter.ActualValue;
    151       acceptedQualities[binIndex].Add(new DoubleValue(quality));
     186      ItemList<IntValue> binCapacity = BinCapacityParameter.ActualValue;
     187      binCapacity[binIndex].Value = binCapacity[binIndex].Value + 1;
    152188    }
    153189
Note: See TracChangeset for help on using the changeset viewer.