Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OptimizationNetworks/HeuristicLab.Networks/3.3/KSPTSPControlCode.cs @ 12228

Last change on this file since 12228 was 11823, checked in by abeham, 10 years ago

#2205:

  • Added cosolving KSPTSP network
  • Fixed output path in projects for release target
  • Fixed penalty in seqsolving KSPTSP network (would produce infeasible solutions)
  • Added some additional references
File size: 9.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Drawing;
24using System.Linq;
25using System.Threading;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Core.Networks;
29using HeuristicLab.Data;
30using HeuristicLab.Encodings.BinaryVectorEncoding;
31using HeuristicLab.Encodings.PermutationEncoding;
32using HeuristicLab.Networks.Programmable;
33using HeuristicLab.Problems.Knapsack;
34using HeuristicLab.Problems.TravelingSalesman;
35
36namespace HeuristicLab.Networks {
37  [Item("KSPTSPControl", "A node of an optimization network which connects a KSP and a TSP.")]
38  public class CompiledKSPTSPControl : ProgrammableNode.CompiledProgrammableNode {
39
40    public static new Image StaticItemImage {
41      get { return HeuristicLab.Common.Resources.VSImageLibrary.RadialChart; }
42    }
43
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)
50      : base(context) {
51      if (Ports.Count == 0)
52        Initialize();
53    }
54
55    public override IDeepCloneable Clone(Cloner cloner) {
56      return new CompiledKSPTSPControl(this, cloner);
57    }
58
59    public override void Initialize() {
60      base.Initialize();
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));
138    }
139
140    public override void RegisterEvents() {
141      base.RegisterEvents();
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
148    }
149    public override void DeregisterEvents() {
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;
155      base.DeregisterEvents();
156    }
157
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];
216        }
217      }
218      return distances;
219    }
220
221  }
222}
Note: See TracBrowser for help on using the repository browser.