Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost/3.3/Evaluators/ConcludingEvaluator.cs @ 15469

Last change on this file since 15469 was 13071, checked in by gkronber, 9 years ago

#2499: added license headers and removed unused usings

File size: 19.5 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 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.Text.RegularExpressions;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Parameters;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30using System.Linq;
31using HeuristicLab.BioBoost.Representation;
32using HeuristicLab.BioBoost.Utils;
33
34namespace HeuristicLab.BioBoost.Evaluators {
35  [StorableClass]
36  public class ConcludingEvaluator : BioBoostEvaluator {
37
38    #region Parameter
39    public LookupParameter<DoubleValue> TotalCostParameter {
40      get { return (LookupParameter<DoubleValue>) Parameters["TotalCost"]; }
41    }
42    public LookupParameter<BoolValue> RemoveIntermediateResultsParameter {
43      get { return (LookupParameter<BoolValue>) Parameters["RemoveIntermediateResults"]; }
44    }
45    public ILookupParameter<DoubleArray> QualityCriteriaParameter {
46      get { return (ILookupParameter<DoubleArray>) Parameters["QualityCriteria"]; }
47    }
48    #endregion
49
50    #region Parameter Values
51    public double TotalCost {
52      get { return TotalCostParameter.ActualValue.Value; }
53      set { TotalCostParameter.ActualValue = new DoubleValue(value); }
54    }
55    public bool RemoveIntermediateResults {
56      get { return RemoveIntermediateResultsParameter.ActualValue.Value; }
57      set { RemoveIntermediateResultsParameter.ActualValue = new BoolValue(value); }
58    }
59    public DoubleArray QualityCriteria {
60      get { return QualityCriteriaParameter.ActualValue; }
61      set { QualityCriteriaParameter.ActualValue = value; }
62    }
63    #endregion
64
65    #region Construction & Cloning
66    [StorableConstructor]
67    protected ConcludingEvaluator(bool isDeserializing) : base(isDeserializing) {}
68    public ConcludingEvaluator() {
69      Parameters.Add(new LookupParameter<BoolValue>("RemoveIntermediateResults", "Whether to remove intermediate results created during evaluation."));
70      Parameters.Add(new LookupParameter<DoubleValue>("TotalCost", "Overall cost of the whole scenario."));
71      Parameters.Add(new LookupParameter<DoubleArray>("QualityCriteria", "The list of qualities to consider."));
72    }
73    public ConcludingEvaluator(ConcludingEvaluator original, Cloner cloner) : base(original, cloner) { }
74    public override IDeepCloneable Clone(Cloner cloner) {
75      return new ConcludingEvaluator(this, cloner);
76    }
77    [StorableHook(HookType.AfterDeserialization)]
78    void AfterDeserialization() {
79      if (!Parameters.ContainsKey("QualityCriteria"))
80        Parameters.Add(new LookupParameter<DoubleArray>("QualityCriteria", "The list of qualities to consider."));
81    }
82    #endregion
83
84    private readonly Regex penaltyRegex = new Regex("[Pp]enalt(y|ies)$");
85
86    public override IOperation Apply() {
87      CreateAggregationLayers();
88      var expenses = 0d;
89      var revenues = 0d;
90      var penalties = 0d;
91      foreach (var cost in Costs) {
92        var value = cost.Value as DoubleValue;
93        if (value == null) continue;
94        if (penaltyRegex.IsMatch(cost.Name)) {
95          penalties += value.Value;
96        } else if (value.Value > 0) {
97          expenses += value.Value;
98        } else {
99          revenues -= value.Value;
100        }
101      }
102      var roi = Math.Abs(expenses) < 1 ? revenues : (revenues - expenses)/expenses;
103      TotalCost = roi - penalties;
104      var qualities = new List<double> {TotalCost};
105      if (RemoveIntermediateResults) {
106        foreach (var r in IntermediateResults) {
107          RemoveFromScope(r.Name);
108        }
109        RemoveFromScope(IntermediateResultsParameter.ActualName);
110        RemoveFromScope(CostsParameter.ActualName);
111      }
112      foreach (var p in ProblemData.Products) {
113        var amounts = GetFromScope<DoubleArray>(LayerDescriptor.AmountsAtSource.NameWithPrefix(p.Label));
114        if (amounts != null) {
115          qualities.Add(amounts.Sum());
116        }
117      }
118      QualityCriteria = new DoubleArray(qualities.ToArray());
119      return base.Apply();
120    }
121
122    private void CreateAggregationLayers() {
123      // for transport targets (straw, biosyncrude)
124      // aggregate sources (recursively)
125      // straw -> straw targets
126      // straw -> straw targets -> biosyncrude targets
127      // biosyncrude -> biosyncrude targets
128      var scope = ExecutionContext.Scope;
129
130      // straw sources, biosyncrude sources
131      var sources = scope.Variables
132        .Where(v => LayerDescriptor.Sources.IsSuffixOf(v.Name))
133        .Where(v => v.Value is ItemArray<ItemList<IntValue>>)
134        .ToDictionary(
135          v => LayerDescriptor.Sources.RemoveSuffixFrom(v.Name),
136          v => (ItemArray<ItemList<IntValue>>)v.Value);
137
138      // determine straw 1, biosyncrude 2 ???
139      // -> find utilizations
140      var feedstocks = scope.Variables
141        .Where(v => LayerDescriptor.Utilizations.IsSuffixOf(v.Name))
142        .Select(v => LayerDescriptor.Utilizations.RemoveSuffixFrom(v.Name))
143        .ToHashSet();
144      if (feedstocks.Count > 1) throw new InvalidOperationException("Currently only one feedstock is allowed.");
145      if (feedstocks.Count == 0) return;
146      var feedstock = feedstocks.First();
147      var carriers = sources.Keys.Where(k => k != feedstock);
148      if (carriers.Count() > 1) throw new InvalidOperationException("Currently only one carrier is allowed");
149      var carrier = carriers.Count() == 0 ? null : carriers.First();
150
151      var feedstockSources = sources[feedstock];
152      var carrierSources = carrier == null ? null : sources[carrier];
153      var finalProductName = GetFinalProductName(carrier ?? feedstock);
154      if (finalProductName == null) finalProductName = "TransportFuel";
155
156
157      if (carrier == null) {
158        AnalyzeSingleEchelon(feedstock, finalProductName, feedstockSources);
159      } else {
160        AnalyzeBinaryEchelon(feedstock, carrier, finalProductName, feedstockSources, carrierSources);
161      }
162    }
163
164    private void AnalyzeBinaryEchelon(string feedstock, string carrier, string finalProductName, ItemArray<ItemList<IntValue>> feedstockSources, ItemArray<ItemList<IntValue>> carrierSources) {
165      var length = feedstockSources.Length;
166
167      var feedstockCosts = GetFromScope<DoubleArray>(LayerDescriptor.TotalCostsAtSource.NameWithPrefix(feedstock));
168      //var feedstockAmounts = GetFromScope<DoubleArray>(LayerDescriptor.AmountsTransportedFromSource.NameWithPrefix(feedstock));
169      var feedstockLogisticCosts = GetFromScope<DoubleArray>(LayerDescriptor.TotalLogisticCosts.NameWithPrefix(feedstock));
170      var carrierLogisticCosts = GetFromScope<DoubleArray>(LayerDescriptor.TotalLogisticCosts.NameWithPrefix(carrier));
171      var decentralConversionCosts = GetFromScope<DoubleArray>(LayerDescriptor.TotalAmortizedConversionCosts.NameWithPrefix(feedstock));
172      var finalProductAmounts = GetFromScope<DoubleArray>(LayerDescriptor.AmountsAtSource.NameWithPrefix(finalProductName));
173      var carrierProductAmounts = GetFromScope<DoubleArray>(LayerDescriptor.AmountsTransportedFromSource.NameWithPrefix(carrier));
174      var finalProductCosts = GetFromScope<DoubleArray>(LayerDescriptor.TotalCostsAtSource.NameWithPrefix(finalProductName));
175      var carrierProductCosts = GetFromScope<DoubleArray>(LayerDescriptor.TotalCostsAtSource.NameWithPrefix(carrier));
176      var centralConversionCosts = GetFromScope<DoubleArray>(LayerDescriptor.TotalAmortizedConversionCosts.NameWithPrefix(carrier));
177      var finalProductPrice = ProblemData.Products.FirstOrDefault(p => p.Label == finalProductName).PriceAtSource;
178      var carrierProductPrice = ProblemData.Products.FirstOrDefault(p => p.Label == carrier).PriceAtSource;
179
180      var centralPlantsFeedstockCosts = new DoubleArray(length);
181      var centralPlantsFeedstockCostsRelative = new DoubleArray(length);
182      var centralPlantsDecentralLogisticCosts = new DoubleArray(length);
183      var centralPlantsDecentralLogisticCostsRelative = new DoubleArray(length);
184      var centralPlantsDecentralConversionCosts = new DoubleArray(length);
185      var centralPlantsDecentralConversionCostsRelative = new DoubleArray(length);
186      var centralPlantsCentralLogisticCosts = new DoubleArray(length);
187      var centralPlantsCentralLogisticCostsRelative = new DoubleArray(length);
188      // var plantsCentralConversionCosts = new DoubleArray(length);  already there
189      var centralPlantsCentralConversionCostsRelative = new DoubleArray(length);
190      var centralPlantsRoiFollowed = new DoubleArray(length);
191      var centralPlantsRoiAggregated = new DoubleArray(length);
192
193      var decentralPlantsFeedstockCosts = new DoubleArray(length);
194      var decentralPlantsFeedstockCostsRelative = new DoubleArray(length);
195      var decentralPlantsDecentralLogisticCosts = new DoubleArray(length);
196      var decentralPlantsDecentralLogisticCostsRelative = new DoubleArray(length);
197      //var decentralPlantsDecentralConversionCosts = new DoubleArray(length);
198      var decentralPlantsDecentralConversionCostsRelative = new DoubleArray(length);
199      var decentralPlantsRoiFollowed = new DoubleArray(length);
200      var decentralPlantsRoiAggregated = new DoubleArray(length);
201
202      for (int i = 0; i < carrierSources.Length; i++) {
203        if (carrierSources[i] != null) { // central plant
204          var plantsFeedstockSources = carrierSources[i]
205            .Select(j => feedstockSources[j.Value].Select(s => s.Value))
206            .Aggregate((e1, e2) => e1.Concat(e2))
207            .ToHashSet();
208          var plantsCarrierSources = carrierSources[i].Select(j => j.Value).ToHashSet();
209          var finalProductAmount = finalProductAmounts[i];
210
211          centralPlantsFeedstockCosts[i] = feedstockCosts.FuncOverIndices(plantsFeedstockSources, Sum);
212          centralPlantsFeedstockCostsRelative[i] = centralPlantsFeedstockCosts[i]/finalProductAmount;
213
214          centralPlantsDecentralLogisticCosts[i] = feedstockLogisticCosts.FuncOverIndices(plantsFeedstockSources, Sum);
215          centralPlantsDecentralLogisticCostsRelative[i] = centralPlantsDecentralLogisticCosts[i]/finalProductAmount;
216
217          centralPlantsDecentralConversionCosts[i] = decentralConversionCosts.FuncOverIndices(plantsCarrierSources, Sum);
218          centralPlantsDecentralConversionCostsRelative[i] = centralPlantsDecentralConversionCosts[i]/finalProductAmount;
219
220          centralPlantsCentralLogisticCosts[i] = carrierLogisticCosts.FuncOverIndices(plantsCarrierSources, Sum);
221          centralPlantsCentralLogisticCostsRelative[i] = centralPlantsCentralLogisticCosts[i]/finalProductAmount;
222
223          centralPlantsCentralConversionCostsRelative[i] = centralConversionCosts[i]/finalProductAmount;
224
225          var revenue = finalProductAmounts[i]*finalProductPrice;
226          var profit = revenue - finalProductCosts[i];
227          centralPlantsRoiFollowed[i] = finalProductCosts[i] == 0 ? profit : profit/finalProductCosts[i];
228
229          var totalCost = centralPlantsFeedstockCosts[i] + centralPlantsDecentralLogisticCosts[i] +
230                          centralPlantsDecentralConversionCosts[i] +
231                          centralPlantsCentralLogisticCosts[i] +
232                          centralConversionCosts[i];
233          centralPlantsRoiAggregated[i] = (revenue - totalCost)/totalCost;
234        }
235        if (feedstockSources[i] != null) { // decentral plant
236          var plantsFeedstockSources = feedstockSources[i].Select(j => j.Value).ToHashSet();
237          var carrierProductAmount = carrierProductAmounts[i];
238
239          decentralPlantsFeedstockCosts[i] = feedstockCosts.FuncOverIndices(plantsFeedstockSources, Sum);
240          decentralPlantsFeedstockCostsRelative[i] = decentralPlantsFeedstockCosts[i]/carrierProductAmount;
241
242          decentralPlantsDecentralLogisticCosts[i] = feedstockLogisticCosts.FuncOverIndices(plantsFeedstockSources, Sum);
243          decentralPlantsDecentralLogisticCostsRelative[i] = decentralPlantsDecentralLogisticCosts[i]/carrierProductAmount;
244
245          decentralPlantsDecentralConversionCostsRelative[i] = decentralConversionCosts[i]/carrierProductAmount;
246
247          var revenue = carrierProductAmounts[i]*carrierProductPrice;
248          var profit = revenue - carrierProductCosts[i];
249          decentralPlantsRoiFollowed[i] = carrierProductCosts[i] == 0 ? profit : profit/carrierProductCosts[i];
250
251          var totalCost = decentralPlantsFeedstockCosts[i] + decentralPlantsDecentralLogisticCosts[i] + decentralConversionCosts[i];
252          decentralPlantsRoiAggregated[i] = (revenue - totalCost)/totalCost;
253        }
254      }
255
256      PutInScope(LayerDescriptor.FeedstockCosts.NameWithPrefix(finalProductName), centralPlantsFeedstockCosts, false);
257      PutInScope(LayerDescriptor.FeedstockCostsRelative.NameWithPrefix(finalProductName), centralPlantsFeedstockCostsRelative, false);
258      PutInScope(LayerDescriptor.DecentralLogisticCosts.NameWithPrefix(finalProductName), centralPlantsDecentralLogisticCosts, false);
259      PutInScope(LayerDescriptor.DecentralLogisticCostsRelative.NameWithPrefix(finalProductName), centralPlantsDecentralLogisticCostsRelative, false);
260      PutInScope(LayerDescriptor.DecentralConversionCosts.NameWithPrefix(finalProductName), centralPlantsDecentralConversionCosts, false);
261      PutInScope(LayerDescriptor.DecentralConversionCostsRelative.NameWithPrefix(finalProductName), centralPlantsDecentralConversionCostsRelative, false);
262      PutInScope(LayerDescriptor.CentralLogisticCosts.NameWithPrefix(finalProductName), centralPlantsCentralLogisticCosts, false);
263      PutInScope(LayerDescriptor.CentralLogisticCostsRelative.NameWithPrefix(finalProductName), centralPlantsCentralLogisticCostsRelative, false);
264      PutInScope(LayerDescriptor.CentralConversionCostsRelative.NameWithPrefix(finalProductName), centralPlantsCentralConversionCostsRelative, false);
265      PutInScope(LayerDescriptor.RoiFollowed.NameWithPrefix(finalProductName), centralPlantsRoiFollowed, false);
266      PutInScope(LayerDescriptor.RoiAggregated.NameWithPrefix(finalProductName), centralPlantsRoiAggregated, false);
267
268      PutInScope(LayerDescriptor.FeedstockCosts.NameWithPrefix(carrier), decentralPlantsFeedstockCosts, false);
269      PutInScope(LayerDescriptor.FeedstockCostsRelative.NameWithPrefix(carrier), decentralPlantsFeedstockCostsRelative, false);
270      PutInScope(LayerDescriptor.DecentralLogisticCosts.NameWithPrefix(carrier), decentralPlantsDecentralLogisticCosts, false);
271      PutInScope(LayerDescriptor.DecentralLogisticCostsRelative.NameWithPrefix(carrier), decentralPlantsDecentralLogisticCostsRelative, false);
272      PutInScope(LayerDescriptor.DecentralConversionCostsRelative.NameWithPrefix(carrier), decentralPlantsDecentralConversionCostsRelative, false);
273      PutInScope(LayerDescriptor.RoiFollowed.NameWithPrefix(carrier), decentralPlantsRoiFollowed, false);
274      PutInScope(LayerDescriptor.RoiAggregated.NameWithPrefix(carrier), decentralPlantsRoiAggregated, false);
275    }
276
277    private void AnalyzeSingleEchelon(string feedstock, string finalProductName, ItemArray<ItemList<IntValue>> feedstockSources) {
278      var length = feedstockSources.Length;
279
280      var feedstockCosts = GetFromScope<DoubleArray>(LayerDescriptor.TotalCostsAtSource.NameWithPrefix(feedstock));
281      var feedstockLogisticCosts = GetFromScope<DoubleArray>(LayerDescriptor.TotalLogisticCosts.NameWithPrefix(feedstock));
282      var centralConversionCosts = GetFromScope<DoubleArray>(LayerDescriptor.TotalAmortizedConversionCosts.NameWithPrefix(feedstock));
283      var finalProductAmounts = GetFromScope<DoubleArray>(LayerDescriptor.AmountsAtSource.NameWithPrefix(finalProductName));
284      var finalProductCosts = GetFromScope<DoubleArray>(LayerDescriptor.TotalCostsAtSource.NameWithPrefix(finalProductName));
285      var finalProductPrice = ProblemData.Products.FirstOrDefault(p => p.Label == finalProductName).PriceAtSource;
286
287      var centralPlantsFeedstockCosts = new DoubleArray(length);
288      var centralPlantsFeedstockCostsRelative = new DoubleArray(length);
289      var centralPlantsCentralLogisticCosts = new DoubleArray(length);
290      var centralPlantsCentralLogisticCostsRelative = new DoubleArray(length);
291      var centralPlantsCentralConversionCostsRelative = new DoubleArray(length);
292      var centralPlantsRoiFollowed = new DoubleArray(length);
293      var centralPlantsRoiAggregated = new DoubleArray(length);
294
295      for (int i = 0; i < feedstockSources.Length; i++) {
296        if (feedstockSources[i] != null) {
297          var plantsFeedstockSources = feedstockSources[i].Select(j => j.Value).ToHashSet();
298          var finalProductAmount = finalProductAmounts[i];
299
300          centralPlantsFeedstockCosts[i] = feedstockCosts.FuncOverIndices(plantsFeedstockSources, Sum);
301          centralPlantsFeedstockCostsRelative[i] = centralPlantsFeedstockCosts[i]/finalProductAmount;
302
303          centralPlantsCentralLogisticCosts[i] = feedstockLogisticCosts.FuncOverIndices(plantsFeedstockSources, Sum);
304          centralPlantsCentralLogisticCostsRelative[i] = centralPlantsCentralLogisticCosts[i]/finalProductAmount;
305
306          centralPlantsCentralConversionCostsRelative[i] = centralConversionCosts[i]/finalProductAmount;
307
308          var revenue = finalProductAmounts[i]*finalProductPrice;
309          var profit = revenue - finalProductCosts[i];
310          centralPlantsRoiFollowed[i] = finalProductCosts[i] == 0 ? profit : profit/finalProductCosts[i];
311
312          var totalCost = centralPlantsFeedstockCosts[i] + centralPlantsCentralLogisticCosts[i] + centralConversionCosts[i];
313          centralPlantsRoiAggregated[i] = (revenue - totalCost)/totalCost;
314        }
315      }
316
317      PutInScope(LayerDescriptor.FeedstockCosts.NameWithPrefix(finalProductName), centralPlantsFeedstockCosts, false);
318      PutInScope(LayerDescriptor.FeedstockCostsRelative.NameWithPrefix(finalProductName), centralPlantsFeedstockCostsRelative, false);
319      PutInScope(LayerDescriptor.CentralLogisticCosts.NameWithPrefix(finalProductName), centralPlantsCentralLogisticCosts, false);
320      PutInScope(LayerDescriptor.CentralLogisticCostsRelative.NameWithPrefix(finalProductName), centralPlantsCentralLogisticCostsRelative, false);
321      PutInScope(LayerDescriptor.CentralConversionCostsRelative.NameWithPrefix(finalProductName), centralPlantsCentralConversionCostsRelative, false);
322      PutInScope(LayerDescriptor.RoiFollowed.NameWithPrefix(finalProductName), centralPlantsRoiFollowed, false);
323      PutInScope(LayerDescriptor.RoiAggregated.NameWithPrefix(finalProductName), centralPlantsRoiAggregated, false);
324
325    }
326
327    private static double Sum(IEnumerable<double> values) { return values.Sum(); }
328
329    private string GetFinalProductName(string feedstock) {
330      var productLinks = ProblemData.ProductLinks;
331      for (int i = 0; i < productLinks.Rows; i++) {
332        if (productLinks[i, 0] == feedstock)
333          return productLinks[i, 1];
334      }
335      return null;
336    }
337  }
338}
Note: See TracBrowser for help on using the repository browser.