Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Operators/3.3/DataReducer.cs @ 7743

Last change on this file since 7743 was 7395, checked in by ascheibe, 12 years ago

#1745 moved new Island GA to trunk

File size: 8.6 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 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.Collections.Generic;
24using System.Linq;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Parameters;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30
31namespace HeuristicLab.Operators {
32  [Item("DataReducer", "An operator to reduce values of sub scopes.")]
33  [StorableClass]
34  public sealed class DataReducer : SingleSuccessorOperator {
35    #region Parameter Properties
36    public ScopeTreeLookupParameter<IItem> ParameterToReduce {
37      get { return (ScopeTreeLookupParameter<IItem>)Parameters["ParameterToReduce"]; }
38    }
39    public LookupParameter<IItem> TargetParameter {
40      get { return (LookupParameter<IItem>)Parameters["TargetParameter"]; }
41    }
42    public ValueParameter<ReductionOperation> ReductionOperation {
43      get { return (ValueParameter<ReductionOperation>)Parameters["ReductionOperation"]; }
44    }
45    public ValueParameter<ReductionOperation> TargetOperation {
46      get { return (ValueParameter<ReductionOperation>)Parameters["TargetOperation"]; }
47    }
48    #endregion
49
50    [StorableConstructor]
51    private DataReducer(bool deserializing) : base(deserializing) { }
52    private DataReducer(DataReducer original, Cloner cloner)
53      : base(original, cloner) {
54    }
55    public DataReducer()
56      : base() {
57      #region Create parameters
58      Parameters.Add(new ScopeTreeLookupParameter<IItem>("ParameterToReduce", "The parameter on which the reduction operation should be applied."));
59      Parameters.Add(new LookupParameter<IItem>("TargetParameter", "The target variable in which the reduced value should be stored."));
60      Parameters.Add(new ValueParameter<ReductionOperation>("ReductionOperation", "The operation which is applied on the parameters to reduce."));
61      Parameters.Add(new ValueParameter<ReductionOperation>("TargetOperation", "The operation used to apply the reduced value to the target variable."));
62      #endregion
63    }
64
65    public override IDeepCloneable Clone(Cloner cloner) {
66      return new DataReducer(this, cloner);
67    }
68
69    public override IOperation Apply() {
70      var values = ParameterToReduce.ActualValue;
71      if (values.Count() > 0) {
72        if (values.All(x => x.GetType() == typeof(IntValue))) {
73          List<IntValue> intValues = new List<IntValue>();
74          values.ForEach(x => intValues.Add((IntValue)x));
75          CalculateResult(intValues);
76        } else if (values.All(x => x.GetType() == typeof(DoubleValue))) {
77          List<DoubleValue> doubleValues = new List<DoubleValue>();
78          values.ForEach(x => doubleValues.Add((DoubleValue)x));
79          CalculateResult(doubleValues);
80        } else if (values.All(x => x.GetType() == typeof(TimeSpanValue))) {
81          List<TimeSpanValue> timeSpanValues = new List<TimeSpanValue>();
82          values.ForEach(x => timeSpanValues.Add((TimeSpanValue)x));
83          CalculateResult(timeSpanValues);
84        } else {
85          throw new ArgumentException(string.Format("Type {0} is not supported by the DataReducer.", values.First().GetType()));
86        }
87      }
88      return base.Apply();
89    }
90
91    private void CalculateResult(List<IntValue> values) {
92      int result = 1;
93      if (TargetParameter.ActualValue == null) TargetParameter.ActualValue = new IntValue();
94      IntValue target = (IntValue)TargetParameter.ActualValue;
95
96      switch (ReductionOperation.Value.Value) {
97        case ReductionOperations.Sum:
98          result = values.Sum(x => x.Value);
99          break;
100        case ReductionOperations.Prod:
101          values.ForEach(x => result *= x.Value);
102          break;
103        case ReductionOperations.Avg:
104          result = (int)Math.Round(values.Average(x => x.Value));
105          break;
106        case ReductionOperations.Min:
107          result = values.Min(x => x.Value);
108          break;
109        case ReductionOperations.Max:
110          result = values.Max(x => x.Value);
111          break;
112        default:
113          throw new InvalidOperationException(string.Format("Operation {0} is not supported as ReductionOperation for type: {1}.", ReductionOperation.Value.Value, result.GetType()));
114      }
115
116      switch (TargetOperation.Value.Value) {
117        case ReductionOperations.Assign:
118          target.Value = result;
119          break;
120        case ReductionOperations.Sum:
121          target.Value += result;
122          break;
123        case ReductionOperations.Prod:
124          if (target.Value == 0) target.Value = 1;
125          target.Value *= result;
126          break;
127        default:
128          throw new InvalidOperationException(string.Format("Operation {0} is not supported as TargetOperation for type: {1}.", TargetOperation.Value.Value, result.GetType()));
129      }
130    }
131
132    private void CalculateResult(List<DoubleValue> values) {
133      double result = 1.0;
134      if (TargetParameter.ActualValue == null) TargetParameter.ActualValue = new DoubleValue();
135      DoubleValue target = (DoubleValue)TargetParameter.ActualValue;
136
137      switch (ReductionOperation.Value.Value) {
138        case ReductionOperations.Sum:
139          result = values.Sum(x => x.Value);
140          break;
141        case ReductionOperations.Prod:
142          values.ForEach(x => result *= x.Value);
143          break;
144        case ReductionOperations.Avg:
145          result = values.Average(x => x.Value);
146          break;
147        case ReductionOperations.Min:
148          result = values.Min(x => x.Value);
149          break;
150        case ReductionOperations.Max:
151          result = values.Max(x => x.Value);
152          break;
153        default:
154          throw new InvalidOperationException(string.Format("Operation {0} is not supported as ReductionOperation for type: {1}.", ReductionOperation.Value.Value, result.GetType()));
155      }
156
157      switch (TargetOperation.Value.Value) {
158        case ReductionOperations.Assign:
159          target.Value = result;
160          break;
161        case ReductionOperations.Sum:
162          target.Value += result;
163          break;
164        case ReductionOperations.Prod:
165          if (target.Value == 0.0) target.Value = 1.0;
166          target.Value *= result;
167          break;
168        default:
169          throw new InvalidOperationException(string.Format("Operation {0} is not supported as TargetOperation for type: {1}.", TargetOperation.Value.Value, result.GetType()));
170      }
171    }
172
173    private void CalculateResult(List<TimeSpanValue> values) {
174      TimeSpan result = TimeSpan.Zero;
175      if (TargetParameter.ActualValue == null) TargetParameter.ActualValue = new TimeSpanValue();
176      TimeSpanValue target = (TimeSpanValue)TargetParameter.ActualValue;
177
178      switch (ReductionOperation.Value.Value) {
179        case ReductionOperations.Sum:
180          values.ForEach(x => result = result.Add(x.Value));
181          break;
182        case ReductionOperations.Avg:
183          double avg = values.Average(x => x.Value.TotalMilliseconds);
184          result = TimeSpan.FromMilliseconds(avg);
185          break;
186        case ReductionOperations.Min:
187          result = values.Min(x => x.Value);
188          break;
189        case ReductionOperations.Max:
190          result = values.Max(x => x.Value);
191          break;
192        default:
193          throw new InvalidOperationException(string.Format("Operation {0} is not supported as ReductionOperation for type: {1}.", ReductionOperation.Value.Value, result.GetType()));
194      }
195
196      switch (TargetOperation.Value.Value) {
197        case ReductionOperations.Assign:
198          target.Value = result;
199          break;
200        case ReductionOperations.Sum:
201          target.Value += result;
202          break;
203        default:
204          throw new InvalidOperationException(string.Format("Operation {0} is not supported as TargetOperation for type: {1}.", TargetOperation.Value.Value, result.GetType()));
205      }
206    }
207  }
208}
Note: See TracBrowser for help on using the repository browser.