- Timestamp:
- 01/26/15 15:52:03 (9 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/OptimizationNetworks/HeuristicLab.Networks/3.3/KSPTSPControlCode.cs
r11711 r11823 20 20 #endregion 21 21 22 using System; 23 using System.Drawing; 24 using System.Linq; 25 using System.Threading; 22 26 using HeuristicLab.Common; 23 27 using HeuristicLab.Core; … … 25 29 using HeuristicLab.Data; 26 30 using HeuristicLab.Encodings.BinaryVectorEncoding; 31 using HeuristicLab.Encodings.PermutationEncoding; 27 32 using HeuristicLab.Networks.Programmable; 33 using HeuristicLab.Problems.Knapsack; 28 34 using HeuristicLab.Problems.TravelingSalesman; 29 using System.Drawing;30 using System.Linq;31 using System.Threading;32 35 33 36 namespace HeuristicLab.Networks { 34 [Item("KSPTSPConnector", "A node of an optimization network which connects a KSP and a TSP.")] 35 public class CompiledKSPTSPConnector : ProgrammableNode.CompiledProgrammableNode { 37 [Item("KSPTSPControl", "A node of an optimization network which connects a KSP and a TSP.")] 38 public class CompiledKSPTSPControl : ProgrammableNode.CompiledProgrammableNode { 39 36 40 public static new Image StaticItemImage { 37 41 get { return HeuristicLab.Common.Resources.VSImageLibrary.RadialChart; } 38 42 } 39 43 40 protected CompiledKSPTSPConnector(CompiledKSPTSPConnector original, Cloner cloner) : base(original, cloner) { } 41 public CompiledKSPTSPConnector(ProgrammableNode context) 44 new protected KSPTSPControl Context { 45 get { return (KSPTSPControl)base.Context; } 46 } 47 48 protected CompiledKSPTSPControl(CompiledKSPTSPControl original, Cloner cloner) : base(original, cloner) { } 49 public CompiledKSPTSPControl(ProgrammableNode context) 42 50 : base(context) { 43 51 if (Ports.Count == 0) … … 46 54 47 55 public override IDeepCloneable Clone(Cloner cloner) { 48 return new CompiledKSPTSPCon nector(this, cloner);56 return new CompiledKSPTSPControl(this, cloner); 49 57 } 50 58 51 59 public override void Initialize() { 52 60 base.Initialize(); 53 var parameters = new MessagePort("Parameters"); 54 Ports.Add(parameters); 55 parameters.Parameters.Add(new PortParameter<DoubleMatrix>("Cities") { Type = PortParameterType.Input }); 56 parameters.Parameters.Add(new PortParameter<DoubleValue>("TransportCostsFactor") { Type = PortParameterType.Input }); 57 58 var ksp = new MessagePort("KSP Connector"); 59 Ports.Add(ksp); 60 ksp.Parameters.Add(new PortParameter<BinaryVector>("KnapsackSolution") { Type = PortParameterType.Input }); 61 ksp.Parameters.Add(new PortParameter<DoubleValue>("Quality") { Type = PortParameterType.Input | PortParameterType.Output }); 62 ksp.Parameters.Add(new PortParameter<DoubleValue>("TransportCosts") { Type = PortParameterType.Output }); 63 ksp.Parameters.Add(new PortParameter<PathTSPTour>("Route") { Type = PortParameterType.Output }); 64 65 var tsp = new MessagePort("TSP Connector"); 66 Ports.Add(tsp); 67 tsp.Parameters.Add(new PortParameter<DoubleMatrix>("Coordinates") { Type = PortParameterType.Output }); 68 tsp.Parameters.Add(new PortParameter<PathTSPTour>("Best TSP Solution") { Type = PortParameterType.Input }); 69 tsp.Parameters.Add(new PortParameter<DoubleValue>("BestQuality") { Type = PortParameterType.Input }); 61 var configPort = new ConfigurationPort("Configure"); 62 Ports.Add(configPort); 63 64 configPort.Parameters.Add(new PortParameter<IntValue>("KnapsackCapacity") { 65 Type = PortParameterType.Input 66 }); 67 configPort.Parameters.Add(new PortParameter<IntArray>("Values") { 68 Type = PortParameterType.Input 69 }); 70 configPort.Parameters.Add(new PortParameter<IntArray>("Weights") { 71 Type = PortParameterType.Input 72 }); 73 configPort.Parameters.Add(new PortParameter<DoubleMatrix>("Coordinates") { 74 Type = PortParameterType.Input 75 }); 76 configPort.Parameters.Add(new PortParameter<DoubleValue>("TransportCostsFactor") { 77 Type = PortParameterType.Input 78 }); 79 80 var evalKspPort = new MessagePort("Evaluate KSP"); 81 Ports.Add(evalKspPort); 82 evalKspPort.Parameters.Add(new PortParameter<BinaryVector>("KnapsackSolution") { 83 Type = PortParameterType.Input 84 }); 85 evalKspPort.Parameters.Add(new PortParameter<DoubleValue>("Quality") { 86 Type = PortParameterType.Output 87 }); 88 89 var evalTspPort = new MessagePort("Evaluate TSP"); 90 Ports.Add(evalTspPort); 91 evalTspPort.Parameters.Add(new PortParameter<Permutation>("TSPTour") { 92 Type = PortParameterType.Input 93 }); 94 evalTspPort.Parameters.Add(new PortParameter<DoubleValue>("TSPTourLength") { 95 Type = PortParameterType.Output 96 }); 97 98 var addKspSolultionPort = new MessagePort("Add KSP Solution"); 99 Ports.Add(addKspSolultionPort); 100 addKspSolultionPort.Parameters.Add(new PortParameter<KnapsackSolution>("BestSolution") { 101 Type = PortParameterType.Input 102 }); 103 104 var addTspSolutionPort = new MessagePort("Add TSP Solution"); 105 Ports.Add(addTspSolutionPort); 106 addTspSolutionPort.Parameters.Add(new PortParameter<PathTSPTour>("BestSolution") { 107 Type = PortParameterType.Input 108 }); 109 } 110 111 private void AddKspSolultionPortOnMessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) { 112 var cities = (KnapsackSolution)(e.Value.Values["BestSolution"]).Value; 113 AddSelectedCities(cities.BinaryVector); 114 } 115 116 private void AddTspSolutionPortOnMessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) { 117 var trip = (PathTSPTour)(e.Value.Values["BestSolution"]).Value; 118 AddPredefinedTrip(trip.Permutation); 119 } 120 121 private void ConfigPortOnMessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) { 122 Context.TransportCostFactor = (DoubleValue)(e.Value["TransportCostsFactor"]); 123 Context.Coordinates = (DoubleMatrix)(e.Value["Coordinates"]); 124 Context.Distances = CalculateEuclidean(Context.Coordinates); 125 Context.CityValues = (IntArray)(e.Value["Values"]); 126 Context.CityWeights = (IntArray)(e.Value["Weights"]); 127 Context.CityLimit = (IntValue)(e.Value["KnapsackCapacity"]); 128 } 129 130 private void EvalKspPortOnMessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) { 131 var cities = (BinaryVector)(e.Value.Values["KnapsackSolution"]).Value; 132 e.Value.Values["Quality"].Value = new DoubleValue(EvaluatePredefinedTrip(cities)); 133 } 134 135 private void EvalTspPortOnMessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) { 136 var trip = (Permutation)(e.Value.Values["TSPTour"]).Value; 137 e.Value.Values["TSPTourLength"].Value = new DoubleValue(EvaluateSelectedCities(trip)); 70 138 } 71 139 72 140 public override void RegisterEvents() { 73 141 base.RegisterEvents(); 74 var ksp = (IMessagePort)Ports["KSP Connector"]; 75 ksp.MessageReceived += Knapsack_MessageReceived; 142 ((IMessagePort)Ports["Configure"]).MessageReceived += ConfigPortOnMessageReceived; 143 ((IMessagePort)Ports["Evaluate KSP"]).MessageReceived += EvalKspPortOnMessageReceived; 144 ((IMessagePort)Ports["Evaluate TSP"]).MessageReceived += EvalTspPortOnMessageReceived; 145 ((IMessagePort)Ports["Add KSP Solution"]).MessageReceived += AddKspSolultionPortOnMessageReceived; 146 ((IMessagePort)Ports["Add TSP Solution"]).MessageReceived += AddTspSolutionPortOnMessageReceived; 147 76 148 } 77 149 public override void DeregisterEvents() { 78 var ksp = (IMessagePort)Ports["KSP Connector"]; 79 ksp.MessageReceived -= Knapsack_MessageReceived; 150 ((IMessagePort)Ports["Configure"]).MessageReceived -= ConfigPortOnMessageReceived; 151 ((IMessagePort)Ports["Evaluate KSP"]).MessageReceived -= EvalKspPortOnMessageReceived; 152 ((IMessagePort)Ports["Evaluate TSP"]).MessageReceived -= EvalTspPortOnMessageReceived; 153 ((IMessagePort)Ports["Add KSP Solution"]).MessageReceived -= AddKspSolultionPortOnMessageReceived; 154 ((IMessagePort)Ports["Add TSP Solution"]).MessageReceived -= AddTspSolutionPortOnMessageReceived; 80 155 base.DeregisterEvents(); 81 156 } 82 157 83 private void Knapsack_MessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) { 84 // get parameters 85 var parametersPort = (IMessagePort)Ports["Parameters"]; 86 var parameters = parametersPort.PrepareMessage(); 87 parametersPort.SendMessage(parameters, e.Value2); 88 var cities = (DoubleMatrix)parameters["Cities"]; 89 var factor = ((DoubleValue)parameters["TransportCostsFactor"]).Value; 90 91 // build coordinates 92 var kspMsg = e.Value; 93 var kspSolution = (BinaryVector)kspMsg["KnapsackSolution"]; 94 var kspQuality = ((DoubleValue)kspMsg["Quality"]).Value; 95 var coords = new DoubleMatrix(kspSolution.Count(x => x), 2); 96 int j = 0; 97 for (int i = 0; i < kspSolution.Length; i++) { 98 if (kspSolution[i]) { 99 coords[j, 0] = cities[i, 0]; 100 coords[j, 1] = cities[i, 1]; 101 j++; 158 public double EvaluatePredefinedTrip(BinaryVector cities) { 159 if (Context.SelectedCities.Count == 0) { 160 Context.SelectedCities.Add(cities); 161 Context.KspWait.Set(); 162 Context.TspWait.WaitOne(); 163 } 164 return EvaluateBoth(cities, Context.PredefinedTrip.Last()); 165 } 166 167 public double EvaluateSelectedCities(Permutation trip) { 168 if (Context.PredefinedTrip.Count == 0) { 169 Context.PredefinedTrip.Add(trip); 170 Context.TspWait.Set(); 171 Context.KspWait.WaitOne(); 172 } 173 return EvaluateBoth(Context.SelectedCities.Last(), trip); 174 } 175 176 public double EvaluateBoth(BinaryVector cities, Permutation trip) { 177 var cityValues = cities.Select((v, i) => v ? Context.CityValues[i] : 0).Sum(); 178 var cityWeights = cities.Select((v, i) => v ? Context.CityWeights[i] : 0).Sum(); 179 var subtour = trip.Where(x => cities[x]).ToArray(); 180 var tourLength = 0.0; 181 for (var i = 1; i < subtour.Length; i++) 182 tourLength += Context.Distances[subtour[i - 1], subtour[i]]; 183 tourLength += Context.Distances[subtour.Last(), subtour[0]]; 184 if (cityWeights > Context.CityLimit.Value) // infeasible solution 185 return Context.CityLimit.Value - cityWeights - tourLength * Context.TransportCostFactor.Value; 186 return cityValues - tourLength * Context.TransportCostFactor.Value; 187 } 188 189 public void AddPredefinedTrip(Permutation trip) { 190 Context.TspWait.Set(); 191 Context.KspWait.WaitOne(); 192 lock (Context.Locker) { 193 Context.PredefinedTrip.Add(trip); 194 } 195 } 196 197 public void AddSelectedCities(BinaryVector cities) { 198 Context.KspWait.Set(); 199 Context.TspWait.WaitOne(); 200 lock (Context.Locker) { 201 Context.SelectedCities.Add(cities); 202 } 203 } 204 205 public static DoubleMatrix CalculateEuclidean(DoubleMatrix cities) { 206 var len = cities.Rows; 207 var distances = new DoubleMatrix(len, len); 208 for (var i = 0; i < len - 1; i++) { 209 var sX = cities[i, 0]; 210 var sY = cities[i, 1]; 211 for (var j = i + 1; j < len; j++) { 212 var tX = cities[j, 0]; 213 var tY = cities[j, 1]; 214 distances[i, j] = Math.Sqrt((sX - tX) * (sX - tX) + (sY - tY) * (sY - tY)); 215 distances[j, i] = distances[i, j]; 102 216 } 103 217 } 104 105 // solve TSP 106 var tspConnectorPort = (IMessagePort)Ports["TSP Connector"]; 107 var tspMsg = tspConnectorPort.PrepareMessage(); 108 tspMsg["Coordinates"] = coords; 109 tspConnectorPort.SendMessage(tspMsg, e.Value2); 110 var tspSolution = (PathTSPTour)tspMsg["Best TSP Solution"]; 111 var tspQuality = ((DoubleValue)tspMsg["BestQuality"]).Value; 112 113 // calculate transport costs 114 ((DoubleValue)kspMsg["Quality"]).Value = kspQuality - factor * tspQuality; 115 kspMsg["TransportCosts"] = new DoubleValue(factor * tspQuality); 116 kspMsg["Route"] = tspSolution; 117 } 218 return distances; 219 } 220 118 221 } 119 222 }
Note: See TracChangeset
for help on using the changeset viewer.