source: branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost/3.3/Evaluators/FeedstockCostEvaluator.cs @ 13069

Last change on this file since 13069 was 13069, checked in by gkronber, 7 years ago

#2499: imported source code for HeuristicLab.BioBoost from private repository with some changes

File size: 3.8 KB
Line 
1using HeuristicLab.BioBoost.Data;
2using HeuristicLab.Common;
3using HeuristicLab.Core;
4using HeuristicLab.Data;
5using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
6using System;
7using System.Linq;
8using HeuristicLab.BioBoost.Representation;
9using HeuristicLab.BioBoost.Utils;
10
11namespace HeuristicLab.BioBoost.Evaluators {
12
13  [StorableClass]
14  [Item("FeedstockCostEvaluator", @"Calculates all feedstock costs for known products,
15for which both <Product.Label>Potentials and <Product.Label>Utilizations are available.
16The intermedate results are vectors of amounts and costs per product and region and a
17final output named <Product.Label>Cost for each product.")]
18  public class FeedstockCostEvaluator : BioBoostEvaluator {
19
20    #region Construction & Cloning
21    [StorableConstructor]
22    protected FeedstockCostEvaluator(bool isDeserializing) : base(isDeserializing) { }
23    protected FeedstockCostEvaluator(FeedstockCostEvaluator original, Cloner cloner) : base(original, cloner) { }
24    public FeedstockCostEvaluator() { }
25    public override IDeepCloneable Clone(Cloner cloner) {
26      return new FeedstockCostEvaluator(this, cloner);
27    }
28    #endregion
29
30    /// <summary>
31    /// foreach product with both potential and utilization calculate
32    /// amounts = potential*utilization
33    /// costs = amounts*price*penalty(utilization)
34    /// cost = sum(costs)
35    /// </summary>
36    public override IOperation Apply() {
37      foreach (var p in ProblemData.Products) {
38        var totalProductCost = 0d;
39        var potentials = GetFromProblemData<DoubleArray>(LayerDescriptor.PotentialsFromProblemData.NameWithPrefix(p.Label));
40        var utilizations = GetFromScope<DoubleArray>(LayerDescriptor.Utilizations.NameWithPrefix(p.Label));
41        if (potentials == null || utilizations == null) continue;
42        var utilizationsEffective = (DoubleArray)utilizations.Clone();
43        var length = Math.Min(potentials.Length, utilizations.Length);
44        var amountsAtSource = new DoubleArray(length);
45        var feedstockCosts = new DoubleArray(length);
46       
47        // price/supply curve quadr. for utilization > 0.5
48        for (var i = 0; i < length; i++) {
49          var regionName = ProblemData.LocationNames[i];
50          var amount = potentials[i] * utilizations[i];
51          if (amount < 100) { // TODO: make this configurable
52            utilizationsEffective[i] = 0;
53            amount = 0;
54          }
55          amountsAtSource[i] = amount;
56          var cost = GetScaledCost(
57            p.GetRegionalBasePrice(regionName),
58            p.GetRegionalMaxPrice(regionName),
59            amount, utilizations[i]);
60          feedstockCosts[i] = cost;
61          totalProductCost += cost;
62        }
63
64        PutInScope(LayerDescriptor.UtilizationsEffective.NameWithPrefix(p.Label), utilizationsEffective, false);
65        PutInScope(LayerDescriptor.AmountsAtSource.NameWithPrefix(p.Label), amountsAtSource, true);
66        PutInScope(LayerDescriptor.TotalCostsAtSource.NameWithPrefix(p.Label) , feedstockCosts, false);
67        PutInScope(LayerDescriptor.RelativeCostAtSource.NameWithPrefix(p.Label), feedstockCosts.Zip(amountsAtSource, (c,a) => a == 0 ? 0 : c/a).ToDoubleArray(), false);
68        AddCost(LayerDescriptor.AcquisitionCosts.NameWithPrefix(p.Label), totalProductCost);     
69        AddInScope(LayerDescriptor.LocalAddedValue.Name, (DoubleArray)feedstockCosts.Clone(), false);
70      }
71         
72      return base.Apply();
73    }
74
75    public static double GetScaledCost(double basePrice, double maxPrice, double amount, double utilization) {
76      if (utilization > 0.5) {
77        var priceDifference = maxPrice - basePrice;
78         return amount*(priceDifference*Math.Pow((utilization - 0.5)*2, 2) + basePrice);
79      } else {
80       return amount*basePrice;
81      }
82    }
83  }
84}
Note: See TracBrowser for help on using the repository browser.