using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Optimization; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using System.Linq; using HeuristicLab.BioBoost.Representation; namespace HeuristicLab.BioBoost.Evaluators { [StorableClass] public class SinkEvaluator : BioBoostEvaluator { #region Construction & Cloning [StorableConstructor] protected SinkEvaluator(bool isDeserializing) : base(isDeserializing) {} protected SinkEvaluator(SinkEvaluator original, Cloner cloner) : base(original, cloner) { } public SinkEvaluator() { Parameters.Add(new ScopeParameter("Scope", "The scope to search products in.")); } public override IDeepCloneable Clone(Cloner cloner) { return new SinkEvaluator(this, cloner); } #endregion private static LayerDescriptor emptyLayerDescriptor = new LayerDescriptor("", "", ""); public override IOperation Apply() { foreach (var product in ProblemData.Products) { InvoiceProduct(product.Label, product.Price, emptyLayerDescriptor, LayerDescriptor.DischargeCosts); InvoiceProduct(product.Label, product.PriceAtSource, LayerDescriptor.AmountsAtSource, LayerDescriptor.TotalCostsAtSource); InvoiceProduct(product.Label, product.PriceAtTarget, LayerDescriptor.AmountsAtTarget, LayerDescriptor.TotalCostsAtTarget); } return base.Apply(); } private void InvoiceProduct(string productName, double price, LayerDescriptor amountLayerDescriptor, LayerDescriptor costLayerDescriptor) { var variables = ExecutionContext.Scope.Variables; IVariable amountVariable, costsVariable; if (!variables.TryGetValue(amountLayerDescriptor.NameWithPrefix(productName), out amountVariable)) return; var amounts = amountVariable.Value as DoubleArray; if (amounts == null) return; var relativeProductionCosts = new DoubleArray(amounts.Length); DoubleArray productionCosts = null; if (variables.TryGetValue(costLayerDescriptor.NameWithPrefix(productName), out costsVariable)) { productionCosts = costsVariable.Value as DoubleArray; } var totalCost = amounts.Sum()*-price; var length = amounts.Length; var costs = new DoubleArray(length); for (int i = 0; i < length; i++) { costs[i] = amounts[i]*-price; if (productionCosts != null && amounts[i] != 0) relativeProductionCosts[i] = productionCosts[i]/amounts[i]; } if (totalCost != 0) { AddInScope(LayerDescriptor.DischargeCosts.NameWithPrefix(productName), costs, false); Costs.Add(new Result(costLayerDescriptor.NameWithPrefix(productName), new DoubleValue(totalCost))); if (totalCost > 0) AddInScope(LayerDescriptor.LocalAddedValue.Name, costs, false); } } } }