Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 14606 was 14606, checked in by jkarder, 6 years ago

#2205: worked on optimization networks

File size: 19.6 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 bestFlpQuality = FlpParameter.Value.Evaluate(bestFlpSolution);
281      var flpCustomerDemands = (DoubleArray)FlpParameter.Value.CustomerDemandsParameter.Value.Clone();
282      var flpDeliveryCosts = (DoubleMatrix)FlpParameter.Value.DeliveryCostsParameter.Value.Clone();
283      var flpDepotCapacities = (DoubleArray)FlpParameter.Value.DepotCapacitiesParameter.Value.Clone();
284      var flpOpeningCosts = (DoubleArray)FlpParameter.Value.OpeningCostsParameter.Value.Clone();
285      double totalOpeningCosts, totalDeliveryCosts; double[] depotUsage;
286      FacilityLocationProblem.Evaluate(bestFlpSolution.ToArray(), flpOpeningCosts, flpDepotCapacities, flpCustomerDemands, flpDeliveryCosts, out totalOpeningCosts, out totalDeliveryCosts, out depotUsage);
287      var flpSolution = new FacilityLocationSolution {
288        OpeningCosts = flpOpeningCosts,
289        DepotCapacities = flpDepotCapacities,
290        CustomerDemands = flpCustomerDemands,
291        DeliveryCosts = flpDeliveryCosts
292      };
293      flpSolution.CustomerToDepotAssignmentParameter.Value = bestFlpSolution;
294      flpSolution.FitnessValueParameter.Value = new DoubleValue(bestFlpQuality);
295      flpSolution.TotalOpeningCostsParameter.Value = new DoubleValue(totalOpeningCosts);
296      flpSolution.TotalDeliveryCostsParameter.Value = new DoubleValue(totalDeliveryCosts);
297      flpSolution.TotalOverbookedCapacityParameter.Value = new DoubleValue(bestFlpQuality - totalOpeningCosts - totalDeliveryCosts);
298
299      var depots = bestFlpSolution.Select((x, i) => Tuple.Create(x, i)).GroupBy(x => x.Item1, x => x.Item2);
300      var vrpSolutions = new ResultCollection(depots.Count());
301      foreach (var depot in depots.OrderBy(x => x.Key)) {
302        var depotIdx = depot.Key;
303        var customers = depot.ToArray();
304
305        var vrp = (VehicleRoutingProblem)VrpParameter.Value.Clone();
306        var vrpInstance = (CVRPProblemInstance)vrp.ProblemInstance;
307        var coordinates = LrpUtils.GetVrpCoordinates(depotCoordinates, customerCoordinates, depot.Key, customers);
308        var distances = LrpUtils.GetVrpDistances(coordinates, distanceType);
309        vrpInstance.Coordinates = new DoubleMatrix(coordinates);
310        vrpInstance.DistanceMatrix = new DoubleMatrix(distances);
311        vrpInstance.Demand = new DoubleArray(new[] { 0.0 }.Concat(customers.Select(x => customerDemands[x])).ToArray());
312        vrpInstance.Vehicles.Value = customers.Length;
313
314        var vrpMsg = VrpSolverOrchestrationPort.PrepareMessage();
315        vrpMsg["OrchestrationMessage"] = new EnumValue<OrchestrationMessage>(OrchestrationMessage.Prepare | OrchestrationMessage.Start);
316        vrpMsg["Problem"] = vrp;
317        VrpSolverOrchestrationPort.SendMessage(vrpMsg);
318        cts.Token.ThrowIfCancellationRequested();
319
320        var bestVrpSolution = (VRPSolution)vrpResults["Best valid VRP Solution"].Value.Clone();
321        vrpSolutions.Add(new Result("Depot " + depot.Key, bestVrpSolution));
322      }
323
324      #region Analyze
325      double objectiveValue = LrpUtils.Evaluate(flpSolution, vrpSolutions.Select(x => (VRPSolution)x.Value).ToArray());
326      ((DoubleValue)message["Quality"]).Value = objectiveValue;
327
328      IResult bestQuality;
329      if (!Results.TryGetValue("Best LRP Quality", out bestQuality)) {
330        Results.Add(new Result("Best LRP Quality", new DoubleValue(objectiveValue)));
331        Results.Add(new Result("Best FLP Solution", flpSolution));
332        Results.Add(new Result("Best VRP Solutions", vrpSolutions));
333      } else if (objectiveValue < ((DoubleValue)bestQuality.Value).Value) {
334        ((DoubleValue)bestQuality.Value).Value = objectiveValue;
335        Results["Best FLP Solution"].Value = flpSolution;
336        Results["Best VRP Solutions"].Value = vrpSolutions;
337      }
338      #endregion
339    }
340    #endregion
341
342    #region VrpSolver Message Handling
343    private void VrpSolverOrchestrationPortMessage(IMessage message) {
344      var results = (ResultCollection)message["Results"];
345      if (results.ContainsKey("Best valid VRP Solution")) {
346        vrpResults = results;
347      }
348    }
349
350    private void VrpSolverEvaluationPortMessage(IMessage message) { }
351    #endregion
352
353    #region KspSolver Message Handling
354    private void FlpSolverOrchestrationPortMessage(IMessage message) {
355      var results = (ResultCollection)message["Results"];
356      if (results.ContainsKey("Best Solution")) {
357        flpResults = results;
358      }
359    }
360
361    private void FlpSolverEvaluationPortMessage(IMessage message) { }
362    #endregion
363
364    #region Event Handlers
365    private void MetaSolverOrchestrationPort_ConnectedPortChanged(object sender, EventArgs e) {
366      if (MetaSolverOrchestrationPort.ConnectedPort == null) return;
367
368      var node = MetaSolverOrchestrationPort.ConnectedPort.Parent as OrchestratedAlgorithmNode;
369      if (node == null) return;
370
371      var hook = new HookOperator { Name = "Meta Eval Hook" };
372      hook.Parameters.Add(new LookupParameter<RealVector>("RealVector") { Hidden = true });
373      hook.Parameters.Add(new LookupParameter<DoubleValue>("Quality") { Hidden = true });
374      node.EvalHook = hook;
375
376      node.OrchestrationPort.CloneParametersFromPort(MetaSolverOrchestrationPort);
377      node.EvaluationPort.CloneParametersFromPort(MetaSolverEvaluationPort);
378      node.EvaluationPort.ConnectedPort = MetaSolverEvaluationPort;
379    }
380
381    private void VrpSolverOrchestrationPort_ConnectedPortChanged(object sender, EventArgs e) {
382      if (VrpSolverOrchestrationPort.ConnectedPort == null) return;
383
384      var node = VrpSolverOrchestrationPort.ConnectedPort.Parent as OrchestratedAlgorithmNode;
385      if (node == null) return;
386
387      var hook = new HookOperator { Name = "VRP Eval Hook" };
388      hook.Parameters.Add(new LookupParameter<Permutation>("VRPTours") { Hidden = true });
389      hook.Parameters.Add(new LookupParameter<DoubleValue>("Quality") { Hidden = true });
390      node.EvalHook = hook;
391
392      node.OrchestrationPort.CloneParametersFromPort(VrpSolverOrchestrationPort);
393      node.EvaluationPort.CloneParametersFromPort(VrpSolverEvaluationPort);
394      node.EvaluationPort.ConnectedPort = VrpSolverEvaluationPort;
395    }
396
397    private void FlpSolverOrchestrationPort_ConnectedPortChanged(object sender, EventArgs e) {
398      if (FlpSolverOrchestrationPort.ConnectedPort == null) return;
399
400      var node = FlpSolverOrchestrationPort.ConnectedPort.Parent as OrchestratedAlgorithmNode;
401      if (node == null) return;
402
403      var hook = new HookOperator { Name = "FLP Eval Hook" };
404      hook.Parameters.Add(new LookupParameter<BinaryVector>("IntegerVector") { Hidden = true });
405      hook.Parameters.Add(new LookupParameter<DoubleValue>("Quality") { Hidden = true });
406      node.EvalHook = hook;
407
408      node.OrchestrationPort.CloneParametersFromPort(FlpSolverOrchestrationPort);
409      node.EvaluationPort.CloneParametersFromPort(FlpSolverEvaluationPort);
410      node.EvaluationPort.ConnectedPort = FlpSolverEvaluationPort;
411    }
412    #endregion
413  }
414}
Note: See TracBrowser for help on using the repository browser.