using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Text.RegularExpressions; using HeuristicLab.BioBoost.Representation; using HeuristicLab.Data; namespace HeuristicLab.BioBoost.Views { public class SupplierCollector { public class ProductInfo { public string Name; public double Potential; public double Utilization; public double ConverterCapacity; public double StorageCapacity; public double ConversionCost; public double StorageCost; public double ConversionPlantConstructionCost; public double ConversionPlantOperationCost; public string TargetName; public IntArray TransportTargts; public DoubleArray TransportedAmounts; public DoubleArray Utilizations; public DoubleArray Potentials; public DoubleArray AcquisitionCosts; public DoubleArray DischargeCosts; public DoubleArray TransportCosts; public DoubleArray HandlingCosts; public DoubleArray RelativeProductionCosts; public DoubleArray TransportDistances; public DoubleArray Tkm; public StringArray TransportModes; public Dictionary Suppliers; public List SuppliersIndices; } public List Feedstocks { get; private set; } public List Products { get; private set; } public SupplierCollector(BioBoostCompoundSolution solution, string regionName) { Feedstocks = new List(); Products = new List(); var locidx = solution.LocationNames.IndexOfFirst(s => s == regionName); if (locidx < 0) return; var products = new Dictionary(); foreach (var kvp in solution.DoubleValues) { AddProductInfo( products, kvp.Key, LayerDescriptor.PotentialsFromProblemData.FullName, pi => { pi.Potential = kvp.Value[locidx]; pi.Potentials = kvp.Value; }); AddProductInfo( products, kvp.Key, LayerDescriptor.Utilizations.FullName, pi => { pi.Utilization = kvp.Value[locidx]; pi.Utilizations = kvp.Value; }); AddProductInfo(products, kvp.Key, LayerDescriptor.AmountsTransportedFromSource.FullName, pi => { pi.TransportedAmounts = kvp.Value; }); AddProductInfo(products, kvp.Key, LayerDescriptor.TotalCostsAtSource.FullName, pi => { pi.AcquisitionCosts = kvp.Value; }); AddProductInfo(products, kvp.Key, LayerDescriptor.DischargeCosts.FullName, pi => { pi.DischargeCosts = kvp.Value; }); //AddProductInfo(products, kvp.Key, LayerDescriptor.TotalCostsAtSource.FullName, pi => { pi.Costs = kvp.Value; }); //AddProductInfo(products, kvp.Key, LayerDescriptor.TotalCostsAtTarget.FullName, pi => { pi.Costs = kvp.Value; }); //AddProductInfo(products, kvp.Key, LayerDescriptor.Costs.FullName, pi => { pi.Costs = kvp.Value; }); //AddProductInfo(products, kvp.Key, LayerDescriptor.AmountsAtSource.FullName + LayerDescriptor.Costs.FullName, pi => { pi.Costs = Add(pi.Costs, kvp.Value); }); //AddProductInfo(products, kvp.Key, LayerDescriptor.AmountsAtTarget.FullName + LayerDescriptor.Costs.FullName, pi => { pi.Costs = Add(pi.Costs, kvp.Value); }); AddProductInfo(products, kvp.Key, LayerDescriptor.TransportCosts.FullName, pi => { pi.TransportCosts = kvp.Value; }); AddProductInfo(products, kvp.Key, LayerDescriptor.HandlingCosts.FullName, pi => { pi.HandlingCosts = kvp.Value; }); AddProductInfo(products, kvp.Key, LayerDescriptor.RelativeCostAtSource.FullName, pi => { pi.RelativeProductionCosts = kvp.Value; }); AddProductInfo(products, kvp.Key, LayerDescriptor.TransportDistance.FullName, pi => { pi.TransportDistances = kvp.Value; }); AddProductInfo(products, kvp.Key, LayerDescriptor.Tkm.FullName, pi => { pi.Tkm = kvp.Value; }); AddProductInfo(products, kvp.Key, LayerDescriptor.ConverterCapacities.FullName, pi => { pi.ConverterCapacity = kvp.Value[locidx]; }); AddProductInfo(products, kvp.Key, LayerDescriptor.StorageCapacities.FullName, pi => { pi.StorageCapacity = kvp.Value[locidx]; }); AddProductInfo(products, kvp.Key, LayerDescriptor.ConversionCosts.FullName, pi => { pi.ConversionCost = kvp.Value[locidx]; }); AddProductInfo(products, kvp.Key, LayerDescriptor.StorageCost.FullName, pi => { pi.StorageCost = kvp.Value[locidx]; }); AddProductInfo(products, kvp.Key, LayerDescriptor.ConversionPlantConstructionCost.FullName, pi => { pi.ConversionPlantConstructionCost = kvp.Value[locidx]; }); AddProductInfo(products, kvp.Key, LayerDescriptor.ConversionPlantOperationCost.FullName, pi => { pi.ConversionPlantOperationCost = kvp.Value[locidx]; }); } foreach (var kvp in solution.IntValues) { AddProductInfo( products, kvp.Key, LayerDescriptor.TransportTargets.FullName, pi => { var target = kvp.Value[locidx]; pi.TargetName = target >= 0 ? solution.LocationNames[target] : ""; pi.TransportTargts = kvp.Value; }); } if (solution.StringValues == null) { foreach (var kvp in solution.StringValues) { AddProductInfo( products, kvp.Key, LayerDescriptor.TransportModes.FullName, pi => { pi.TransportModes = kvp.Value; }); } } foreach (var product in products.Values) { product.Suppliers = new Dictionary(); product.SuppliersIndices = new List(); Products.Add(product); if (product.Potentials != null) Feedstocks.Add(product); if (product.TransportTargts == null) { product.Suppliers.Add(solution.LocationNames[locidx], 0); product.SuppliersIndices.Add(locidx); } else { for (int i = 0; i < product.TransportTargts.Length; i++) { if (product.TransportTargts[i] != locidx) continue; var amount = 1d; if (product.TransportedAmounts != null) { amount = product.TransportedAmounts[i]; } else if (product.Potentials != null && product.Utilizations != null) { amount = product.Potentials[i]*product.Utilizations[i]; } if (amount > 0) { product.SuppliersIndices.Add(i); product.Suppliers.Add(solution.LocationNames[i], amount); } } } } } private static readonly Regex nameSplitter = new Regex(@"([^ ]+)( .*)"); private void AddProductInfo(Dictionary dict, string name, string suffix, Action setter) { var match = nameSplitter.Match(name); if (!match.Success) return; if (!match.Groups[2].Success || match.Groups[2].Value != suffix) return; var productName = match.Groups[1].Value; ProductInfo info; if (!dict.TryGetValue(productName, out info)) { info = new ProductInfo { Name = productName }; dict.Add(productName, info); } setter(info); } private static DoubleArray Add(DoubleArray a, DoubleArray b) { if (a == null) return b; if (b == null) return a; Debug.Assert(a.Length == b.Length); var result = new DoubleArray(a.Length); for (int i = 0; i < a.Length; i++) { result[i] = a[i] + b[i]; } return result; } } }