#region License Information /* HeuristicLab * Copyright (C) 2002-2017 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.Threading; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Core.Networks; using HeuristicLab.Data; using HeuristicLab.Encodings.RealVectorEncoding; using HeuristicLab.Operators; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Problems.TravelingSalesman; namespace HeuristicLab.Networks.IntegratedOptimization.TravelingThief { [Item("TtpOrchestratorNode", "An abstract base class for orchestrators used in TTP optimization networks.")] [StorableClass] public abstract class TtpOrchestratorNode : OrchestratorNode { #region Constants protected const string InstanceParameterName = "Instance"; protected const string TspParameterName = "TSP"; protected const string KspParameterName = "KSP"; protected const string AvailabilityParameterName = "Availability"; protected const string MinSpeedParameterName = "MinSpeed"; protected const string MaxSpeedParameterName = "MaxSpeed"; protected const string RentingRatioParameterName = "RentingRatio"; protected const string MetaSolverName = "MetaSolver"; protected const string TspSolverName = "TspSolver"; protected const string KspSolverName = "KspSolver"; protected const string OrchestrationPortNameSuffix = "OrchestrationPort"; protected const string EvaluationPortNameSuffix = "EvaluationPort"; #endregion protected CancellationTokenSource cts; [Storable] protected double[,] tspCoordinates = new double[0, 0]; [Storable] protected TtpUtils.DistanceType distanceType; [Storable] protected int kspCapacity; [Storable] protected int[] kspItemWeights = new int[0], kspItemValues = new int[0], ttpAvailability = new int[0]; [Storable] protected double ttpMinSpeed, ttpMaxSpeed, ttpRentingRatio; #region Parameters public IFixedValueParameter InstanceParameter { get { return (IFixedValueParameter)Parameters[InstanceParameterName]; } } public IValueParameter TspParameter { get { return (IValueParameter)Parameters[TspParameterName]; } } public IValueParameter KspParameter { get { return (IValueParameter)Parameters[KspParameterName]; } } public IValueParameter AvailabilityParameter { get { return (IValueParameter)Parameters[AvailabilityParameterName]; } } public IValueParameter MinSpeedParameter { get { return (IValueParameter)Parameters[MinSpeedParameterName]; } } public IValueParameter MaxSpeedParameter { get { return (IValueParameter)Parameters[MaxSpeedParameterName]; } } public IValueParameter RentingRatioParameter { get { return (IValueParameter)Parameters[RentingRatioParameterName]; } } #endregion #region Ports public IMessagePort MetaSolverOrchestrationPort { get { return (IMessagePort)Ports[MetaSolverName + OrchestrationPortNameSuffix]; } protected set { string portName = MetaSolverName + OrchestrationPortNameSuffix; if (Ports.ContainsKey(portName)) throw new InvalidOperationException(portName + " already set."); Ports.Add(value); value.ConnectedPortChanged += MetaSolverOrchestrationPort_ConnectedPortChanged; } } public IMessagePort MetaSolverEvaluationPort { get { return (IMessagePort)Ports[MetaSolverName + EvaluationPortNameSuffix]; } protected set { string portName = MetaSolverName + EvaluationPortNameSuffix; if (Ports.ContainsKey(portName)) throw new InvalidOperationException(portName + " already set."); Ports.Add(value); } } public IMessagePort TspSolverOrchestrationPort { get { return (IMessagePort)Ports[TspSolverName + OrchestrationPortNameSuffix]; } protected set { string portName = TspSolverName + OrchestrationPortNameSuffix; if (Ports.ContainsKey(portName)) throw new InvalidOperationException(portName + " already set."); Ports.Add(value); value.ConnectedPortChanged += TspSolverOrchestrationPort_ConnectedPortChanged; } } public IMessagePort TspSolverEvaluationPort { get { return (IMessagePort)Ports[TspSolverName + EvaluationPortNameSuffix]; } protected set { string portName = TspSolverName + EvaluationPortNameSuffix; if (Ports.ContainsKey(portName)) throw new InvalidOperationException(portName + " already set."); Ports.Add(value); } } public IMessagePort KspSolverOrchestrationPort { get { return (IMessagePort)Ports[KspSolverName + OrchestrationPortNameSuffix]; } protected set { string portName = KspSolverName + OrchestrationPortNameSuffix; if (Ports.ContainsKey(portName)) throw new InvalidOperationException(portName + " already set."); Ports.Add(value); value.ConnectedPortChanged += KspSolverOrchestrationPort_ConnectedPortChanged; } } public IMessagePort KspSolverEvaluationPort { get { return (IMessagePort)Ports[KspSolverName + EvaluationPortNameSuffix]; } protected set { string portName = KspSolverName + EvaluationPortNameSuffix; if (Ports.ContainsKey(portName)) throw new InvalidOperationException(portName + " already set."); Ports.Add(value); } } #endregion [StorableConstructor] protected TtpOrchestratorNode(bool deserializing) : base(deserializing) { } protected TtpOrchestratorNode(TtpOrchestratorNode original, Cloner cloner) : base(original, cloner) { tspCoordinates = (double[,])original.tspCoordinates.Clone(); kspCapacity = original.kspCapacity; kspItemWeights = (int[])original.kspItemWeights.Clone(); kspItemValues = (int[])original.kspItemValues.Clone(); ttpAvailability = (int[])original.ttpAvailability.Clone(); ttpMinSpeed = original.ttpMinSpeed; ttpMaxSpeed = original.ttpMaxSpeed; ttpRentingRatio = original.ttpRentingRatio; RegisterEvents(); } protected TtpOrchestratorNode() : this("TtpOrchestratorNode") { } protected TtpOrchestratorNode(string name) : base(name) { Parameters.Add(new FixedValueParameter(InstanceParameterName)); Parameters.Add(new ValueParameter(TspParameterName, new TravelingSalesmanProblem())); Parameters.Add(new ValueParameter(KspParameterName, new BinaryKnapsackProblem())); Parameters.Add(new ValueParameter(AvailabilityParameterName)); Parameters.Add(new ValueParameter(MinSpeedParameterName, new DoubleValue(0.1))); Parameters.Add(new ValueParameter(MaxSpeedParameterName, new DoubleValue(1.0))); Parameters.Add(new ValueParameter(RentingRatioParameterName, new DoubleValue(0.5))); InstanceParameter.Value.ToStringChanged += InstanceParameter_Value_ToStringChanged; } [StorableHook(HookType.AfterDeserialization)] private void AfterDeserialization() { RegisterEvents(); } private void RegisterEvents() { InstanceParameter.Value.ToStringChanged += InstanceParameter_Value_ToStringChanged; MetaSolverOrchestrationPort.ConnectedPortChanged += MetaSolverOrchestrationPort_ConnectedPortChanged; TspSolverOrchestrationPort.ConnectedPortChanged += TspSolverOrchestrationPort_ConnectedPortChanged; KspSolverOrchestrationPort.ConnectedPortChanged += KspSolverOrchestrationPort_ConnectedPortChanged; } private void InstanceParameter_Value_ToStringChanged(object sender, EventArgs e) { string filePath = InstanceParameter.Value.Value; TtpUtils.Import(filePath, out tspCoordinates, out distanceType, out kspCapacity, out kspItemValues, out kspItemWeights, out ttpAvailability, out ttpMinSpeed, out ttpMaxSpeed, out ttpRentingRatio); var tsp = TspParameter.Value; tsp.Coordinates = new DoubleMatrix(tspCoordinates); tsp.DistanceMatrix = new DistanceMatrix(TtpUtils.GetDistances(tsp.Coordinates, distanceType)); var ksp = KspParameter.Value; ksp.KnapsackCapacity.Value = kspCapacity; ksp.Encoding.Length = kspItemValues.Length; ksp.Values = new IntArray(kspItemValues); ksp.Weights = new IntArray(kspItemWeights); AvailabilityParameter.Value = new IntArray(ttpAvailability); MinSpeedParameter.Value.Value = ttpMinSpeed; MaxSpeedParameter.Value.Value = ttpMaxSpeed; RentingRatioParameter.Value.Value = ttpRentingRatio; Prepare(); } protected virtual void MetaSolverOrchestrationPort_ConnectedPortChanged(object sender, EventArgs e) { if (MetaSolverOrchestrationPort.ConnectedPort == null) return; var node = MetaSolverOrchestrationPort.ConnectedPort.Parent as OrchestratedAlgorithmNode; if (node == null) return; var hook = new HookOperator { Name = "Meta Eval Hook" }; hook.Parameters.Add(new LookupParameter("RealVector") { Hidden = true }); hook.Parameters.Add(new LookupParameter("Quality") { Hidden = true }); node.EvalHook = hook; node.OrchestrationPort.CloneParametersFromPort(MetaSolverOrchestrationPort); node.EvaluationPort.CloneParametersFromPort(MetaSolverEvaluationPort); node.EvaluationPort.ConnectedPort = MetaSolverEvaluationPort; } protected virtual void TspSolverOrchestrationPort_ConnectedPortChanged(object sender, EventArgs e) { if (TspSolverOrchestrationPort.ConnectedPort == null) return; var node = TspSolverOrchestrationPort.ConnectedPort.Parent as OrchestratedAlgorithmNode; if (node == null) return; node.OrchestrationPort.CloneParametersFromPort(TspSolverOrchestrationPort); } protected virtual void KspSolverOrchestrationPort_ConnectedPortChanged(object sender, EventArgs e) { if (KspSolverOrchestrationPort.ConnectedPort == null) return; var node = KspSolverOrchestrationPort.ConnectedPort.Parent as OrchestratedAlgorithmNode; if (node == null) return; node.OrchestrationPort.CloneParametersFromPort(KspSolverOrchestrationPort); } public override void Prepare(bool clearRuns = false) { Results.Clear(); } public override void Start() { cts = new CancellationTokenSource(); var metaMsg = MetaSolverOrchestrationPort.PrepareMessage(); metaMsg["OrchestrationMessage"] = new EnumValue(OrchestrationMessage.Start); MetaSolverOrchestrationPort.SendMessage(metaMsg); } public override void Pause() { cts.Cancel(); var metaMsg = MetaSolverOrchestrationPort.PrepareMessage(); metaMsg["OrchestrationMessage"] = new EnumValue(OrchestrationMessage.Pause); MetaSolverOrchestrationPort.SendMessage(metaMsg); var tspMsg = TspSolverOrchestrationPort.PrepareMessage(); tspMsg["OrchestrationMessage"] = new EnumValue(OrchestrationMessage.Stop); TspSolverOrchestrationPort.SendMessage(tspMsg); var kspMsg = KspSolverOrchestrationPort.PrepareMessage(); kspMsg["OrchestrationMessage"] = new EnumValue(OrchestrationMessage.Stop); KspSolverOrchestrationPort.SendMessage(kspMsg); } public override void Stop() { cts.Cancel(); var metaMsg = MetaSolverOrchestrationPort.PrepareMessage(); metaMsg["OrchestrationMessage"] = new EnumValue(OrchestrationMessage.Stop); MetaSolverOrchestrationPort.SendMessage(metaMsg); var tspMsg = TspSolverOrchestrationPort.PrepareMessage(); tspMsg["OrchestrationMessage"] = new EnumValue(OrchestrationMessage.Stop); TspSolverOrchestrationPort.SendMessage(tspMsg); var kspMsg = KspSolverOrchestrationPort.PrepareMessage(); kspMsg["OrchestrationMessage"] = new EnumValue(OrchestrationMessage.Stop); KspSolverOrchestrationPort.SendMessage(kspMsg); } protected override void ProcessMessage(IMessage message, IMessagePort port, CancellationToken token) { var messageActions = new Dictionary>(); messageActions.Add(MetaSolverOrchestrationPort, MetaSolverOrchestrationPortMessage); messageActions.Add(MetaSolverEvaluationPort, MetaSolverEvaluationPortMessage); messageActions.Add(TspSolverOrchestrationPort, TspSolverOrchestrationPortMessage); messageActions.Add(KspSolverOrchestrationPort, KspSolverOrchestrationPortMessage); messageActions[port](message); base.ProcessMessage(message, port, token); } #region MetaSolver Message Handling protected virtual void MetaSolverOrchestrationPortMessage(IMessage message) { } protected virtual void MetaSolverEvaluationPortMessage(IMessage message) { } #endregion #region TspSolver Message Handling protected virtual void TspSolverOrchestrationPortMessage(IMessage message) { } protected virtual void TspSolverEvaluationPortMessage(IMessage message) { } #endregion #region KspSolver Message Handling protected virtual void KspSolverOrchestrationPortMessage(IMessage message) { } private void KspSolverEvaluationPortMessage(IMessage message) { } #endregion } }