Changeset 17525 for branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/Improvers
- Timestamp:
- 05/07/20 17:41:18 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/Improvers/OrienteeringLocalImprovementOperator.cs
r17226 r17525 22 22 using System.Collections.Generic; 23 23 using System.Linq; 24 using HEAL.Attic; 24 25 using HeuristicLab.Common; 25 26 using HeuristicLab.Core; … … 29 30 using HeuristicLab.Optimization; 30 31 using HeuristicLab.Parameters; 31 using HEAL.Attic;32 32 33 33 namespace HeuristicLab.Problems.Orienteering { … … 45 45 get { return (ILookupParameter<IntegerVector>)Parameters["OrienteeringSolution"]; } 46 46 } 47 public ILookupParameter<DistanceMatrix> DistanceMatrixParameter { 48 get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; } 49 } 50 public ILookupParameter<DoubleArray> ScoresParameter { 51 get { return (ILookupParameter<DoubleArray>)Parameters["Scores"]; } 52 } 53 public ILookupParameter<DoubleValue> MaximumDistanceParameter { 54 get { return (ILookupParameter<DoubleValue>)Parameters["MaximumDistance"]; } 55 } 56 public ILookupParameter<IntValue> StartingPointParameter { 57 get { return (ILookupParameter<IntValue>)Parameters["StartingPoint"]; } 58 } 59 public ILookupParameter<IntValue> TerminalPointParameter { 60 get { return (ILookupParameter<IntValue>)Parameters["TerminalPoint"]; } 61 } 62 public ILookupParameter<DoubleValue> PointVisitingCostsParameter { 63 get { return (ILookupParameter<DoubleValue>)Parameters["PointVisitingCosts"]; } 64 } 47 public ILookupParameter<IOrienteeringProblemData> OrienteeringProblemDataParameter { 48 get { return (ILookupParameter<IOrienteeringProblemData>)Parameters["OrienteeringProblemData"]; } 49 } 50 65 51 #region ILocalImprovementOperator Parameters 66 52 public IValueLookupParameter<IntValue> LocalIterationsParameter { … … 96 82 : base() { 97 83 Parameters.Add(new LookupParameter<IntegerVector>("OrienteeringSolution", "The Orienteering Solution given in path representation.")); 98 Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the points.")); 99 Parameters.Add(new LookupParameter<DoubleArray>("Scores", "The scores of the points.")); 100 Parameters.Add(new LookupParameter<DoubleValue>("MaximumDistance", "The maximum distance constraint for a Orienteering solution.")); 101 Parameters.Add(new LookupParameter<IntValue>("StartingPoint", "Index of the starting point.")); 102 Parameters.Add(new LookupParameter<IntValue>("TerminalPoint", "Index of the ending point.")); 103 Parameters.Add(new LookupParameter<DoubleValue>("PointVisitingCosts", "The costs for visiting a point.")); 84 Parameters.Add(new LookupParameter<IOrienteeringProblemData>("OrienteeringProblemData", "The main data that comprises the orienteering problem.")); 104 85 105 86 Parameters.Add(new ValueLookupParameter<IntValue>("LocalIterations", "The number of iterations that have already been performed.", new IntValue(0))); … … 118 99 119 100 public override IOperation Apply() { 120 int numPoints = ScoresParameter.ActualValue.Length; 121 var distances = DistanceMatrixParameter.ActualValue; 122 var scores = ScoresParameter.ActualValue; 123 double pointVisitingCosts = PointVisitingCostsParameter.ActualValue.Value; 124 double maxLength = MaximumDistanceParameter.ActualValue.Value; 101 var data = OrienteeringProblemDataParameter.ActualValue; 125 102 int maxIterations = MaximumIterationsParameter.ActualValue.Value; 126 103 int maxBlockLength = MaximumBlockLengthParmeter.Value.Value; … … 132 109 133 110 double tourLength = 0; 134 double tourScore = tour.Sum(point => scores[point]);111 double tourScore = tour.Sum(point => data.GetScore(point)); 135 112 136 113 var localIterations = LocalIterationsParameter.ActualValue; … … 143 120 144 121 if (localIterations.Value == 0) 145 tourLength = distances.CalculateTourLength(tour, pointVisitingCosts);122 tourLength = OrienteeringProblem.CalculateTravelCosts(data, tour); 146 123 147 124 // Try to shorten the path 148 ShortenPath(tour, d istances, maxBlockLength, useMaxBlockLength, ref tourLength, ref evaluations);125 ShortenPath(tour, data, maxBlockLength, useMaxBlockLength, ref tourLength, ref evaluations); 149 126 150 127 // Determine all points that have not yet been visited by this tour 151 var visitablePoints = Enumerable.Range(0, numPoints).Except(tour).ToList();128 var visitablePoints = Enumerable.Range(0, data.RoutingData.Cities).Except(tour).ToList(); 152 129 153 130 // Determine if any of the visitable points can be included at any position within the tour 154 IncludeNewPoints(tour, visitablePoints, 155 distances, pointVisitingCosts, maxLength, scores, 156 ref tourLength, ref tourScore, ref evaluations, ref solutionChanged); 131 IncludeNewPoints(tour, visitablePoints, data, ref tourLength, ref tourScore, ref evaluations, ref solutionChanged); 157 132 158 133 // Determine if any of the visitable points can take the place of an already visited point in the tour to improve the scores 159 ReplacePoints(tour, visitablePoints, 160 distances, maxLength, scores, 161 ref tourLength, ref tourScore, ref evaluations, ref solutionChanged); 134 ReplacePoints(tour, visitablePoints, data, ref tourLength, ref tourScore, ref evaluations, ref solutionChanged); 162 135 163 136 localIterations.Value++; … … 174 147 } 175 148 176 private void ShortenPath(List<int> tour, DistanceMatrix distances, int maxBlockLength, bool useMaxBlockLength, ref double tourLength, ref int evaluations) {149 private void ShortenPath(List<int> tour, IOrienteeringProblemData data, int maxBlockLength, bool useMaxBlockLength, ref double tourLength, ref int evaluations) { 177 150 bool solutionChanged; 178 151 int pathSize = tour.Count; … … 195 168 double newLength = tourLength; 196 169 // Recalculate length of whole swapped part, in case distances are not symmetric 197 for (int index = position - 1; index < position + blockLength; index++) newLength -= d istances[tour[index], tour[index + 1]];198 for (int index = position + blockLength - 1; index > position; index--) newLength += d istances[tour[index], tour[index - 1]];199 newLength += d istances[tour[position - 1], tour[position + blockLength - 1]];200 newLength += d istances[tour[position], tour[position + blockLength]];170 for (int index = position - 1; index < position + blockLength; index++) newLength -= data.RoutingData.GetDistance(tour[index], tour[index + 1]); 171 for (int index = position + blockLength - 1; index > position; index--) newLength += data.RoutingData.GetDistance(tour[index], tour[index - 1]); 172 newLength += data.RoutingData.GetDistance(tour[position - 1], tour[position + blockLength - 1]); 173 newLength += data.RoutingData.GetDistance(tour[position], tour[position + blockLength]); 201 174 202 175 if (newLength < tourLength - 0.00001) { … … 217 190 } 218 191 219 private void IncludeNewPoints(List<int> tour, List<int> visitablePoints, 220 DistanceMatrix distances, double pointVisitingCosts, double maxLength, DoubleArray scores, 192 private void IncludeNewPoints(List<int> tour, List<int> visitablePoints, IOrienteeringProblemData data, 221 193 ref double tourLength, ref double tourScore, ref int evaluations, ref bool solutionChanged) { 222 194 … … 231 203 evaluations++; 232 204 233 double detour = distances.CalculateInsertionCosts(tour, tourPosition, visitablePoints[i], pointVisitingCosts);205 double detour = OrienteeringProblem.CalculateInsertionCosts(data, tour, tourPosition, visitablePoints[i]); 234 206 235 207 // Determine if including the point does not violate any constraint 236 if (tourLength + detour <= maxLength) {208 if (tourLength + detour <= data.MaximumTravelCosts) { 237 209 // Insert the new point at this position 238 210 tour.Insert(tourPosition, visitablePoints[i]); … … 240 212 // Update the overall tour tourLength and score 241 213 tourLength += detour; 242 tourScore += scores[visitablePoints[i]];214 tourScore += data.GetScore(visitablePoints[i]); 243 215 244 216 // Re-run this optimization … … 249 221 } 250 222 251 private void ReplacePoints(List<int> tour, List<int> visitablePoints, 252 DistanceMatrix distances, double maxLength, DoubleArray scores, 223 private void ReplacePoints(List<int> tour, List<int> visitablePoints, IOrienteeringProblemData data, 253 224 ref double tourLength, ref double tourScore, ref int evaluations, ref bool solutionChanged) { 254 225 … … 263 234 evaluations++; 264 235 265 double detour = distances.CalculateReplacementCosts(tour, tourPosition, visitablePoints[i]);266 267 double oldPointScore = scores[tour[tourPosition]];268 double newPointScore = scores[visitablePoints[i]];269 270 if ((tourLength + detour <= maxLength) && (newPointScore > oldPointScore)) {236 double detour = OrienteeringProblem.CalculateReplacementCosts(data, tour, tourPosition, visitablePoints[i]); 237 238 double oldPointScore = data.GetScore(tour[tourPosition]); 239 double newPointScore = data.GetScore(visitablePoints[i]); 240 241 if ((tourLength + detour <= data.MaximumTravelCosts) && (newPointScore > oldPointScore)) { 271 242 // Replace the old point by the new one 272 243 tour[tourPosition] = visitablePoints[i];
Note: See TracChangeset
for help on using the changeset viewer.