Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
01/26/15 15:52:03 (9 years ago)
Author:
abeham
Message:

#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:
1 copied

Legend:

Unmodified
Added
Removed
  • branches/OptimizationNetworks/HeuristicLab.Networks/3.3/KSPTSPControlCode.cs

    r11711 r11823  
    2020#endregion
    2121
     22using System;
     23using System.Drawing;
     24using System.Linq;
     25using System.Threading;
    2226using HeuristicLab.Common;
    2327using HeuristicLab.Core;
     
    2529using HeuristicLab.Data;
    2630using HeuristicLab.Encodings.BinaryVectorEncoding;
     31using HeuristicLab.Encodings.PermutationEncoding;
    2732using HeuristicLab.Networks.Programmable;
     33using HeuristicLab.Problems.Knapsack;
    2834using HeuristicLab.Problems.TravelingSalesman;
    29 using System.Drawing;
    30 using System.Linq;
    31 using System.Threading;
    3235
    3336namespace 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
    3640    public static new Image StaticItemImage {
    3741      get { return HeuristicLab.Common.Resources.VSImageLibrary.RadialChart; }
    3842    }
    3943
    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)
    4250      : base(context) {
    4351      if (Ports.Count == 0)
     
    4654
    4755    public override IDeepCloneable Clone(Cloner cloner) {
    48       return new CompiledKSPTSPConnector(this, cloner);
     56      return new CompiledKSPTSPControl(this, cloner);
    4957    }
    5058
    5159    public override void Initialize() {
    5260      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));
    70138    }
    71139
    72140    public override void RegisterEvents() {
    73141      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
    76148    }
    77149    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;
    80155      base.DeregisterEvents();
    81156    }
    82157
    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];
    102216        }
    103217      }
    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
    118221  }
    119222}
Note: See TracChangeset for help on using the changeset viewer.