source: stable/HeuristicLab.Problems.VehicleRouting/3.4/ProblemInstances/MultiDepotVRP/MultiDepotVRPProblemInstance.cs @ 15219

Last change on this file since 15219 was 15219, checked in by abeham, 3 years ago

#2696, #2790: merged revisions 15072, 15083, 15168 to stable

File size: 7.3 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2016 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 HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Optimization;
29using HeuristicLab.Parameters;
30using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
31using HeuristicLab.PluginInfrastructure;
32using HeuristicLab.Problems.VehicleRouting.Interfaces;
33using HeuristicLab.Problems.VehicleRouting.Variants;
34
35namespace HeuristicLab.Problems.VehicleRouting.ProblemInstances {
36  [Item("MultiDepotVRPProblemInstance", "Represents a multi depot VRP instance.")]
37  [StorableClass]
38  public class MultiDepotVRPProblemInstance : VRPProblemInstance, IMultiDepotProblemInstance {
39    protected IValueParameter<IntValue> DepotsParameter {
40      get { return (IValueParameter<IntValue>)Parameters["Depots"]; }
41    }
42
43    protected IValueParameter<IntArray> VehicleDepotAssignmentParameter {
44      get { return (IValueParameter<IntArray>)Parameters["VehicleDepotAssignment"]; }
45    }
46
47    public IntValue Depots {
48      get {
49        return DepotsParameter.Value;
50      }
51    }
52
53    public IntArray VehicleDepotAssignment {
54      get {
55        return VehicleDepotAssignmentParameter.Value;
56      }
57      set {
58        VehicleDepotAssignmentParameter.Value = value;
59      }
60    }
61
62    protected override IEnumerable<IOperator> GetOperators() {
63      return ApplicationManager.Manager.GetInstances<IMultiDepotOperator>().Cast<IOperator>();
64    }
65
66    protected override IEnumerable<IOperator> GetAnalyzers() {
67      return ApplicationManager.Manager.GetInstances<IMultiDepotOperator>()
68        .Where(o => o is IAnalyzer)
69        .Cast<IOperator>();
70    }
71
72    public override IntValue Cities {
73      get {
74        return new IntValue(Demand.Length);
75      }
76    }
77
78    protected override IVRPEvaluator Evaluator {
79      get {
80        return new MultiDepotVRPEvaluator();
81      }
82    }
83
84    protected override IVRPCreator Creator {
85      get {
86        return new HeuristicLab.Problems.VehicleRouting.Encodings.Alba.RandomCreator();
87      }
88    }
89
90    public override double GetDemand(int city) {
91      return base.GetDemand(city - 1);
92    }
93
94    public override double[] GetCoordinates(int city) {
95      double[] coordinates;
96
97      if (city == 0) {
98        //calculate centroid
99        coordinates = new double[Coordinates.Columns];
100
101        for (int i = 0; i < Depots.Value; i++) {
102          for (int j = 0; j < coordinates.Length; j++) {
103            coordinates[j] += Coordinates[i, j];
104          }
105        }
106
107        for (int j = 0; j < coordinates.Length; j++) {
108          coordinates[j] /= (double)Depots.Value;
109        }
110      } else {
111        city += Depots.Value - 1;
112        coordinates = base.GetCoordinates(city);
113      }
114
115      return coordinates;
116    }
117
118    public int GetDepot(int customer, IVRPEncoding solution) {
119      int depot = -1;
120
121      Tour tour =
122          solution.GetTours().FirstOrDefault(t => t.Stops.Contains(customer));
123
124      if (tour != null) {
125        int tourIndex = solution.GetTourIndex(tour);
126        int vehicle = solution.GetVehicleAssignment(tourIndex);
127        depot = VehicleDepotAssignment[vehicle];
128      }
129
130      return depot;
131    }
132
133    public override double GetDistance(int start, int end, IVRPEncoding solution) {
134      if (start == 0 && end == 0)
135        return 0;
136
137      if (start == 0) {
138        start = GetDepot(end, solution);
139        end += Depots.Value - 1;
140      } else if (end == 0) {
141        end = GetDepot(start, solution);
142        start += Depots.Value - 1;
143      } else {
144        start += Depots.Value - 1;
145        end += Depots.Value - 1;
146      }
147
148      return base.GetDistance(start, end, solution);
149    }
150
151    public override double GetInsertionDistance(int start, int customer, int end, IVRPEncoding solution,
152      out double startDistance, out double endDistance) {
153      if (start == 0) {
154        start = GetDepot(end, solution);
155        end += Depots.Value - 1;
156      } else if (end == 0) {
157        end = GetDepot(start, solution);
158        start += Depots.Value - 1;
159      } else {
160        start += Depots.Value - 1;
161        end += Depots.Value - 1;
162      }
163      customer += Depots.Value - 1;
164
165      double distance = base.GetDistance(start, end, solution);
166
167      startDistance = base.GetDistance(start, customer, solution);
168      endDistance = base.GetDistance(customer, end, solution);
169
170      double newDistance = startDistance + endDistance;
171
172      return newDistance - distance;
173    }
174
175    [StorableConstructor]
176    protected MultiDepotVRPProblemInstance(bool deserializing) : base(deserializing) { }
177    protected MultiDepotVRPProblemInstance(MultiDepotVRPProblemInstance original, Cloner cloner)
178      : base(original, cloner) {
179      AttachEventHandlers();
180    }
181    public MultiDepotVRPProblemInstance() {
182      Parameters.Add(new ValueParameter<IntValue>("Depots", "The number of depots", new IntValue(0)));
183      Parameters.Add(new ValueParameter<IntArray>("VehicleDepotAssignment", "The assignment of vehicles to depots", new IntArray()));
184      AttachEventHandlers();
185    }
186
187    public override IDeepCloneable Clone(Cloner cloner) {
188      return new MultiDepotVRPProblemInstance(this, cloner);
189    }
190
191    [StorableHook(HookType.AfterDeserialization)]
192    private void AfterDeserialization() {
193      AttachEventHandlers();
194    }
195
196    private void AttachEventHandlers() {
197      DepotsParameter.ValueChanged += DepotsParameter_ValueChanged;
198      Depots.ValueChanged += Depots_ValueChanged;
199      VehicleDepotAssignmentParameter.ValueChanged += VehicleDepotAssignmentParameter_ValueChanged;
200      VehicleDepotAssignment.Reset += VehicleDepotAssignment_Changed;
201      VehicleDepotAssignment.ItemChanged += VehicleDepotAssignment_Changed;
202    }
203
204    #region Event handlers
205    private void DepotsParameter_ValueChanged(object sender, EventArgs e) {
206      Depots.ValueChanged += Depots_ValueChanged;
207      EvalBestKnownSolution();
208    }
209    private void Depots_ValueChanged(object sender, EventArgs e) {
210      EvalBestKnownSolution();
211    }
212    private void VehicleDepotAssignmentParameter_ValueChanged(object sender, EventArgs e) {
213      VehicleDepotAssignment.Reset += VehicleDepotAssignment_Changed;
214      VehicleDepotAssignment.ItemChanged += VehicleDepotAssignment_Changed;
215      EvalBestKnownSolution();
216    }
217    private void VehicleDepotAssignment_Changed(object sender, EventArgs e) {
218      EvalBestKnownSolution();
219    }
220    #endregion
221  }
222}
Note: See TracBrowser for help on using the repository browser.