private VRPSimilarityCalculator(VRPSimilarityCalculator original, Cloner cloner) : base(original, cloner) { this.ProblemInstance = cloner.Clone(original.ProblemInstance); }
public static ItemArray <IItem> Apply(PotvinEncoding initiator, PotvinEncoding guide, PercentValue n, int sampleSize, int iterations, IRandom rand, IVRPProblemInstance problemInstance) { if (initiator == null || guide == null) { throw new ArgumentException("Cannot relink path because one of the provided solutions or both are null."); } double sigma = 1.5; double minPenalty = 0.001; double maxPenalty = 1000000000; var originalOverloadPenalty = new DoubleValue(); if (problemInstance is IHomogenousCapacitatedProblemInstance) { originalOverloadPenalty.Value = (problemInstance as IHomogenousCapacitatedProblemInstance).OverloadPenalty.Value; } var originalTardinessPenalty = new DoubleValue(); if (problemInstance is ITimeWindowedProblemInstance) { originalTardinessPenalty.Value = (problemInstance as ITimeWindowedProblemInstance).TardinessPenalty.Value; } PotvinEncoding current = MatchTours(initiator, guide, problemInstance); double currentSimilarity = VRPSimilarityCalculator.CalculateSimilarity(current, guide); IList <PotvinEncoding> solutions = new List <PotvinEncoding>(); int i = 0; while (i < iterations && !currentSimilarity.IsAlmost(1.0)) { var currentEval = problemInstance.Evaluate(current); currentSimilarity = VRPSimilarityCalculator.CalculateSimilarity(current, guide); if (currentSimilarity < 1.0) { for (int sample = 0; sample < sampleSize; sample++) { var next = current.Clone() as PotvinEncoding; int neighborhood = rand.Next(3); switch (neighborhood) { case 0: next = RouteBasedXOver(next, guide, rand, problemInstance); break; case 1: next = SequenceBasedXOver(next, guide, rand, problemInstance); break; case 2: GuidedRelocateMove(next, guide, rand); break; } next = MatchTours(next, guide, problemInstance); var nextEval = problemInstance.Evaluate(next); if ((nextEval.Quality < currentEval.Quality)) { current = next; solutions.Add(current); break; } } if (problemInstance is IHomogenousCapacitatedProblemInstance) { if (((CVRPEvaluation)currentEval).Overload > 0) { (problemInstance as IHomogenousCapacitatedProblemInstance).OverloadPenalty.Value = Math.Min(maxPenalty, (problemInstance as IHomogenousCapacitatedProblemInstance).OverloadPenalty.Value * sigma); } else { (problemInstance as IHomogenousCapacitatedProblemInstance).OverloadPenalty.Value = Math.Max(minPenalty, (problemInstance as IHomogenousCapacitatedProblemInstance).OverloadPenalty.Value * sigma); } } if (problemInstance is ITimeWindowedProblemInstance) { if (((CVRPTWEvaluation)currentEval).Tardiness > 0) { (problemInstance as ITimeWindowedProblemInstance).TardinessPenalty.Value = Math.Min(maxPenalty, (problemInstance as ITimeWindowedProblemInstance).TardinessPenalty.Value * sigma); } else { (problemInstance as ITimeWindowedProblemInstance).TardinessPenalty.Value = Math.Max(minPenalty, (problemInstance as ITimeWindowedProblemInstance).TardinessPenalty.Value / sigma); } } i++; } } if (problemInstance is IHomogenousCapacitatedProblemInstance) { (problemInstance as IHomogenousCapacitatedProblemInstance).OverloadPenalty.Value = originalOverloadPenalty.Value; } if (problemInstance is ITimeWindowedProblemInstance) { (problemInstance as ITimeWindowedProblemInstance).TardinessPenalty.Value = originalTardinessPenalty.Value; } return(new ItemArray <IItem>(ChooseSelection(solutions, n))); }