Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Problems.VehicleRouting/3.4/ProblemInstances/VRPProblemInstance.cs @ 14517

Last change on this file since 14517 was 14482, checked in by pfleck, 8 years ago

#2705

  • Added best-known solutions to the Solomon benchmark set.
  • When the distance matrix is calculate internally for performance optimization, the DistanceMatrix-parameter is not set anymore, because this matrix is actually not part of the problem instance. This also fixes issues that qualities of known-solutions are wrongfully discarded due to a problem instance change that is actually not a change.
File size: 12.7 KB
RevLine 
[4362]1#region License Information
2/* HeuristicLab
[14185]3 * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[4362]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;
[7934]25using HeuristicLab.Common;
[4362]26using HeuristicLab.Core;
[7934]27using HeuristicLab.Data;
[4362]28using HeuristicLab.Parameters;
[7934]29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
[5867]30using HeuristicLab.Problems.VehicleRouting.Encodings.General;
[7934]31using HeuristicLab.Problems.VehicleRouting.Interfaces;
[4362]32
33namespace HeuristicLab.Problems.VehicleRouting.ProblemInstances {
34  [Item("VRPProblemInstance", "Represents a VRP instance.")]
35  [StorableClass]
[6711]36  public abstract class VRPProblemInstance : ParameterizedNamedItem, IVRPProblemInstance, IStatefulItem {
[5867]37    IVRPEvaluator moveEvaluator;
38
[9321]39    private object locker = new object();
40
[5867]41    public IVRPEvaluator MoveEvaluator {
42      get {
[9321]43        lock (locker) {
44          if (evaluator == null)
45            return null;
46          else {
47            if (moveEvaluator == null) {
48              moveEvaluator = evaluator.Clone() as IVRPEvaluator;
[5867]49
[9321]50              foreach (IParameter parameter in moveEvaluator.Parameters) {
51                if (parameter is ILookupParameter
52                  && parameter != moveEvaluator.ProblemInstanceParameter
53                  && parameter != moveEvaluator.VRPToursParameter) {
54                  (parameter as ILookupParameter).ActualName =
55                    VRPMoveEvaluator.MovePrefix +
56                    (parameter as ILookupParameter).ActualName;
57                }
[5867]58              }
59            }
[9321]60
61            return moveEvaluator;
[5867]62          }
63        }
64      }
65    }
66
[4374]67    protected abstract IEnumerable<IOperator> GetOperators();
68    protected abstract IEnumerable<IOperator> GetAnalyzers();
69
70    public IEnumerable<IOperator> Operators {
71      get {
72        return GetOperators().Union(GetAnalyzers());
73      }
74    }
[7934]75
[4362]76    protected ValueParameter<DoubleMatrix> CoordinatesParameter {
77      get { return (ValueParameter<DoubleMatrix>)Parameters["Coordinates"]; }
78    }
[4380]79    protected OptionalValueParameter<DoubleMatrix> DistanceMatrixParameter {
80      get { return (OptionalValueParameter<DoubleMatrix>)Parameters["DistanceMatrix"]; }
81    }
[4362]82    protected ValueParameter<BoolValue> UseDistanceMatrixParameter {
83      get { return (ValueParameter<BoolValue>)Parameters["UseDistanceMatrix"]; }
84    }
85    protected ValueParameter<IntValue> VehiclesParameter {
86      get { return (ValueParameter<IntValue>)Parameters["Vehicles"]; }
87    }
88    protected ValueParameter<DoubleArray> DemandParameter {
89      get { return (ValueParameter<DoubleArray>)Parameters["Demand"]; }
90    }
91
92    protected IValueParameter<DoubleValue> FleetUsageFactorParameter {
93      get { return (IValueParameter<DoubleValue>)Parameters["EvalFleetUsageFactor"]; }
94    }
95    protected IValueParameter<DoubleValue> DistanceFactorParameter {
96      get { return (IValueParameter<DoubleValue>)Parameters["EvalDistanceFactor"]; }
97    }
98
99    public DoubleMatrix Coordinates {
100      get { return CoordinatesParameter.Value; }
101      set { CoordinatesParameter.Value = value; }
102    }
[4380]103
104    public DoubleMatrix DistanceMatrix {
105      get { return DistanceMatrixParameter.Value; }
106      set { DistanceMatrixParameter.Value = value; }
107    }
[4362]108    public BoolValue UseDistanceMatrix {
109      get { return UseDistanceMatrixParameter.Value; }
110      set { UseDistanceMatrixParameter.Value = value; }
111    }
112    public IntValue Vehicles {
113      get { return VehiclesParameter.Value; }
114      set { VehiclesParameter.Value = value; }
115    }
116    public DoubleArray Demand {
117      get { return DemandParameter.Value; }
118      set { DemandParameter.Value = value; }
119    }
[4365]120    public virtual IntValue Cities {
[4362]121      get { return new IntValue(Demand.Length); }
122    }
123
124    public DoubleValue FleetUsageFactor {
125      get { return FleetUsageFactorParameter.Value; }
126      set { FleetUsageFactorParameter.Value = value; }
127    }
128    public DoubleValue DistanceFactor {
129      get { return DistanceFactorParameter.Value; }
130      set { DistanceFactorParameter.Value = value; }
131    }
132
[6885]133    protected virtual double CalculateDistance(int start, int end) {
[4362]134      double distance = 0.0;
135
136      distance =
137          Math.Sqrt(
138            Math.Pow(Coordinates[start, 0] - Coordinates[end, 0], 2) +
139            Math.Pow(Coordinates[start, 1] - Coordinates[end, 1], 2));
140
141      return distance;
142    }
143
144    private DoubleMatrix CreateDistanceMatrix() {
145      DoubleMatrix distanceMatrix = new DoubleMatrix(Coordinates.Rows, Coordinates.Rows);
146
147      for (int i = 0; i < distanceMatrix.Rows; i++) {
[7543]148        for (int j = 0; j < distanceMatrix.Columns; j++) {
[4362]149          double distance = CalculateDistance(i, j);
150
151          distanceMatrix[i, j] = distance;
152        }
153      }
154
155      return distanceMatrix;
156    }
[6607]157
[6851]158    public virtual double[] GetCoordinates(int city) {
159      double[] coordinates = new double[Coordinates.Columns];
160
161      for (int i = 0; i < Coordinates.Columns; i++) {
162        coordinates[i] = Coordinates[city, i];
163      }
164
165      return coordinates;
166    }
167
168    public virtual double GetDemand(int city) {
169      return Demand[city];
170    }
171
[6607]172    //cache for performance improvement
173    private DoubleMatrix distanceMatrix = null;
174    private IVRPEvaluator evaluator = null;
175
[7852]176    public IVRPEvaluator SolutionEvaluator {
[7934]177      get {
[7852]178        return evaluator;
179      }
[8006]180
181      set {
[9321]182        lock (locker) {
183          moveEvaluator = null;
184          evaluator = value;
185          EvalBestKnownSolution();
186        }
[8006]187      }
[7852]188    }
189
[6851]190    public virtual double GetDistance(int start, int end, IVRPEncoding solution) {
[4380]191      if (distanceMatrix == null && UseDistanceMatrix.Value) {
[14482]192        distanceMatrix = DistanceMatrix ?? CreateDistanceMatrix();
[4380]193      }
194
[8922]195      if (distanceMatrix != null) return distanceMatrix[start, end];
196      return CalculateDistance(start, end);
[4362]197    }
198
[6854]199    public virtual double GetInsertionDistance(int start, int customer, int end, IVRPEncoding solution,
200      out double startDistance, out double endDistance) {
[6851]201      double distance = GetDistance(start, end, solution);
202
[6854]203      startDistance = GetDistance(start, customer, solution);
204      endDistance = GetDistance(customer, end, solution);
[7934]205
[6854]206      double newDistance = startDistance + endDistance;
207
[6851]208      return newDistance - distance;
209    }
210
[4362]211    public bool Feasible(IVRPEncoding solution) {
[6607]212      return evaluator.Feasible(
213        evaluator.Evaluate(
[4378]214          this, solution));
[4362]215    }
216
[6838]217    public bool TourFeasible(Tour tour, IVRPEncoding solution) {
[6607]218      return evaluator.Feasible(
[6838]219        evaluator.EvaluateTour(
220        this, tour, solution));
[4362]221    }
222
[6607]223    public VRPEvaluation Evaluate(IVRPEncoding solution) {
224      return evaluator.Evaluate(this, solution);
[4362]225    }
226
[6838]227    public VRPEvaluation EvaluateTour(Tour tour, IVRPEncoding solution) {
228      return evaluator.EvaluateTour(this, tour, solution);
[4362]229    }
230
[6607]231    public bool Feasible(VRPEvaluation eval) {
232      return evaluator.Feasible(eval);
233    }
234
[6851]235    public double GetInsertionCosts(VRPEvaluation eval, IVRPEncoding solution, int customer, int tour, int index, out bool feasible) {
236      return evaluator.GetInsertionCosts(this, solution, eval, customer, tour, index, out feasible);
[6752]237    }
238
[7852]239
240    public event EventHandler EvaluationChanged;
241
[4860]242    protected void EvalBestKnownSolution() {
[7852]243      EventHandler tmp = EvaluationChanged;
244      if (tmp != null)
245        tmp(this, null);
[4860]246    }
247
[4362]248    protected abstract IVRPEvaluator Evaluator { get; }
249    protected abstract IVRPCreator Creator { get; }
[7934]250
[4362]251    [StorableConstructor]
252    protected VRPProblemInstance(bool deserializing) : base(deserializing) { }
253
254    public VRPProblemInstance()
255      : base() {
256      Parameters.Add(new ValueParameter<DoubleMatrix>("Coordinates", "The x- and y-Coordinates of the cities.", new DoubleMatrix()));
[4380]257      Parameters.Add(new OptionalValueParameter<DoubleMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
[4362]258      Parameters.Add(new ValueParameter<BoolValue>("UseDistanceMatrix", "True if a distance matrix should be calculated and used for evaluation, otherwise false.", new BoolValue(true)));
259      Parameters.Add(new ValueParameter<IntValue>("Vehicles", "The number of vehicles.", new IntValue(0)));
260      Parameters.Add(new ValueParameter<DoubleArray>("Demand", "The demand of each customer.", new DoubleArray()));
261
[5127]262      Parameters.Add(new ValueParameter<DoubleValue>("EvalFleetUsageFactor", "The fleet usage factor considered in the evaluation.", new DoubleValue(0)));
[4362]263      Parameters.Add(new ValueParameter<DoubleValue>("EvalDistanceFactor", "The distance factor considered in the evaluation.", new DoubleValue(1)));
264
[7852]265      evaluator = Evaluator;
[4860]266      AttachEventHandlers();
[4362]267    }
[4752]268
269    protected VRPProblemInstance(VRPProblemInstance original, Cloner cloner)
270      : base(original, cloner) {
[7934]271      evaluator = Evaluator;
[7852]272      AttachEventHandlers();
[4752]273    }
[4860]274
275    [StorableHook(HookType.AfterDeserialization)]
[7934]276    private void AfterDeserialization() {
[7852]277      evaluator = Evaluator;
[4860]278      AttachEventHandlers();
279    }
280
281    private void AttachEventHandlers() {
282      DistanceFactorParameter.ValueChanged += new EventHandler(DistanceFactorParameter_ValueChanged);
283      DistanceFactorParameter.Value.ValueChanged += new EventHandler(DistanceFactor_ValueChanged);
284      FleetUsageFactorParameter.ValueChanged += new EventHandler(FleetUsageFactorParameter_ValueChanged);
285      FleetUsageFactorParameter.Value.ValueChanged += new EventHandler(FleetUsageFactor_ValueChanged);
286      DistanceMatrixParameter.ValueChanged += new EventHandler(DistanceMatrixParameter_ValueChanged);
287      if (DistanceMatrix != null) {
288        DistanceMatrix.ItemChanged += new EventHandler<EventArgs<int, int>>(DistanceMatrix_ItemChanged);
289        DistanceMatrix.Reset += new EventHandler(DistanceMatrix_Reset);
290      }
291      UseDistanceMatrixParameter.ValueChanged += new EventHandler(UseDistanceMatrixParameter_ValueChanged);
292      UseDistanceMatrix.ValueChanged += new EventHandler(UseDistanceMatrix_ValueChanged);
293    }
294
[6711]295    public virtual void InitializeState() {
296    }
297
298    public virtual void ClearState() {
299    }
300
[4860]301    #region Event handlers
302    void DistanceFactorParameter_ValueChanged(object sender, EventArgs e) {
303      DistanceFactorParameter.Value.ValueChanged += new EventHandler(DistanceFactor_ValueChanged);
304      EvalBestKnownSolution();
305    }
306    void DistanceFactor_ValueChanged(object sender, EventArgs e) {
307      EvalBestKnownSolution();
308    }
309    void FleetUsageFactorParameter_ValueChanged(object sender, EventArgs e) {
310      FleetUsageFactorParameter.Value.ValueChanged += new EventHandler(FleetUsageFactor_ValueChanged);
311      EvalBestKnownSolution();
312    }
313    void FleetUsageFactor_ValueChanged(object sender, EventArgs e) {
314      EvalBestKnownSolution();
315    }
316    void DistanceMatrixParameter_ValueChanged(object sender, EventArgs e) {
317      if (DistanceMatrix != null) {
318        DistanceMatrix.ItemChanged += new EventHandler<EventArgs<int, int>>(DistanceMatrix_ItemChanged);
319        DistanceMatrix.Reset += new EventHandler(DistanceMatrix_Reset);
320      }
[6607]321      distanceMatrix = DistanceMatrix;
[4860]322      EvalBestKnownSolution();
323    }
324    void DistanceMatrix_Reset(object sender, EventArgs e) {
325      EvalBestKnownSolution();
326    }
327    void DistanceMatrix_ItemChanged(object sender, EventArgs<int, int> e) {
[6607]328      distanceMatrix = DistanceMatrix;
[4860]329      EvalBestKnownSolution();
330    }
331    void UseDistanceMatrixParameter_ValueChanged(object sender, EventArgs e) {
332      UseDistanceMatrix.ValueChanged += new EventHandler(UseDistanceMatrix_ValueChanged);
[6607]333      if (!UseDistanceMatrix.Value)
334        distanceMatrix = null;
[4860]335      EvalBestKnownSolution();
336    }
337    void UseDistanceMatrix_ValueChanged(object sender, EventArgs e) {
[6607]338      if (!UseDistanceMatrix.Value)
339        distanceMatrix = null;
[4860]340      EvalBestKnownSolution();
341    }
342    #endregion
[4362]343  }
344}
Note: See TracBrowser for help on using the repository browser.