#region License Information /* HeuristicLab * Copyright (C) 2002-2014 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 HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Encodings.BinaryVectorEncoding; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using System.Linq; namespace HeuristicLab.Optimization.Networks { [Item("KSPTSPConnector", "A node of an optimization network which connects a KSP and a TSP.")] [StorableClass] public class KSPTSPConnector : Node { [StorableConstructor] protected KSPTSPConnector(bool deserializing) : base(deserializing) { } protected KSPTSPConnector(KSPTSPConnector original, Cloner cloner) : base(original, cloner) { } public KSPTSPConnector() : base("KSPTSPConnector") { Initialize(); } public KSPTSPConnector(string name) : base(name) { Initialize(); } public KSPTSPConnector(string name, string description) : base(name, description) { Initialize(); } public override IDeepCloneable Clone(Cloner cloner) { return new KSPTSPConnector(this, cloner); } protected virtual void Initialize() { var parameters = new GenericPort("Parameters"); Ports.Add(parameters); parameters.Parameters.Add(new PortParameter("Cities") { Type = PortParameterType.Input }); parameters.Parameters.Add(new PortParameter("TransportCostsFactor") { Type = PortParameterType.Input }); var ksp = new GenericPort("KSP Connector"); Ports.Add(ksp); ksp.Parameters.Add(new PortParameter("KnapsackSolution") { Type = PortParameterType.Input }); ksp.Parameters.Add(new PortParameter("Quality") { Type = PortParameterType.Input | PortParameterType.Output }); ksp.Parameters.Add(new PortParameter("TransportCosts") { Type = PortParameterType.Output }); ksp.MessageReceived += Knapsack_MessageReceived; var tsp = new GenericPort("TSP Connector"); Ports.Add(tsp); tsp.Parameters.Add(new PortParameter("Coordinates") { Type = PortParameterType.Output }); ksp.Parameters.Add(new PortParameter("BestQuality") { Type = PortParameterType.Input }); } protected virtual void Knapsack_MessageReceived(object sender, EventArgs e) { // get parameters var parametersPort = (IGenericPort)Ports["Parameters"]; var parameters = parametersPort.PrepareMessage(); parametersPort.SendMessage(parameters, e.Value2); var cities = (DoubleMatrix)parameters["Cities"]; var factor = ((DoubleValue)parameters["TransportCostsFactor"]).Value; // build coordinates var kspMsg = e.Value; var kspSolution = (BinaryVector)kspMsg["KnapsackSolution"]; var kspQuality = ((DoubleValue)kspMsg["Quality"]).Value; var coords = new DoubleMatrix(kspSolution.Count(x => x), 2); int j = 0; for (int i = 0; i < kspSolution.Length; i++) { if (kspSolution[i]) { coords[j, 0] = cities[i, 0]; coords[j, 1] = cities[i, 1]; j++; } } // solve TSP var tspConnectorPort = (IGenericPort)Ports["TSP Connector"]; var tspMsg = tspConnectorPort.PrepareMessage(); tspMsg["Coordinates"] = coords; tspConnectorPort.SendMessage(tspMsg, e.Value2); var tspQuality = ((DoubleValue)tspMsg["BestQuality"]).Value; // calculate transport costs ((DoubleValue)kspMsg["Quality"]).Value = kspQuality - factor * tspQuality; kspMsg["TransportCosts"] = new DoubleValue(factor * tspQuality); } } }