Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2205: worked on optimization networks

  • added abstract base classes for ttp networks/orchestrators
  • removed ttp networks/orchestrators from HeuristicLab.Networks.IntegratedOptimization
  • runs can now be cleared when preparing OrchestratedAlgorithmNodes
File size: 18.4 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 = new double[0, 0], customerCoordinates = new double[0, 0];
64    [Storable]
65    LrpUtils.DistanceType distanceType;
66    [Storable]
67    double[] depotCapacities = new double[0], customerDemands = new double[0], depotCosts = new double[0];
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      Prepare();
191    }
192
193    public override void Prepare(bool clearRuns = false) {
194      Results.Clear();
195
196      var metaMsg = MetaSolverOrchestrationPort.PrepareMessage();
197      var msgFlags = OrchestrationMessage.Prepare | OrchestrationMessage.SetEvalHook;
198      if (clearRuns) msgFlags |= OrchestrationMessage.ClearRuns;
199      metaMsg["OrchestrationMessage"] = new EnumValue<OrchestrationMessage>(msgFlags);
200      var problem = new VariegationProblem();
201      problem.Encoding.Length = FlpParameter.Value.Encoding.Length * 2;
202      problem.Encoding.Bounds = new DoubleMatrix(new[,] { { 0.0, 2.0 } });
203      metaMsg["Problem"] = problem;
204      MetaSolverOrchestrationPort.SendMessage(metaMsg);
205    }
206
207    public override void Start() {
208      cts = new CancellationTokenSource();
209
210      var metaMsg = MetaSolverOrchestrationPort.PrepareMessage();
211      metaMsg["OrchestrationMessage"] = new EnumValue<OrchestrationMessage>(OrchestrationMessage.Start);
212      MetaSolverOrchestrationPort.SendMessage(metaMsg);
213    }
214
215    public override void Pause() {
216      cts.Cancel();
217
218      var metaMsg = MetaSolverOrchestrationPort.PrepareMessage();
219      metaMsg["OrchestrationMessage"] = new EnumValue<OrchestrationMessage>(OrchestrationMessage.Pause);
220      MetaSolverOrchestrationPort.SendMessage(metaMsg);
221
222      var vrpMsg = VrpSolverOrchestrationPort.PrepareMessage();
223      vrpMsg["OrchestrationMessage"] = new EnumValue<OrchestrationMessage>(OrchestrationMessage.Stop);
224      VrpSolverOrchestrationPort.SendMessage(vrpMsg);
225
226      var kspMsg = FlpSolverOrchestrationPort.PrepareMessage();
227      kspMsg["OrchestrationMessage"] = new EnumValue<OrchestrationMessage>(OrchestrationMessage.Stop);
228      FlpSolverOrchestrationPort.SendMessage(kspMsg);
229    }
230
231    public override void Stop() {
232      cts.Cancel();
233
234      var metaMsg = MetaSolverOrchestrationPort.PrepareMessage();
235      metaMsg["OrchestrationMessage"] = new EnumValue<OrchestrationMessage>(OrchestrationMessage.Stop);
236      MetaSolverOrchestrationPort.SendMessage(metaMsg);
237
238      var vrpMsg = VrpSolverOrchestrationPort.PrepareMessage();
239      vrpMsg["OrchestrationMessage"] = new EnumValue<OrchestrationMessage>(OrchestrationMessage.Stop);
240      VrpSolverOrchestrationPort.SendMessage(vrpMsg);
241
242      var kspMsg = FlpSolverOrchestrationPort.PrepareMessage();
243      kspMsg["OrchestrationMessage"] = new EnumValue<OrchestrationMessage>(OrchestrationMessage.Stop);
244      FlpSolverOrchestrationPort.SendMessage(kspMsg);
245    }
246
247    protected override void ProcessMessage(IMessage message, IMessagePort port, CancellationToken token) {
248      var messageActions = new Dictionary<IMessagePort, Action<IMessage>>();
249      messageActions.Add(MetaSolverOrchestrationPort, MetaSolverOrchestrationPortMessage);
250      messageActions.Add(MetaSolverEvaluationPort, MetaSolverEvaluationPortMessage);
251      messageActions.Add(VrpSolverOrchestrationPort, VrpSolverOrchestrationPortMessage);
252      messageActions.Add(VrpSolverEvaluationPort, VrpSolverEvaluationPortMessage);
253      messageActions.Add(FlpSolverOrchestrationPort, FlpSolverOrchestrationPortMessage);
254      messageActions.Add(FlpSolverEvaluationPort, FlpSolverEvaluationPortMessage);
255
256      messageActions[port](message);
257
258      base.ProcessMessage(message, port, token);
259    }
260
261    #region MetaSolver Message Handling
262    private void MetaSolverOrchestrationPortMessage(IMessage message) { }
263
264    private void MetaSolverEvaluationPortMessage(IMessage message) {
265      var factors = (RealVector)message["RealVector"];
266
267      var flp = (FacilityLocationProblem)FlpParameter.Value.Clone();
268      var cc = (double[,])customerCoordinates.Clone();
269      for (int i = 0; i < nrOfCustomers; i++) {
270        cc[i, 0] = cc[i, 0] * factors[i * 2];
271        cc[i, 1] = cc[i, 1] * factors[i * 2 + 1];
272      }
273      flp.DeliveryCostsParameter.Value = new DoubleMatrix(LrpUtils.GetFlpDeliveryCosts(depotCoordinates, cc, distanceType));
274
275      var flpMsg = FlpSolverOrchestrationPort.PrepareMessage();
276      flpMsg["OrchestrationMessage"] = new EnumValue<OrchestrationMessage>(OrchestrationMessage.Prepare | OrchestrationMessage.ClearRuns | OrchestrationMessage.Start);
277      flpMsg["Problem"] = flp;
278      FlpSolverOrchestrationPort.SendMessage(flpMsg);
279      cts.Token.ThrowIfCancellationRequested();
280
281      var bestFlpSolution = (IntegerVector)flpResults["Best Solution"].Value;
282      var flpSolution = FlpParameter.Value.GetSolution(bestFlpSolution);
283
284      var depots = bestFlpSolution.Select((x, i) => Tuple.Create(x, i)).GroupBy(x => x.Item1, x => x.Item2);
285      var vrpSolutions = new ResultCollection(depots.Count());
286      foreach (var depot in depots.OrderBy(x => x.Key)) {
287        var depotIdx = depot.Key;
288        var customers = depot.ToArray();
289
290        var vrp = (VehicleRoutingProblem)VrpParameter.Value.Clone();
291        var vrpInstance = (CVRPProblemInstance)vrp.ProblemInstance;
292        var coordinates = LrpUtils.GetVrpCoordinates(depotCoordinates, customerCoordinates, depotIdx, customers);
293        var distances = LrpUtils.GetVrpDistances(coordinates, distanceType);
294        vrpInstance.Coordinates = new DoubleMatrix(coordinates);
295        vrpInstance.DistanceMatrix = new DoubleMatrix(distances);
296        vrpInstance.Demand = new DoubleArray(new[] { 0.0 }.Concat(customers.Select(x => customerDemands[x])).ToArray());
297        vrpInstance.Vehicles.Value = customers.Length;
298
299        var vrpMsg = VrpSolverOrchestrationPort.PrepareMessage();
300        vrpMsg["OrchestrationMessage"] = new EnumValue<OrchestrationMessage>(OrchestrationMessage.Prepare | OrchestrationMessage.ClearRuns | OrchestrationMessage.Start);
301        vrpMsg["Problem"] = vrp;
302        VrpSolverOrchestrationPort.SendMessage(vrpMsg);
303        cts.Token.ThrowIfCancellationRequested();
304
305        var bestVrpSolution = (VRPSolution)vrpResults["Best valid VRP Solution"].Value.Clone();
306        vrpSolutions.Add(new Result("Depot " + depot.Key, bestVrpSolution));
307      }
308
309      #region Analyze
310      double objectiveValue = LrpUtils.Evaluate(flpSolution, vrpSolutions.Select(x => (VRPSolution)x.Value).ToArray());
311      ((DoubleValue)message["Quality"]).Value = objectiveValue;
312
313      IResult bestQuality;
314      if (!Results.TryGetValue("Best LRP Quality", out bestQuality)) {
315        Results.Add(new Result("Best LRP Quality", new DoubleValue(objectiveValue)));
316        Results.Add(new Result("Best FLP Solution", flpSolution));
317        Results.Add(new Result("Best VRP Solutions", vrpSolutions));
318      } else if (objectiveValue < ((DoubleValue)bestQuality.Value).Value) {
319        ((DoubleValue)bestQuality.Value).Value = objectiveValue;
320        Results["Best FLP Solution"].Value = flpSolution;
321        Results["Best VRP Solutions"].Value = vrpSolutions;
322      }
323      #endregion
324    }
325    #endregion
326
327    #region VrpSolver Message Handling
328    private void VrpSolverOrchestrationPortMessage(IMessage message) {
329      var results = (ResultCollection)message["Results"];
330      if (results.ContainsKey("Best valid VRP Solution")) {
331        vrpResults = results;
332      }
333    }
334
335    private void VrpSolverEvaluationPortMessage(IMessage message) { }
336    #endregion
337
338    #region KspSolver Message Handling
339    private void FlpSolverOrchestrationPortMessage(IMessage message) {
340      var results = (ResultCollection)message["Results"];
341      if (results.ContainsKey("Best Solution")) {
342        flpResults = results;
343      }
344    }
345
346    private void FlpSolverEvaluationPortMessage(IMessage message) { }
347    #endregion
348
349    #region Event Handlers
350    private void MetaSolverOrchestrationPort_ConnectedPortChanged(object sender, EventArgs e) {
351      if (MetaSolverOrchestrationPort.ConnectedPort == null) return;
352
353      var node = MetaSolverOrchestrationPort.ConnectedPort.Parent as OrchestratedAlgorithmNode;
354      if (node == null) return;
355
356      var hook = new HookOperator { Name = "Meta Eval Hook" };
357      hook.Parameters.Add(new LookupParameter<RealVector>("RealVector") { Hidden = true });
358      hook.Parameters.Add(new LookupParameter<DoubleValue>("Quality") { Hidden = true });
359      node.EvalHook = hook;
360
361      node.OrchestrationPort.CloneParametersFromPort(MetaSolverOrchestrationPort);
362      node.EvaluationPort.CloneParametersFromPort(MetaSolverEvaluationPort);
363      node.EvaluationPort.ConnectedPort = MetaSolverEvaluationPort;
364    }
365
366    private void VrpSolverOrchestrationPort_ConnectedPortChanged(object sender, EventArgs e) {
367      if (VrpSolverOrchestrationPort.ConnectedPort == null) return;
368
369      var node = VrpSolverOrchestrationPort.ConnectedPort.Parent as OrchestratedAlgorithmNode;
370      if (node == null) return;
371
372      var hook = new HookOperator { Name = "VRP Eval Hook" };
373      hook.Parameters.Add(new LookupParameter<Permutation>("VRPTours") { Hidden = true });
374      hook.Parameters.Add(new LookupParameter<DoubleValue>("Quality") { Hidden = true });
375      node.EvalHook = hook;
376
377      node.OrchestrationPort.CloneParametersFromPort(VrpSolverOrchestrationPort);
378      node.EvaluationPort.CloneParametersFromPort(VrpSolverEvaluationPort);
379      node.EvaluationPort.ConnectedPort = VrpSolverEvaluationPort;
380    }
381
382    private void FlpSolverOrchestrationPort_ConnectedPortChanged(object sender, EventArgs e) {
383      if (FlpSolverOrchestrationPort.ConnectedPort == null) return;
384
385      var node = FlpSolverOrchestrationPort.ConnectedPort.Parent as OrchestratedAlgorithmNode;
386      if (node == null) return;
387
388      var hook = new HookOperator { Name = "FLP Eval Hook" };
389      hook.Parameters.Add(new LookupParameter<BinaryVector>("IntegerVector") { Hidden = true });
390      hook.Parameters.Add(new LookupParameter<DoubleValue>("Quality") { Hidden = true });
391      node.EvalHook = hook;
392
393      node.OrchestrationPort.CloneParametersFromPort(FlpSolverOrchestrationPort);
394      node.EvaluationPort.CloneParametersFromPort(FlpSolverEvaluationPort);
395      node.EvaluationPort.ConnectedPort = FlpSolverEvaluationPort;
396    }
397    #endregion
398  }
399}
Note: See TracBrowser for help on using the repository browser.