Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2205_OptimizationNetworks/HeuristicLab.Networks/3.3/KSPTSPControlCode.cs @ 15895

Last change on this file since 15895 was 12945, checked in by jkarder, 9 years ago

#2205: disabled compiler warning cs0436 for all code resources

File size: 9.1 KB
Line 
1#pragma warning disable 436
2
3#region License Information
4/* HeuristicLab
5 * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
6 *
7 * This file is part of HeuristicLab.
8 *
9 * HeuristicLab is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * HeuristicLab is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
21 */
22#endregion
23
24using System;
25using System.Drawing;
26using System.Linq;
27using System.Threading;
28using HeuristicLab.Common;
29using HeuristicLab.Core;
30using HeuristicLab.Core.Networks;
31using HeuristicLab.Data;
32using HeuristicLab.Encodings.BinaryVectorEncoding;
33using HeuristicLab.Encodings.PermutationEncoding;
34using HeuristicLab.Networks.Programmable;
35using HeuristicLab.Problems.Knapsack;
36using HeuristicLab.Problems.TravelingSalesman;
37
38namespace HeuristicLab.Networks {
39  [Item("KSPTSPControl", "A node of an optimization network which connects a KSP and a TSP.")]
40  public class CompiledKSPTSPControl : ProgrammableNode.CompiledProgrammableNode {
41
42    public static new Image StaticItemImage {
43      get { return HeuristicLab.Common.Resources.VSImageLibrary.RadialChart; }
44    }
45
46    new protected KSPTSPControl Context {
47      get { return (KSPTSPControl)base.Context; }
48    }
49
50    protected CompiledKSPTSPControl(CompiledKSPTSPControl original, Cloner cloner) : base(original, cloner) { }
51    public CompiledKSPTSPControl(ProgrammableNode context)
52      : base(context) {
53      if (Ports.Count == 0)
54        Initialize();
55    }
56
57    public override IDeepCloneable Clone(Cloner cloner) {
58      return new CompiledKSPTSPControl(this, cloner);
59    }
60
61    public override void Initialize() {
62      base.Initialize();
63      var configPort = new ConfigurationPort("Configure");
64      Ports.Add(configPort);
65
66      configPort.Parameters.Add(new PortParameter<IntValue>("KnapsackCapacity") {
67        Type = PortParameterType.Input
68      });
69      configPort.Parameters.Add(new PortParameter<IntArray>("Values") {
70        Type = PortParameterType.Input
71      });
72      configPort.Parameters.Add(new PortParameter<IntArray>("Weights") {
73        Type = PortParameterType.Input
74      });
75      configPort.Parameters.Add(new PortParameter<DoubleMatrix>("Coordinates") {
76        Type = PortParameterType.Input
77      });
78      configPort.Parameters.Add(new PortParameter<DoubleValue>("TransportCostsFactor") {
79        Type = PortParameterType.Input
80      });
81
82      var evalKspPort = new MessagePort("Evaluate KSP");
83      Ports.Add(evalKspPort);
84      evalKspPort.Parameters.Add(new PortParameter<BinaryVector>("KnapsackSolution") {
85        Type = PortParameterType.Input
86      });
87      evalKspPort.Parameters.Add(new PortParameter<DoubleValue>("Quality") {
88        Type = PortParameterType.Output
89      });
90
91      var evalTspPort = new MessagePort("Evaluate TSP");
92      Ports.Add(evalTspPort);
93      evalTspPort.Parameters.Add(new PortParameter<Permutation>("TSPTour") {
94        Type = PortParameterType.Input
95      });
96      evalTspPort.Parameters.Add(new PortParameter<DoubleValue>("TSPTourLength") {
97        Type = PortParameterType.Output
98      });
99
100      var addKspSolultionPort = new MessagePort("Add KSP Solution");
101      Ports.Add(addKspSolultionPort);
102      addKspSolultionPort.Parameters.Add(new PortParameter<KnapsackSolution>("BestSolution") {
103        Type = PortParameterType.Input
104      });
105
106      var addTspSolutionPort = new MessagePort("Add TSP Solution");
107      Ports.Add(addTspSolutionPort);
108      addTspSolutionPort.Parameters.Add(new PortParameter<PathTSPTour>("BestSolution") {
109        Type = PortParameterType.Input
110      });
111    }
112
113    private void AddKspSolultionPortOnMessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) {
114      var cities = (KnapsackSolution)(e.Value.Values["BestSolution"]).Value;
115      AddSelectedCities(cities.BinaryVector);
116    }
117
118    private void AddTspSolutionPortOnMessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) {
119      var trip = (PathTSPTour)(e.Value.Values["BestSolution"]).Value;
120      AddPredefinedTrip(trip.Permutation);
121    }
122
123    private void ConfigPortOnMessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) {
124      Context.TransportCostFactor = (DoubleValue)(e.Value["TransportCostsFactor"]);
125      Context.Coordinates = (DoubleMatrix)(e.Value["Coordinates"]);
126      Context.Distances = CalculateEuclidean(Context.Coordinates);
127      Context.CityValues = (IntArray)(e.Value["Values"]);
128      Context.CityWeights = (IntArray)(e.Value["Weights"]);
129      Context.CityLimit = (IntValue)(e.Value["KnapsackCapacity"]);
130    }
131
132    private void EvalKspPortOnMessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) {
133      var cities = (BinaryVector)(e.Value.Values["KnapsackSolution"]).Value;
134      e.Value.Values["Quality"].Value = new DoubleValue(EvaluatePredefinedTrip(cities));
135    }
136
137    private void EvalTspPortOnMessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) {
138      var trip = (Permutation)(e.Value.Values["TSPTour"]).Value;
139      e.Value.Values["TSPTourLength"].Value = new DoubleValue(EvaluateSelectedCities(trip));
140    }
141
142    public override void RegisterEvents() {
143      base.RegisterEvents();
144      ((IMessagePort)Ports["Configure"]).MessageReceived += ConfigPortOnMessageReceived;
145      ((IMessagePort)Ports["Evaluate KSP"]).MessageReceived += EvalKspPortOnMessageReceived;
146      ((IMessagePort)Ports["Evaluate TSP"]).MessageReceived += EvalTspPortOnMessageReceived;
147      ((IMessagePort)Ports["Add KSP Solution"]).MessageReceived += AddKspSolultionPortOnMessageReceived;
148      ((IMessagePort)Ports["Add TSP Solution"]).MessageReceived += AddTspSolutionPortOnMessageReceived;
149
150    }
151    public override void DeregisterEvents() {
152      ((IMessagePort)Ports["Configure"]).MessageReceived -= ConfigPortOnMessageReceived;
153      ((IMessagePort)Ports["Evaluate KSP"]).MessageReceived -= EvalKspPortOnMessageReceived;
154      ((IMessagePort)Ports["Evaluate TSP"]).MessageReceived -= EvalTspPortOnMessageReceived;
155      ((IMessagePort)Ports["Add KSP Solution"]).MessageReceived -= AddKspSolultionPortOnMessageReceived;
156      ((IMessagePort)Ports["Add TSP Solution"]).MessageReceived -= AddTspSolutionPortOnMessageReceived;
157      base.DeregisterEvents();
158    }
159
160    public double EvaluatePredefinedTrip(BinaryVector cities) {
161      if (Context.SelectedCities.Count == 0) {
162        Context.SelectedCities.Add(cities);
163        Context.KspWait.Set();
164        Context.TspWait.WaitOne();
165      }
166      return EvaluateBoth(cities, Context.PredefinedTrip.Last());
167    }
168
169    public double EvaluateSelectedCities(Permutation trip) {
170      if (Context.PredefinedTrip.Count == 0) {
171        Context.PredefinedTrip.Add(trip);
172        Context.TspWait.Set();
173        Context.KspWait.WaitOne();
174      }
175      return EvaluateBoth(Context.SelectedCities.Last(), trip);
176    }
177
178    public double EvaluateBoth(BinaryVector cities, Permutation trip) {
179      var cityValues = cities.Select((v, i) => v ? Context.CityValues[i] : 0).Sum();
180      var cityWeights = cities.Select((v, i) => v ? Context.CityWeights[i] : 0).Sum();
181      var subtour = trip.Where(x => cities[x]).ToArray();
182      var tourLength = 0.0;
183      for (var i = 1; i < subtour.Length; i++)
184        tourLength += Context.Distances[subtour[i - 1], subtour[i]];
185      tourLength += Context.Distances[subtour.Last(), subtour[0]];
186      if (cityWeights > Context.CityLimit.Value) // infeasible solution
187        return Context.CityLimit.Value - cityWeights - tourLength * Context.TransportCostFactor.Value;
188      return cityValues - tourLength * Context.TransportCostFactor.Value;
189    }
190
191    public void AddPredefinedTrip(Permutation trip) {
192      Context.TspWait.Set();
193      Context.KspWait.WaitOne();
194      lock (Context.Locker) {
195        Context.PredefinedTrip.Add(trip);
196      }
197    }
198
199    public void AddSelectedCities(BinaryVector cities) {
200      Context.KspWait.Set();
201      Context.TspWait.WaitOne();
202      lock (Context.Locker) {
203        Context.SelectedCities.Add(cities);
204      }
205    }
206
207    public static DoubleMatrix CalculateEuclidean(DoubleMatrix cities) {
208      var len = cities.Rows;
209      var distances = new DoubleMatrix(len, len);
210      for (var i = 0; i < len - 1; i++) {
211        var sX = cities[i, 0];
212        var sY = cities[i, 1];
213        for (var j = i + 1; j < len; j++) {
214          var tX = cities[j, 0];
215          var tY = cities[j, 1];
216          distances[i, j] = Math.Sqrt((sX - tX) * (sX - tX) + (sY - tY) * (sY - tY));
217          distances[j, i] = distances[i, j];
218        }
219      }
220      return distances;
221    }
222
223  }
224}
Note: See TracBrowser for help on using the repository browser.