Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.LocationRouting/3.3/LrpOrchestratorNode1.cs @ 14607

Last change on this file since 14607 was 14607, checked in by abeham, 8 years ago

#2205: added GetSolution() method to FLP

File size: 18.2 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2017 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.Collections.Generic;
24using System.Linq;
25using System.Text.RegularExpressions;
26using System.Threading;
27using HeuristicLab.Common;
28using HeuristicLab.Core;
29using HeuristicLab.Core.Networks;
30using HeuristicLab.Data;
31using HeuristicLab.Encodings.BinaryVectorEncoding;
32using HeuristicLab.Encodings.IntegerVectorEncoding;
33using HeuristicLab.Encodings.PermutationEncoding;
34using HeuristicLab.Encodings.RealVectorEncoding;
35using HeuristicLab.Operators;
36using HeuristicLab.Optimization;
37using HeuristicLab.Parameters;
38using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
39using HeuristicLab.Problems.FacilityLocation;
40using HeuristicLab.Problems.VehicleRouting;
41using HeuristicLab.Problems.VehicleRouting.Encodings.General;
42using HeuristicLab.Problems.VehicleRouting.ProblemInstances;
43
44namespace HeuristicLab.Networks.IntegratedOptimization.LocationRouting {
45  [Item("LrpOrchestratorNode1", "Orchestrator for LRP optimization network version 1.")]
46  [StorableClass]
47  public sealed class LrpOrchestratorNode1 : OrchestratorNode {
48    #region Constants
49    private const string InstanceParameterName = "Instance";
50    private const string FlpParameterName = "FLP";
51    private const string VrpParameterName = "VRP";
52    private const string MetaSolverName = "MetaSolver";
53    private const string FlpSolverName = "FlpSolver";
54    private const string VrpSolverName = "VrpSolver";
55    #endregion
56
57    private CancellationTokenSource cts;
58    private ResultCollection vrpResults, flpResults;
59
60    [Storable]
61    int nrOfDepots, nrOfCustomers;
62    [Storable]
63    double[,] depotCoordinates, customerCoordinates;
64    [Storable]
65    LrpUtils.DistanceType distanceType;
66    [Storable]
67    double[] depotCapacities, customerDemands, depotCosts;
68    [Storable]
69    double vehicleCapacity, vehicleCost;
70
71    #region Parameters
72    public IFixedValueParameter<TextFileValue> InstanceParameter {
73      get { return (IFixedValueParameter<TextFileValue>)Parameters[InstanceParameterName]; }
74    }
75
76    public IValueParameter<FacilityLocationProblem> FlpParameter {
77      get { return (IValueParameter<FacilityLocationProblem>)Parameters[FlpParameterName]; }
78    }
79
80    public IValueParameter<VehicleRoutingProblem> VrpParameter {
81      get { return (IValueParameter<VehicleRoutingProblem>)Parameters[VrpParameterName]; }
82    }
83    #endregion
84
85    #region Ports
86    public IMessagePort MetaSolverOrchestrationPort {
87      get { return (IMessagePort)Ports[MetaSolverName + OrchestrationPortNameSuffix]; }
88    }
89
90    public IMessagePort MetaSolverEvaluationPort {
91      get { return (IMessagePort)Ports[MetaSolverName + EvaluationPortNameSuffix]; }
92    }
93
94    public IMessagePort FlpSolverOrchestrationPort {
95      get { return (IMessagePort)Ports[FlpSolverName + OrchestrationPortNameSuffix]; }
96    }
97
98    public IMessagePort FlpSolverEvaluationPort {
99      get { return (IMessagePort)Ports[FlpSolverName + EvaluationPortNameSuffix]; }
100    }
101
102    public IMessagePort VrpSolverOrchestrationPort {
103      get { return (IMessagePort)Ports[VrpSolverName + OrchestrationPortNameSuffix]; }
104    }
105
106    public IMessagePort VrpSolverEvaluationPort {
107      get { return (IMessagePort)Ports[VrpSolverName + EvaluationPortNameSuffix]; }
108    }
109    #endregion
110
111    [StorableConstructor]
112    private LrpOrchestratorNode1(bool deserializing) : base(deserializing) { }
113    private LrpOrchestratorNode1(LrpOrchestratorNode1 original, Cloner cloner) : base(original, cloner) {
114      nrOfDepots = original.nrOfDepots;
115      nrOfCustomers = original.nrOfCustomers;
116      depotCoordinates = (double[,])original.depotCoordinates.Clone();
117      customerCoordinates = (double[,])original.customerCoordinates.Clone();
118      distanceType = original.distanceType;
119      depotCapacities = (double[])original.depotCapacities.Clone();
120      customerDemands = (double[])original.customerDemands.Clone();
121      depotCosts = (double[])original.depotCosts.Clone();
122      vehicleCapacity = original.vehicleCapacity;
123      vehicleCost = original.vehicleCost;
124
125      RegisterEvents();
126    }
127    public LrpOrchestratorNode1() : this("LrpOrchestratorNode1") { }
128    public LrpOrchestratorNode1(string name) : base(name) {
129      #region Configure Parameters
130      Parameters.Add(new FixedValueParameter<TextFileValue>(InstanceParameterName));
131      Parameters.Add(new ValueParameter<FacilityLocationProblem>(FlpParameterName, new FacilityLocationProblem()));
132      Parameters.Add(new ValueParameter<VehicleRoutingProblem>(VrpParameterName, new VehicleRoutingProblem() { ProblemInstance = new CVRPProblemInstance() }));
133      #endregion
134
135      #region Configure Ports
136      AddOrchestrationPort<VariegationProblem>(MetaSolverName);
137      AddEvaluationPort<RealVector>(MetaSolverName, "RealVector", "Quality");
138      AddOrchestrationPort<VehicleRoutingProblem>(VrpSolverName);
139      AddEvaluationPort<Permutation>(VrpSolverName, "TSPTour", "TSPTourLength");
140      AddOrchestrationPort<FacilityLocationProblem>(FlpSolverName);
141      AddEvaluationPort<BinaryVector>(FlpSolverName, "KnapsackSolution", "Quality");
142
143      RegisterEvents();
144      #endregion
145    }
146
147    public override IDeepCloneable Clone(Cloner cloner) {
148      return new LrpOrchestratorNode1(this, cloner);
149    }
150
151    [StorableHook(HookType.AfterDeserialization)]
152    private void AfterDeserialization() {
153      RegisterEvents();
154    }
155
156    private void RegisterEvents() {
157      InstanceParameter.Value.ToStringChanged += InstanceParameter_Value_ToStringChanged;
158      MetaSolverOrchestrationPort.ConnectedPortChanged += MetaSolverOrchestrationPort_ConnectedPortChanged;
159      VrpSolverOrchestrationPort.ConnectedPortChanged += VrpSolverOrchestrationPort_ConnectedPortChanged;
160      FlpSolverOrchestrationPort.ConnectedPortChanged += FlpSolverOrchestrationPort_ConnectedPortChanged;
161    }
162
163    private void InstanceParameter_Value_ToStringChanged(object sender, EventArgs e) {
164      string filePath = InstanceParameter.Value.Value;
165      LrpUtils.Import(filePath, out nrOfDepots, out nrOfCustomers,
166                                out depotCoordinates, out customerCoordinates,
167                                out distanceType,
168                                out depotCapacities, out customerDemands, out depotCosts,
169                                out vehicleCapacity, out vehicleCost);
170
171      var flp = FlpParameter.Value;
172      flp.CustomerDemandsParameter.Value = new DoubleArray(customerDemands);
173      flp.DeliveryCostsParameter.Value = new DoubleMatrix(LrpUtils.GetFlpDeliveryCosts(depotCoordinates, customerCoordinates, distanceType));
174      flp.DepotCapacitiesParameter.Value = new DoubleArray(depotCapacities);
175      flp.Encoding.Length = nrOfCustomers;
176      flp.OpeningCostsParameter.Value = new DoubleArray(depotCosts);
177
178      var vrpInstance = (CVRPProblemInstance)VrpParameter.Value.ProblemInstance;
179      vrpInstance.Capacity.Value = vehicleCapacity;
180      vrpInstance.FleetUsageFactor.Value = vehicleCost;
181      vrpInstance.OverloadPenalty.Value = vehicleCost * 1000.0;
182
183      var crossover = VrpParameter.Value.OperatorsParameter.Value.OfType<MultiVRPSolutionCrossover>().Single(x => x.Name == "MultiVRPSolutionCrossover");
184      foreach (var c in crossover.Operators)
185        crossover.Operators.SetItemCheckedState(c, c.Name.StartsWith("Potvin"));
186      var mutator = VrpParameter.Value.OperatorsParameter.Value.OfType<MultiVRPSolutionManipulator>().Single(x => x.Name == "MultiVRPSolutionManipulator");
187      foreach (var m in mutator.Operators)
188        mutator.Operators.SetItemCheckedState(m, Regex.IsMatch(m.Name, @"Potvin(One|Two).*"));
189    }
190
191    public override void Prepare() {
192      Results.Clear();
193
194      var metaMsg = MetaSolverOrchestrationPort.PrepareMessage();
195      metaMsg["OrchestrationMessage"] = new EnumValue<OrchestrationMessage>(OrchestrationMessage.Prepare | OrchestrationMessage.QualityAdaption);
196      var problem = new VariegationProblem();
197      problem.Encoding.Length = FlpParameter.Value.Encoding.Length * 2;
198      problem.Encoding.Bounds = new DoubleMatrix(new[,] { { 0.0, 2.0 } });
199      metaMsg["Problem"] = problem;
200      MetaSolverOrchestrationPort.SendMessage(metaMsg);
201    }
202
203    public override void Start() {
204      cts = new CancellationTokenSource();
205
206      try {
207        var metaMsg = MetaSolverOrchestrationPort.PrepareMessage();
208        metaMsg["OrchestrationMessage"] = new EnumValue<OrchestrationMessage>(OrchestrationMessage.Start);
209        MetaSolverOrchestrationPort.SendMessage(metaMsg);
210      } catch (Exception e) { }
211    }
212
213    public override void Pause() {
214      cts.Cancel();
215
216      var metaMsg = MetaSolverOrchestrationPort.PrepareMessage();
217      metaMsg["OrchestrationMessage"] = new EnumValue<OrchestrationMessage>(OrchestrationMessage.Pause);
218      MetaSolverOrchestrationPort.SendMessage(metaMsg);
219
220      var vrpMsg = VrpSolverOrchestrationPort.PrepareMessage();
221      vrpMsg["OrchestrationMessage"] = new EnumValue<OrchestrationMessage>(OrchestrationMessage.Stop);
222      VrpSolverOrchestrationPort.SendMessage(vrpMsg);
223
224      var kspMsg = FlpSolverOrchestrationPort.PrepareMessage();
225      kspMsg["OrchestrationMessage"] = new EnumValue<OrchestrationMessage>(OrchestrationMessage.Stop);
226      FlpSolverOrchestrationPort.SendMessage(kspMsg);
227    }
228
229    public override void Stop() {
230      cts.Cancel();
231
232      var metaMsg = MetaSolverOrchestrationPort.PrepareMessage();
233      metaMsg["OrchestrationMessage"] = new EnumValue<OrchestrationMessage>(OrchestrationMessage.Stop);
234      MetaSolverOrchestrationPort.SendMessage(metaMsg);
235
236      var vrpMsg = VrpSolverOrchestrationPort.PrepareMessage();
237      vrpMsg["OrchestrationMessage"] = new EnumValue<OrchestrationMessage>(OrchestrationMessage.Stop);
238      VrpSolverOrchestrationPort.SendMessage(vrpMsg);
239
240      var kspMsg = FlpSolverOrchestrationPort.PrepareMessage();
241      kspMsg["OrchestrationMessage"] = new EnumValue<OrchestrationMessage>(OrchestrationMessage.Stop);
242      FlpSolverOrchestrationPort.SendMessage(kspMsg);
243    }
244
245    protected override void ProcessMessage(IMessage message, IMessagePort port, CancellationToken token) {
246      var messageActions = new Dictionary<IMessagePort, Action<IMessage>>();
247      messageActions.Add(MetaSolverOrchestrationPort, MetaSolverOrchestrationPortMessage);
248      messageActions.Add(MetaSolverEvaluationPort, MetaSolverEvaluationPortMessage);
249      messageActions.Add(VrpSolverOrchestrationPort, VrpSolverOrchestrationPortMessage);
250      messageActions.Add(VrpSolverEvaluationPort, VrpSolverEvaluationPortMessage);
251      messageActions.Add(FlpSolverOrchestrationPort, FlpSolverOrchestrationPortMessage);
252      messageActions.Add(FlpSolverEvaluationPort, FlpSolverEvaluationPortMessage);
253
254      messageActions[port](message);
255
256      base.ProcessMessage(message, port, token);
257    }
258
259    #region MetaSolver Message Handling
260    private void MetaSolverOrchestrationPortMessage(IMessage message) { }
261
262    private void MetaSolverEvaluationPortMessage(IMessage message) {
263      var factors = (RealVector)message["RealVector"];
264
265      var flp = (FacilityLocationProblem)FlpParameter.Value.Clone();
266      var cc = (double[,])customerCoordinates.Clone();
267      for (int i = 0; i < nrOfCustomers; i++) {
268        cc[i, 0] = cc[i, 0] * factors[i * 2];
269        cc[i, 1] = cc[i, 1] * factors[i * 2 + 1];
270      }
271      flp.DeliveryCostsParameter.Value = new DoubleMatrix(LrpUtils.GetFlpDeliveryCosts(depotCoordinates, cc, distanceType));
272
273      var flpMsg = FlpSolverOrchestrationPort.PrepareMessage();
274      flpMsg["OrchestrationMessage"] = new EnumValue<OrchestrationMessage>(OrchestrationMessage.Prepare | OrchestrationMessage.Start);
275      flpMsg["Problem"] = flp;
276      FlpSolverOrchestrationPort.SendMessage(flpMsg);
277      cts.Token.ThrowIfCancellationRequested();
278
279      var bestFlpSolution = (IntegerVector)flpResults["Best Solution"].Value;
280      var flpSolution = FlpParameter.Value.GetSolution(bestFlpSolution);
281     
282      var depots = bestFlpSolution.Select((x, i) => Tuple.Create(x, i)).GroupBy(x => x.Item1, x => x.Item2);
283      var vrpSolutions = new ResultCollection(depots.Count());
284      foreach (var depot in depots.OrderBy(x => x.Key)) {
285        var depotIdx = depot.Key;
286        var customers = depot.ToArray();
287
288        var vrp = (VehicleRoutingProblem)VrpParameter.Value.Clone();
289        var vrpInstance = (CVRPProblemInstance)vrp.ProblemInstance;
290        var coordinates = LrpUtils.GetVrpCoordinates(depotCoordinates, customerCoordinates, depotIdx, customers);
291        var distances = LrpUtils.GetVrpDistances(coordinates, distanceType);
292        vrpInstance.Coordinates = new DoubleMatrix(coordinates);
293        vrpInstance.DistanceMatrix = new DoubleMatrix(distances);
294        vrpInstance.Demand = new DoubleArray(new[] { 0.0 }.Concat(customers.Select(x => customerDemands[x])).ToArray());
295        vrpInstance.Vehicles.Value = customers.Length;
296
297        var vrpMsg = VrpSolverOrchestrationPort.PrepareMessage();
298        vrpMsg["OrchestrationMessage"] = new EnumValue<OrchestrationMessage>(OrchestrationMessage.Prepare | OrchestrationMessage.Start);
299        vrpMsg["Problem"] = vrp;
300        VrpSolverOrchestrationPort.SendMessage(vrpMsg);
301        cts.Token.ThrowIfCancellationRequested();
302
303        var bestVrpSolution = (VRPSolution)vrpResults["Best valid VRP Solution"].Value.Clone();
304        vrpSolutions.Add(new Result("Depot " + depot.Key, bestVrpSolution));
305      }
306
307      #region Analyze
308      double objectiveValue = LrpUtils.Evaluate(flpSolution, vrpSolutions.Select(x => (VRPSolution)x.Value).ToArray());
309      ((DoubleValue)message["Quality"]).Value = objectiveValue;
310
311      IResult bestQuality;
312      if (!Results.TryGetValue("Best LRP Quality", out bestQuality)) {
313        Results.Add(new Result("Best LRP Quality", new DoubleValue(objectiveValue)));
314        Results.Add(new Result("Best FLP Solution", flpSolution));
315        Results.Add(new Result("Best VRP Solutions", vrpSolutions));
316      } else if (objectiveValue < ((DoubleValue)bestQuality.Value).Value) {
317        ((DoubleValue)bestQuality.Value).Value = objectiveValue;
318        Results["Best FLP Solution"].Value = flpSolution;
319        Results["Best VRP Solutions"].Value = vrpSolutions;
320      }
321      #endregion
322    }
323    #endregion
324
325    #region VrpSolver Message Handling
326    private void VrpSolverOrchestrationPortMessage(IMessage message) {
327      var results = (ResultCollection)message["Results"];
328      if (results.ContainsKey("Best valid VRP Solution")) {
329        vrpResults = results;
330      }
331    }
332
333    private void VrpSolverEvaluationPortMessage(IMessage message) { }
334    #endregion
335
336    #region KspSolver Message Handling
337    private void FlpSolverOrchestrationPortMessage(IMessage message) {
338      var results = (ResultCollection)message["Results"];
339      if (results.ContainsKey("Best Solution")) {
340        flpResults = results;
341      }
342    }
343
344    private void FlpSolverEvaluationPortMessage(IMessage message) { }
345    #endregion
346
347    #region Event Handlers
348    private void MetaSolverOrchestrationPort_ConnectedPortChanged(object sender, EventArgs e) {
349      if (MetaSolverOrchestrationPort.ConnectedPort == null) return;
350
351      var node = MetaSolverOrchestrationPort.ConnectedPort.Parent as OrchestratedAlgorithmNode;
352      if (node == null) return;
353
354      var hook = new HookOperator { Name = "Meta Eval Hook" };
355      hook.Parameters.Add(new LookupParameter<RealVector>("RealVector") { Hidden = true });
356      hook.Parameters.Add(new LookupParameter<DoubleValue>("Quality") { Hidden = true });
357      node.EvalHook = hook;
358
359      node.OrchestrationPort.CloneParametersFromPort(MetaSolverOrchestrationPort);
360      node.EvaluationPort.CloneParametersFromPort(MetaSolverEvaluationPort);
361      node.EvaluationPort.ConnectedPort = MetaSolverEvaluationPort;
362    }
363
364    private void VrpSolverOrchestrationPort_ConnectedPortChanged(object sender, EventArgs e) {
365      if (VrpSolverOrchestrationPort.ConnectedPort == null) return;
366
367      var node = VrpSolverOrchestrationPort.ConnectedPort.Parent as OrchestratedAlgorithmNode;
368      if (node == null) return;
369
370      var hook = new HookOperator { Name = "VRP Eval Hook" };
371      hook.Parameters.Add(new LookupParameter<Permutation>("VRPTours") { Hidden = true });
372      hook.Parameters.Add(new LookupParameter<DoubleValue>("Quality") { Hidden = true });
373      node.EvalHook = hook;
374
375      node.OrchestrationPort.CloneParametersFromPort(VrpSolverOrchestrationPort);
376      node.EvaluationPort.CloneParametersFromPort(VrpSolverEvaluationPort);
377      node.EvaluationPort.ConnectedPort = VrpSolverEvaluationPort;
378    }
379
380    private void FlpSolverOrchestrationPort_ConnectedPortChanged(object sender, EventArgs e) {
381      if (FlpSolverOrchestrationPort.ConnectedPort == null) return;
382
383      var node = FlpSolverOrchestrationPort.ConnectedPort.Parent as OrchestratedAlgorithmNode;
384      if (node == null) return;
385
386      var hook = new HookOperator { Name = "FLP Eval Hook" };
387      hook.Parameters.Add(new LookupParameter<BinaryVector>("IntegerVector") { Hidden = true });
388      hook.Parameters.Add(new LookupParameter<DoubleValue>("Quality") { Hidden = true });
389      node.EvalHook = hook;
390
391      node.OrchestrationPort.CloneParametersFromPort(FlpSolverOrchestrationPort);
392      node.EvaluationPort.CloneParametersFromPort(FlpSolverEvaluationPort);
393      node.EvaluationPort.ConnectedPort = FlpSolverEvaluationPort;
394    }
395    #endregion
396  }
397}
Note: See TracBrowser for help on using the repository browser.