using System; using System.Collections.Generic; using System.Linq; using System.Threading; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Core.Networks; using HeuristicLab.Data; using HeuristicLab.Encodings.BinaryVectorEncoding; using HeuristicLab.Encodings.PermutationEncoding; using HeuristicLab.Encodings.RealVectorEncoding; using HeuristicLab.Operators; using HeuristicLab.Optimization; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Problems.Knapsack; using HeuristicLab.Problems.TravelingSalesman; namespace HeuristicLab.Networks.IntegratedOptimization { [Item("TtpOrchestratorNode5", "An abstract base class for an orchestrator node for the TTP.")] [StorableClass] public sealed class TtpOrchestratorNode5 : OrchestratorNode { #region Constants private const string TspParameterName = "TSP"; private const string KspParameterName = "KSP"; private const string AvailabilityParameterName = "Availability"; private const string MinSpeedParameterName = "MinSpeed"; private const string MaxSpeedParameterName = "MaxSpeed"; private const string RentingRatioParameterName = "RentingRatio"; private const string IterationsParameterName = "Iterations"; private const string MetaSolverName = "MetaSolver"; private const string TspSolverName = "TspSolver"; private const string KspSolverName = "KspSolver"; #endregion [Storable] private ResultCollection tspResults, kspResults; private CancellationTokenSource cts; #region Parameters public IValueParameter IterationsParameter { get { return (IValueParameter)Parameters[IterationsParameterName]; } } 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]; } } public IMessagePort MetaSolverEvaluationPort { get { return (IMessagePort)Ports[MetaSolverName + EvaluationPortNameSuffix]; } } public IMessagePort TspSolverOrchestrationPort { get { return (IMessagePort)Ports[TspSolverName + OrchestrationPortNameSuffix]; } } public IMessagePort TspSolverEvaluationPort { get { return (IMessagePort)Ports[TspSolverName + EvaluationPortNameSuffix]; } } public IMessagePort KspSolverOrchestrationPort { get { return (IMessagePort)Ports[KspSolverName + OrchestrationPortNameSuffix]; } } public IMessagePort KspSolverEvaluationPort { get { return (IMessagePort)Ports[KspSolverName + EvaluationPortNameSuffix]; } } #endregion [StorableConstructor] private TtpOrchestratorNode5(bool deserializing) : base(deserializing) { } private TtpOrchestratorNode5(TtpOrchestratorNode5 original, Cloner cloner) : base(original, cloner) { RegisterEvents(); } public TtpOrchestratorNode5() : this("TtpOrchestratorNode5") { } public TtpOrchestratorNode5(string name) : base(name) { #region Configure Parameters Parameters.Add(new ValueParameter(IterationsParameterName, new IntValue(20))); 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))); #endregion #region Configure Ports AddOrchestrationPort(MetaSolverName); AddEvaluationPort(MetaSolverName, "RealVector", "Quality"); AddOrchestrationPort(TspSolverName); AddEvaluationPort(TspSolverName, "TSPTour", "TSPTourLength"); AddOrchestrationPort(KspSolverName); AddEvaluationPort(KspSolverName, "KnapsackSolution", "Quality"); RegisterEvents(); #endregion } public override IDeepCloneable Clone(Cloner cloner) { return new TtpOrchestratorNode5(this, cloner); } [StorableHook(HookType.AfterDeserialization)] private void AfterDeserialization() { RegisterEvents(); } private void RegisterEvents() { MetaSolverOrchestrationPort.ConnectedPortChanged += MetaSolverOrchestrationPort_ConnectedPortChanged; TspSolverOrchestrationPort.ConnectedPortChanged += TspSolverOrchestrationPort_ConnectedPortChanged; KspSolverOrchestrationPort.ConnectedPortChanged += KspSolverOrchestrationPort_ConnectedPortChanged; } public override void Prepare() { Results.Clear(); var metaMsg = MetaSolverOrchestrationPort.PrepareMessage(); metaMsg["OrchestrationMessage"] = new EnumValue(OrchestrationMessage.Prepare | OrchestrationMessage.QualityAdaption); var problem = new VariegationProblem(); problem.Encoding.Length = KspParameter.Value.Length; problem.Encoding.Bounds = new DoubleMatrix(new[,] { { -1.0, 1.0 } }); metaMsg["Problem"] = problem; MetaSolverOrchestrationPort.SendMessage(metaMsg); } public override void Start() { cts = new CancellationTokenSource(); try { var metaMsg = MetaSolverOrchestrationPort.PrepareMessage(); metaMsg["OrchestrationMessage"] = new EnumValue(OrchestrationMessage.Start); MetaSolverOrchestrationPort.SendMessage(metaMsg); } catch (Exception e) { } } 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(TspSolverEvaluationPort, TspSolverEvaluationPortMessage); messageActions.Add(KspSolverOrchestrationPort, KspSolverOrchestrationPortMessage); messageActions.Add(KspSolverEvaluationPort, KspSolverEvaluationPortMessage); messageActions[port](message); base.ProcessMessage(message, port, token); } #region MetaSolver Message Handling private void MetaSolverOrchestrationPortMessage(IMessage message) { } private void MetaSolverEvaluationPortMessage(IMessage message) { var factors = (RealVector)message["RealVector"]; var ksp = (BinaryKnapsackProblem)KspParameter.Value.Clone(); for (int i = 0; i < factors.Length; i++) ksp.Values[i] = (int)Math.Ceiling(ksp.Values[i] * factors[i]); var kspMsg = KspSolverOrchestrationPort.PrepareMessage(); kspMsg["OrchestrationMessage"] = new EnumValue(OrchestrationMessage.Prepare | OrchestrationMessage.Start); kspMsg["Problem"] = ksp; KspSolverOrchestrationPort.SendMessage(kspMsg); cts.Token.ThrowIfCancellationRequested(); var bestKspSolution = (BinaryVector)kspResults["Best Solution"].Value; var kspCapacity = (IntValue)KspParameter.Value.KnapsackCapacity.Clone(); var kspPenalty = new DoubleValue(0.0); var kspWeights = (IntArray)KspParameter.Value.Weights.Clone(); var kspValues = (IntArray)KspParameter.Value.Values.Clone(); var bestKspQuality = KnapsackEvaluator.Apply(bestKspSolution, kspCapacity, kspPenalty, kspWeights, kspValues).Quality; var loot = new KnapsackSolution(bestKspSolution, bestKspQuality, kspCapacity, kspWeights, kspValues); kspResults.Add(new Result("Best KSP Solution", loot)); var tspMsg = TspSolverOrchestrationPort.PrepareMessage(); tspMsg["OrchestrationMessage"] = new EnumValue(OrchestrationMessage.Prepare | OrchestrationMessage.Start); var tpp = new TourProfitProblem { Tsp = (TravelingSalesmanProblem)TspParameter.Value.Clone(), Ksp = (BinaryKnapsackProblem)KspParameter.Value.Clone(), FixedKspSolution = bestKspSolution, Availability = AvailabilityParameter.Value.ToArray(), RentingRatio = RentingRatioParameter.Value.Value, MinSpeed = MinSpeedParameter.Value.Value, MaxSpeed = MaxSpeedParameter.Value.Value }; tpp.Encoding.Length = TspParameter.Value.Coordinates.Rows; tspMsg["Problem"] = tpp; TspSolverOrchestrationPort.SendMessage(tspMsg); cts.Token.ThrowIfCancellationRequested(); var bestTspSolution = (Permutation)tspResults["Best TSP Solution"].Value; var coordinates = (DoubleMatrix)TspParameter.Value.Coordinates.Clone(); var tour = new PathTSPTour(coordinates, bestTspSolution, new DoubleValue(TSPCoordinatesPathEvaluator.Apply(new TSPEuclideanPathEvaluator(), coordinates, bestTspSolution))); #region Analyze double objectiveValue = TtpUtils.EvaluateTtp(TspParameter.Value, tour.Permutation.ToArray(), KspParameter.Value, loot.BinaryVector.ToArray(), AvailabilityParameter.Value.ToArray(), RentingRatioParameter.Value.Value, MinSpeedParameter.Value.Value, MaxSpeedParameter.Value.Value); ((DoubleValue)message["Quality"]).Value = objectiveValue; IResult bestQuality; if (!Results.TryGetValue("Best TTP Quality", out bestQuality)) { Results.Add(new Result("Best TTP Quality", new DoubleValue(objectiveValue))); Results.Add(new Result("Best Tour", tour)); Results.Add(new Result("Best Loot", loot)); } else if (((DoubleValue)bestQuality.Value).Value < objectiveValue) { ((DoubleValue)bestQuality.Value).Value = objectiveValue; Results["Best Tour"].Value = tour; Results["Best Loot"].Value = loot; } #endregion } #endregion #region TspSolver Message Handling private void TspSolverOrchestrationPortMessage(IMessage message) { var results = (ResultCollection)message["Results"]; if (results.ContainsKey("Best TSP Solution")) { tspResults = results; } } private void TspSolverEvaluationPortMessage(IMessage message) { } #endregion #region KspSolver Message Handling private void KspSolverOrchestrationPortMessage(IMessage message) { var results = (ResultCollection)message["Results"]; if (results.ContainsKey("Best Solution")) { kspResults = results; } } private void KspSolverEvaluationPortMessage(IMessage message) { } #endregion #region Event Handlers private 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; } private void TspSolverOrchestrationPort_ConnectedPortChanged(object sender, EventArgs e) { if (TspSolverOrchestrationPort.ConnectedPort == null) return; var node = TspSolverOrchestrationPort.ConnectedPort.Parent as OrchestratedAlgorithmNode; if (node == null) return; var hook = new HookOperator { Name = "TSP Eval Hook" }; hook.Parameters.Add(new LookupParameter("TSPTour") { Hidden = true }); hook.Parameters.Add(new LookupParameter("TSPTourLength") { Hidden = true }); node.EvalHook = hook; node.OrchestrationPort.CloneParametersFromPort(TspSolverOrchestrationPort); node.EvaluationPort.CloneParametersFromPort(TspSolverEvaluationPort); node.EvaluationPort.ConnectedPort = TspSolverEvaluationPort; } private void KspSolverOrchestrationPort_ConnectedPortChanged(object sender, EventArgs e) { if (KspSolverOrchestrationPort.ConnectedPort == null) return; var node = KspSolverOrchestrationPort.ConnectedPort.Parent as OrchestratedAlgorithmNode; if (node == null) return; var hook = new HookOperator { Name = "KSP Eval Hook" }; hook.Parameters.Add(new LookupParameter("KnapsackSolution") { Hidden = true }); hook.Parameters.Add(new LookupParameter("Quality") { Hidden = true }); node.EvalHook = hook; node.OrchestrationPort.CloneParametersFromPort(KspSolverOrchestrationPort); node.EvaluationPort.CloneParametersFromPort(KspSolverEvaluationPort); node.EvaluationPort.ConnectedPort = KspSolverEvaluationPort; } #endregion } }