#region License Information
/* HeuristicLab
* Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HeuristicLab is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with HeuristicLab. If not, see .
*/
#endregion
using System;
using System.Collections.Generic;
using System.Diagnostics;
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;
}
}
}