//using System; //using System.Collections.Concurrent; //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("TtpOrchestratorNode2", "An abstract base class for an orchestrator node for the TTP.")] // [StorableClass] // public sealed class TtpOrchestratorNode2 : 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"; // private const string TspResultsResultName = "TspResults"; // private const string KspResultsResultName = "KspResults"; // private const string TtpResultsResultName = "TtpResults"; // #endregion // #region Thread Results // private object locker = new object(); // private ConcurrentDictionary tspThreadResults = new ConcurrentDictionary(); // private ConcurrentDictionary kspThreadResults = new ConcurrentDictionary(); // #endregion // #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 // #region Results // public ItemList TspResults { // get { return (ItemList)Results[TspResultsResultName].Value; } // } // public ItemList KspResults { // get { return (ItemList)Results[KspResultsResultName].Value; } // } // public ItemList TtpResults { // get { return (ItemList)Results[TtpResultsResultName].Value; } // } // #endregion // [StorableConstructor] // private TtpOrchestratorNode2(bool deserializing) : base(deserializing) { } // private TtpOrchestratorNode2(TtpOrchestratorNode2 original, Cloner cloner) : base(original, cloner) { } // public TtpOrchestratorNode2() : this("TtpOrchestratorNode2") { } // public TtpOrchestratorNode2(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"); // MetaSolverOrchestrationPort.ConnectedPortChanged += MetaSolverOrchestrationPort_ConnectedPortChanged; // TspSolverOrchestrationPort.ConnectedPortChanged += TspSolverOrchestrationPort_ConnectedPortChanged; // KspSolverOrchestrationPort.ConnectedPortChanged += KspSolverOrchestrationPort_ConnectedPortChanged; // #endregion // } // public override IDeepCloneable Clone(Cloner cloner) { // return new TtpOrchestratorNode2(this, cloner); // } // public override void Prepare() { // tspThreadResults.Clear(); // kspThreadResults.Clear(); // Results.Clear(); // Results.Add(new Result(TspResultsResultName, new ItemList())); // Results.Add(new Result(KspResultsResultName, new ItemList())); // Results.Add(new Result(TtpResultsResultName, new ItemList())); // } // public override void Start() { // var metaMsg = MetaSolverOrchestrationPort.PrepareMessage(); // metaMsg["OrchestrationMessage"] = new EnumValue(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 Pause() { // throw new NotImplementedException(); // } // public override void Stop() { // throw new NotImplementedException(); // } // 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.Start); // kspMsg["Problem"] = ksp; // KspSolverOrchestrationPort.SendMessage(kspMsg); // var kspResults = kspThreadResults[Thread.CurrentThread.ManagedThreadId]; // 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.Start); // tspMsg["Problem"] = ReduceTsp(bestKspSolution.ToArray()); // TspSolverOrchestrationPort.SendMessage(tspMsg); // var tspResults = tspThreadResults[Thread.CurrentThread.ManagedThreadId]; // var tour = (PathTSPTour)tspResults["Best TSP Solution"].Value; // tour.Coordinates = (DoubleMatrix)TspParameter.Value.Coordinates.Clone(); // tour.Quality.Value = TSPCoordinatesPathEvaluator.Apply(new TSPEuclideanPathEvaluator(), tour.Coordinates, tour.Permutation); // #region Analyze // int[] cityMapping = MapCities(loot.BinaryVector.ToArray()); // double objectiveValue = EvaluateTtp(TspParameter.Value, tour.Permutation.Select(x => cityMapping[x]).ToArray(), KspParameter.Value, loot.BinaryVector.ToArray()); // ((DoubleValue)message["Quality"]).Value = objectiveValue; // var ttpResults = new ResultCollection(); // ttpResults.Add(new Result("Quality", new DoubleValue(objectiveValue))); // ttpResults.Add(new Result("Tour", tour)); // ttpResults.Add(new Result("Loot", loot)); // lock (locker) { // TtpResults.Add(ttpResults); // TspResults.Add(tspResults); // KspResults.Add(kspResults); // 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")) { // tspThreadResults[Thread.CurrentThread.ManagedThreadId] = 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")) { // kspThreadResults[Thread.CurrentThread.ManagedThreadId] = results; // } // } // private void KspSolverEvaluationPortMessage(IMessage message) { } // #endregion // #region Helpers // private TravelingSalesmanProblem ReduceTsp(bool[] selectedItems) { // var selection = MapCities(selectedItems); // var problem = (TravelingSalesmanProblem)TspParameter.Value.Clone(); // var originalCoordinates = problem.Coordinates; // var coordinates = new DoubleMatrix(selection.Length, 2); // for (int i = 0; i < selection.Length; i++) { // coordinates[i, 0] = originalCoordinates[selection[i], 0]; // coordinates[i, 1] = originalCoordinates[selection[i], 1]; // } // problem.Coordinates = coordinates; // return problem; // } // #region Commented VariegateKsp // /* // private BinaryKnapsackProblem VariegateKsp(TravelingSalesmanProblem tsp, int[] tour, BinaryKnapsackProblem ksp, bool[] loot) { // int[] cities = Enumerable.Range(0, TspParameter.Value.SolutionCreator.LengthParameter.Value.Value).ToArray(); // int[] cityMapping = MapCities(loot); // int[] deselectedCities = cities.Except(cityMapping).ToArray(); // double quality = EvaluateTtp(tsp, tour.Select(x => cityMapping[x]).ToArray(), ksp, loot); // var increase = new HashSet(); // foreach (var dc in deselectedCities) { // var availableItems = AvailabilityParameter.Value.Select((c, i) => new { CityIdx = c, ItemIdx = i }).Where(x => x.CityIdx == dc).ToArray(); // if (!availableItems.Any()) continue; // // build new loot // bool[] newLoot = (bool[])loot.Clone(); // newLoot[availableItems[0].ItemIdx] = true; // // build new ksp // var newKsp = (BinaryKnapsackProblem)ksp.Clone(); // int avgValue = (int)Math.Round(availableItems.Average(x => newKsp.Values[x.ItemIdx])); // int avgWeight = (int)Math.Round(availableItems.Average(x => newKsp.Weights[x.ItemIdx])); // newKsp.Values[availableItems[0].ItemIdx] = avgValue; // newKsp.Weights[availableItems[0].ItemIdx] = avgWeight; // bool better = false; // for (int i = 1; i < cityMapping.Length; i++) { // // evaluate // var newCityMapping = (int[])cityMapping.Clone(); // newCityMapping[i] = dc; // double q = EvaluateTtp(tsp, tour.Select(x => newCityMapping[x]).ToArray(), newKsp, newLoot); // if (q > quality) { // better = true; // break; // } // } // if (better) // foreach (var item in availableItems) // increase.Add(item.ItemIdx); // } // var result = (BinaryKnapsackProblem)ksp.Clone(); // if (increase.Any()) { // // increase values by 5 % // foreach (var itemIndex in increase) // result.Values[itemIndex] = (int)Math.Ceiling(result.Values[itemIndex] * 1.05); // } // return result; // } // */ // #endregion // private double EvaluateTtp(TravelingSalesmanProblem tsp, int[] tour, BinaryKnapsackProblem ksp, bool[] loot) { // bool feasible; // return EvaluateTtp(tsp, tour, ksp, loot, out feasible); // } // private double EvaluateTtp(TravelingSalesmanProblem tsp, int[] tour, BinaryKnapsackProblem ksp, bool[] loot, out bool feasible) { // double collectedWeight = 0.0; // double objectiveValue = 0.0; // double infeasibleBaseLine = -1000000.0; // double speedCoefficient = (MaxSpeedParameter.Value.Value - MinSpeedParameter.Value.Value) / ksp.KnapsackCapacity.Value; // int hideoutIdx = 0; // while (tour[hideoutIdx] != 0) hideoutIdx++; // int cityIdx = (hideoutIdx + 1) % tour.Length; // int lastCityIdx = hideoutIdx; // while (cityIdx != hideoutIdx) { // double oldCollectedWeight = collectedWeight; // var availableItems = AvailabilityParameter.Value.Select((c, i) => new { CityIdx = c, ItemIdx = i }).Where(x => x.CityIdx == tour[cityIdx]); // foreach (var item in availableItems) { // if (!loot[item.ItemIdx]) continue; // collectedWeight += ksp.Weights[item.ItemIdx]; // objectiveValue += ksp.Values[item.ItemIdx]; // } // objectiveValue -= Distance(tsp.Coordinates.CloneAsMatrix(), tour[lastCityIdx], tour[cityIdx]) * RentingRatioParameter.Value.Value / // (MaxSpeedParameter.Value.Value - speedCoefficient * oldCollectedWeight); // lastCityIdx = cityIdx; // cityIdx = (cityIdx + 1) % tour.Length; // } // objectiveValue -= Distance(tsp.Coordinates.CloneAsMatrix(), tour[lastCityIdx], tour[hideoutIdx]) * RentingRatioParameter.Value.Value / // (MaxSpeedParameter.Value.Value - speedCoefficient * collectedWeight); // feasible = collectedWeight <= ksp.KnapsackCapacity.Value; // if (!feasible) objectiveValue = infeasibleBaseLine - collectedWeight; // return objectiveValue; // } // private int[] MapCities(bool[] loot) { // var map = new HashSet { 0 }; // for (int i = 0; i < loot.Length; i++) // if (loot[i]) map.Add(AvailabilityParameter.Value[i]); // return map.OrderBy(x => x).ToArray(); // } // private double Distance(double[,] coords, int fromIdx, int toIdx) { // double fromX = coords[fromIdx, 0], fromY = coords[fromIdx, 1], // toX = coords[toIdx, 0], toY = coords[toIdx, 1]; // return (int)Math.Ceiling(Math.Sqrt((toX - fromX) * (toX - fromX) + (toY - fromY) * (toY - fromY))); // } // #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 // } //}