#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
}
}