Free cookie consent management tool by TermsFeed Policy Generator

source: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Operators/DynOpEqHistogramInitializer.cs @ 10635

Last change on this file since 10635 was 5275, checked in by gkronber, 14 years ago

Merged changes from trunk to data analysis exploration branch and added fractional distance metric evaluator. #1142

File size: 9.5 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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.Linq;
24using HeuristicLab.Core;
25using HeuristicLab.Data;
26using HeuristicLab.Operators;
27using HeuristicLab.Optimization;
28using HeuristicLab.Parameters;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
31using System.Collections.Generic;
32using HeuristicLab.Common;
33
34namespace HeuristicLab.Problems.DataAnalysis.Operators {
35  [Item("DynOpEqHistogramInitializer", "Dynamic Operator Equalization Histogram Initializer.")]
36  [StorableClass]
37  public class DynOpEqHistogramInitializer : SingleSuccessorOperator {
38    public ILookupParameter<ItemList<IntValue>> BinCapacityParameter {
39      get { return (ILookupParameter<ItemList<IntValue>>)Parameters["BinCapacity"]; }
40    }
41    public ILookupParameter<ItemList<ItemList<DoubleValue>>> AcceptedBinQualitiesParameter {
42      get { return (ILookupParameter<ItemList<ItemList<DoubleValue>>>)Parameters["AcceptedBinQualities"]; }
43    }
44    public ILookupParameter<IntValue> PopulationSizeParameter {
45      get { return (ILookupParameter<IntValue>)Parameters["PopulationSize"]; }
46    }
47    public IScopeTreeLookupParameter<SymbolicExpressionTree> SymbolicExpressionTreeParameter {
48      get { return (IScopeTreeLookupParameter<SymbolicExpressionTree>)Parameters["SymbolicExpressionTree"]; }
49    }
50    public IScopeTreeLookupParameter<DoubleValue> QualityParameter {
51      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
52    }
53    public ILookupParameter BinSizeParameter {
54      get { return (ILookupParameter<IntValue>)Parameters["BinSize"]; }
55    }
56    public ILookupParameter<ItemList<IntValue>> AcceptedCountsParameter {
57      get { return (ILookupParameter<ItemList<IntValue>>)Parameters["AcceptedCounts"]; }
58    }
59    public ILookupParameter<ItemList<IntValue>> TotalCountsParameter {
60      get { return (ILookupParameter<ItemList<IntValue>>)Parameters["TotalCounts"]; }
61    }
62    public ILookupParameter<BoolValue> MaximizationParameter {
63      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
64    }
65
66    [StorableConstructor]
67    protected DynOpEqHistogramInitializer(bool deserializing) : base(deserializing) { }
68    protected DynOpEqHistogramInitializer(DynOpEqHistogramInitializer original, Cloner cloner)
69      : base(original, cloner) {
70    }
71    public DynOpEqHistogramInitializer()
72      : base() {
73      Parameters.Add(new ScopeTreeLookupParameter<SymbolicExpressionTree>("SymbolicExpressionTree"));
74      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality"));
75      Parameters.Add(new LookupParameter<IntValue>("PopulationSize"));
76      Parameters.Add(new ValueLookupParameter<IntValue>("BinSize", new IntValue(5)));
77      Parameters.Add(new LookupParameter<ItemList<IntValue>>("BinCapacity"));
78      Parameters.Add(new LookupParameter<ItemList<ItemList<DoubleValue>>>("AcceptedBinQualities"));
79      Parameters.Add(new LookupParameter<ItemList<IntValue>>("AcceptedCounts"));
80      Parameters.Add(new LookupParameter<ItemList<IntValue>>("TotalCounts"));
81      Parameters.Add(new LookupParameter<BoolValue>("Maximization"));
82    }
83    public override IDeepCloneable Clone(Cloner cloner) {
84      return new DynOpEqHistogramInitializer(this, cloner);
85    }
86    public override IOperation Apply() {
87      if (BinCapacityParameter.ActualValue == null) {
88        InitDefaultCapacityHistogram();
89      } else {
90        ItemList<ItemList<DoubleValue>> acceptedBinQualities = AcceptedBinQualitiesParameter.ActualValue;
91        ItemList<IntValue> acceptedCounts = AcceptedCountsParameter.ActualValue;
92        ItemList<IntValue> totalCounts = TotalCountsParameter.ActualValue;
93
94        int popSize = PopulationSizeParameter.ActualValue.Value;
95
96        ScaleBinQualities(acceptedBinQualities, 0, 1, MaximizationParameter.ActualValue.Value);
97
98        double avgQualitySum = (from binAccepted in acceptedBinQualities
99                                where binAccepted.Count > 0
100                                select (from quality in binAccepted
101                                        select quality.Value).Average())
102                                      .Sum();
103        ItemList<IntValue> binCapacity = BinCapacityParameter.ActualValue;
104        int totalCapacity = 0;
105        for (int i = 0; i < binCapacity.Count; i++) {
106          double avgBinQuality = (from quality in acceptedBinQualities[i]
107                                  select quality.Value)
108                                 .DefaultIfEmpty(0.0)
109                                 .Average();
110
111          binCapacity[i].Value = Math.Max(1, (int)Math.Round(popSize * (avgBinQuality / avgQualitySum)));
112          // rounding can lead to loss of capacity
113          // this is problematic if the bin capacities are strict
114          totalCapacity += binCapacity[i].Value;
115          acceptedBinQualities[i].Clear();
116          acceptedCounts[i].Value = 0;
117        }
118        // distribute the remaining slots starting with the largest bins
119        IEnumerator<IntValue> orderedBinCapacities = binCapacity.OrderBy(x => -x.Value).GetEnumerator();
120
121        while (totalCapacity < popSize & orderedBinCapacities.MoveNext()) {
122          orderedBinCapacities.Current.Value = orderedBinCapacities.Current.Value + 1;
123          totalCapacity++;
124        }
125        if (totalCapacity < popSize) throw new InvalidProgramException("The sum of bin capacities doesn't match the population size");
126        for (int i = 0; i < totalCounts.Count; i++)
127          totalCounts[i].Value = 0;
128      }
129      return base.Apply();
130    }
131
132    public static void ScaleBinQualities(ItemList<ItemList<DoubleValue>> acceptedBinQualities, double min, double max, bool maximization) {
133      double minValue = (from bin in acceptedBinQualities
134                         from value in bin
135                         select value.Value).Min();
136      double maxValue = (from bin in acceptedBinQualities
137                         from value in bin
138                         select value.Value).Max();
139
140      if (!maximization) {
141        double tmp = minValue;
142        minValue = maxValue;
143        maxValue = tmp;
144      }
145
146      double valuesRange = maxValue - minValue;
147      double targetRange = max - min;
148
149      foreach (var bin in acceptedBinQualities) {
150        foreach (var value in bin) {
151          double unitScaledValue = (value.Value - minValue) / valuesRange;
152          double targetScaledValue = unitScaledValue * targetRange + min;
153          value.Value = targetScaledValue;
154        }
155      }
156    }
157
158    private void InitDefaultCapacityHistogram() {
159      ItemArray<SymbolicExpressionTree> trees = SymbolicExpressionTreeParameter.ActualValue;
160      ItemArray<DoubleValue> quality = QualityParameter.ActualValue;
161      var binCapacities = new ItemList<IntValue>();
162      var acceptedQuality = new ItemList<ItemList<DoubleValue>>(20);
163      var acceptedCounts = new ItemList<IntValue>();
164      var totalCounts = new ItemList<IntValue>();
165      BinCapacityParameter.ActualValue = binCapacities;
166      AcceptedBinQualitiesParameter.ActualValue = acceptedQuality;
167      TotalCountsParameter.ActualValue = totalCounts;
168      AcceptedCountsParameter.ActualValue = acceptedCounts;
169      for (int i = 0; i < trees.Length; i++) {
170        int binIndex = GetBinIndexForSize(trees[i].Size);
171        if (Exists(binIndex)) {
172          AddToBin(binIndex, quality[i].Value);
173        } else {
174          CreateNewBin(binIndex);
175        }
176      }
177    }
178
179    private void CreateNewBin(int binIndex) {
180      ItemList<IntValue> binCapacities = BinCapacityParameter.ActualValue;
181      ItemList<ItemList<DoubleValue>> acceptedQualities = AcceptedBinQualitiesParameter.ActualValue;
182      ItemList<IntValue> acceptedCounts = AcceptedCountsParameter.ActualValue;
183      ItemList<IntValue> totalCounts = TotalCountsParameter.ActualValue;
184      for (int i = binCapacities.Count; i <= binIndex; i++) {
185        binCapacities.Add(new IntValue(1));
186        acceptedQualities.Add(new ItemList<DoubleValue>(10));
187        acceptedCounts.Add(new IntValue(0));
188        totalCounts.Add(new IntValue(0));
189      }
190    }
191
192    private void AddToBin(int binIndex, double quality) {
193      ItemList<IntValue> binCapacity = BinCapacityParameter.ActualValue;
194      binCapacity[binIndex].Value = binCapacity[binIndex].Value + 1;
195    }
196
197    private bool Exists(int binIndex) {
198      // if the bin has a capacity set then it exists
199      ItemList<IntValue> binCapacities = BinCapacityParameter.ActualValue;
200      return binIndex < binCapacities.Count;
201    }
202
203    private int GetBinIndexForSize(int size) {
204      int binSize = ((IntValue)BinSizeParameter.ActualValue).Value;
205      return (int)Math.Floor((size - 3.0) / binSize);
206    }
207  }
208}
Note: See TracBrowser for help on using the repository browser.