Esempio n. 1
0
        public override double CalculateSolutionSimilarity(IScope leftSolution, IScope rightSolution)
        {
            var sol1 = leftSolution.Variables[SolutionVariableName].Value as IVRPEncoding;
            var sol2 = rightSolution.Variables[SolutionVariableName].Value as IVRPEncoding;

            var potvinSol1 = sol1 is PotvinEncoding ? sol1 as PotvinEncoding : PotvinEncoding.ConvertFrom(sol1, ProblemInstance);
            var potvinSol2 = sol2 is PotvinEncoding ? sol2 as PotvinEncoding : PotvinEncoding.ConvertFrom(sol2, ProblemInstance);

            return(CalculateSimilarity(potvinSol1, potvinSol2));
        }
Esempio n. 2
0
        public static double CalculateSimilarity(PotvinEncoding left, PotvinEncoding right)
        {
            if (left == null || right == null)
            {
                throw new ArgumentException("Cannot calculate similarity because one of the provided solutions or both are null.");
            }
            if (left == right)
            {
                return(1.0);
            }

            // extract edges from first solution
            var edges1 = new List <Tuple <int, int> >();

            foreach (Tour tour in left.Tours)
            {
                edges1.Add(new Tuple <int, int>(0, tour.Stops[0]));
                for (int i = 0; i < tour.Stops.Count - 1; i++)
                {
                    edges1.Add(new Tuple <int, int>(tour.Stops[i], tour.Stops[i + 1]));
                }
                edges1.Add(new Tuple <int, int>(tour.Stops[tour.Stops.Count - 1], 0));
            }

            // extract edges from second solution
            var edges2 = new List <Tuple <int, int> >();

            foreach (Tour tour in right.Tours)
            {
                edges2.Add(new Tuple <int, int>(0, tour.Stops[0]));
                for (int i = 0; i < tour.Stops.Count - 1; i++)
                {
                    edges2.Add(new Tuple <int, int>(tour.Stops[i], tour.Stops[i + 1]));
                }
                edges2.Add(new Tuple <int, int>(tour.Stops[tour.Stops.Count - 1], 0));
            }

            if (edges1.Count + edges2.Count == 0)
            {
                throw new ArgumentException("Cannot calculate diversity because no tours exist.");
            }

            int identicalEdges = 0;

            foreach (var edge in edges1)
            {
                if (edges2.Any(x => x.Equals(edge)))
                {
                    identicalEdges++;
                }
            }

            return(identicalEdges * 2.0 / (edges1.Count + edges2.Count));
        }
Esempio n. 3
0
        private static PotvinEncoding MatchTours(PotvinEncoding initiator, PotvinEncoding guide, IVRPProblemInstance problemInstance)
        {
            var result = new PotvinEncoding(problemInstance);

            var used = new List <bool>();

            for (int i = 0; i < initiator.Tours.Count; i++)
            {
                used.Add(false);
            }

            for (int i = 0; i < guide.Tours.Count; i++)
            {
                int bestMatch = -1;
                int bestTour  = -1;

                for (int j = 0; j < initiator.Tours.Count; j++)
                {
                    if (!used[j])
                    {
                        int match = MatchingCities(guide.Tours[i], initiator.Tours[j]);
                        if (match > bestMatch)
                        {
                            bestMatch = match;
                            bestTour  = j;
                        }
                    }
                }

                if (bestTour != -1)
                {
                    result.Tours.Add(initiator.Tours[bestTour]);
                    used[bestTour] = true;
                }
            }

            for (int i = 0; i < initiator.Tours.Count; i++)
            {
                if (!used[i])
                {
                    result.Tours.Add(initiator.Tours[i]);
                }
            }

            return(result);
        }
Esempio n. 4
0
        protected override ItemArray <IItem> Relink(ItemArray <IItem> parents, PercentValue n)
        {
            if (parents.Length != 2)
            {
                throw new ArgumentException("The number of parents is not equal to 2.");
            }

            if (!(parents[0] is PotvinEncoding))
            {
                parents[0] = PotvinEncoding.ConvertFrom(parents[0] as IVRPEncoding, ProblemInstanceParameter.ActualValue);
            }
            if (!(parents[1] is PotvinEncoding))
            {
                parents[1] = PotvinEncoding.ConvertFrom(parents[1] as IVRPEncoding, ProblemInstanceParameter.ActualValue);
            }

            return(Apply(parents[0] as PotvinEncoding, parents[1] as PotvinEncoding, n,
                         SampleSizeParameter.Value.Value, IterationsParameter.Value.Value, RandomParameter.ActualValue, ProblemInstanceParameter.ActualValue));
        }
Esempio n. 5
0
        public static void RelocateMove(PotvinEncoding individual, IRandom random)
        {
            int  cities       = individual.Cities;
            int  city         = 1 + random.Next(cities);
            Tour originalTour = individual.Tours.Find(t => t.Stops.Contains(city));

            //consider creating new route
            individual.Tours.Add(new Tour());

            int position = 1 + random.Next(cities + individual.Tours.Count - 1);

            if (position >= city)
            {
                position++;
            }

            int originalPosition = originalTour.Stops.IndexOf(city);

            originalTour.Stops.RemoveAt(originalPosition);

            Tour insertionTour;
            int  insertionPosition;

            if (position <= cities)
            {
                insertionTour     = individual.Tours.Find(t => t.Stops.Contains(position));
                insertionPosition = insertionTour.Stops.IndexOf(position) + 1;
            }
            else
            {
                insertionTour     = individual.Tours[position - cities - 1];
                insertionPosition = 0;
            }

            insertionTour.Stops.Insert(insertionPosition, city);

            individual.Tours.RemoveAll(t => t.Stops.Count == 0);
        }
Esempio n. 6
0
        protected virtual IVRPEncoding GetBestKnowTour(IVRPData data, IVRPProblemInstance problemInstance)
        {
            if (data.BestKnownTour != null)
            {
                PotvinEncoding solution = new PotvinEncoding(problemInstance);

                for (int i = 0; i < data.BestKnownTour.GetLength(0); i++)
                {
                    Tour tour = new Tour();
                    solution.Tours.Add(tour);

                    foreach (int stop in data.BestKnownTour[i])
                    {
                        tour.Stops.Add(stop + 1);
                    }
                }

                if (data.BestKnownTourVehicleAssignment != null)
                {
                    if (data.BestKnownTourVehicleAssignment.Length != solution.VehicleAssignment.Length)
                    {
                        throw new InvalidDataException("Number of vehicles of the best known tour does not match the number vehicles of the instance.");
                    }
                    for (int i = 0; i < data.BestKnownTourVehicleAssignment.Length; i++)
                    {
                        solution.VehicleAssignment[i] = data.BestKnownTourVehicleAssignment[i];
                    }
                }

                return(solution);
            }
            else
            {
                return(null);
            }
        }
Esempio n. 7
0
        protected override int Improve(PotvinEncoding solution)
        {
            int evaluatedSolutions = 0;

            var rand       = RandomParameter.ActualValue;
            var instance   = ProblemInstance;
            int sampleSize = SampleSizeParameter.Value.Value;
            int attempts   = ImprovementAttemptsParameter.Value.Value;
            int customers  = instance.Cities.Value;

            // store city-to-tour assignment and position of the city within the tour
            var tours    = new Dictionary <int, Tour>();
            var position = new Dictionary <int, int>();

            foreach (Tour tour in solution.Tours)
            {
                for (int stop = 0; stop < tour.Stops.Count; stop++)
                {
                    int city = tour.Stops[stop];
                    tours[city]    = tour;
                    position[city] = stop;
                }
            }

            for (int attempt = 0; attempt < attempts; attempt++)
            {
                for (int sample = 0; sample < sampleSize; sample++)
                {
                    int chosenCust = 1 + rand.Next(customers);
                    var custTour   = tours[chosenCust];

                    double beforeQuality = instance.EvaluateTour(custTour, solution).Quality;
                    evaluatedSolutions++;

                    custTour.Stops.RemoveAt(position[chosenCust]);
                    int place = solution.FindBestInsertionPlace(custTour, chosenCust);
                    evaluatedSolutions += custTour.Stops.Count;
                    custTour.Stops.Insert(place, chosenCust);

                    if (place != position[chosenCust])
                    {
                        double afterQuality = instance.EvaluateTour(custTour, solution).Quality;
                        if (afterQuality > beforeQuality)
                        {
                            // revert move
                            custTour.Stops.RemoveAt(place);
                            custTour.Stops.Insert(position[chosenCust], chosenCust);
                        }
                        else
                        {
                            // accept move and update positions of the cities within the tour
                            for (int stop = 0; stop < custTour.Stops.Count; stop++)
                            {
                                int city = custTour.Stops[stop];
                                position[city] = stop;
                            }
                            break;
                        }
                    }
                }
            }

            return(evaluatedSolutions);
        }
        public override IOperation InstrumentedApply()
        {
            var solution       = SolutionParameter.ActualValue as IVRPEncoding;
            var potvinSolution = solution is PotvinEncoding ? solution as PotvinEncoding : PotvinEncoding.ConvertFrom(solution, ProblemInstance);

            if (solution == null)
            {
                throw new ArgumentException("Cannot improve solution because it has the wrong type.");
            }

            int evaluatedSolutions = Improve(potvinSolution);

            SolutionParameter.ActualValue       = solution;
            LocalEvaluatedSolutions.ActualValue = new IntValue(evaluatedSolutions);

            return(base.InstrumentedApply());
        }
 protected abstract int Improve(PotvinEncoding solution);
Esempio n. 10
0
        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)));
        }
Esempio n. 11
0
        public static void GuidedRelocateMove(PotvinEncoding initiator, PotvinEncoding guide, IRandom random)
        {
            List <int> cities = new List <int>();

            foreach (Tour tour in initiator.Tours)
            {
                foreach (int city in tour.Stops)
                {
                    Tour guideTour = guide.Tours.First(t => t.Stops.Contains(city));
                    if (guide.Tours.IndexOf(guideTour) != initiator.Tours.IndexOf(tour))
                    {
                        cities.Add(city);
                    }
                }
            }

            if (cities.Count == 0)
            {
                RelocateMove(initiator, random);
            }
            else
            {
                int  city = cities[random.Next(cities.Count)];
                Tour tour = initiator.Tours.First(t => t.Stops.Contains(city));
                tour.Stops.Remove(city);

                Tour guideTour      = guide.Tours.First(t => t.Stops.Contains(city));
                int  guideTourIndex = guide.Tours.IndexOf(guideTour);

                if (guideTourIndex < initiator.Tours.Count)
                {
                    Tour tour2 = initiator.Tours[guideTourIndex];

                    int guideIndex = guideTour.Stops.IndexOf(city);
                    if (guideIndex == 0)
                    {
                        tour2.Stops.Insert(0, city);
                    }
                    else
                    {
                        int predecessor = guideTour.Stops[guideIndex - 1];
                        int initIndex   = tour2.Stops.IndexOf(predecessor);
                        if (initIndex != -1)
                        {
                            tour2.Stops.Insert(initIndex + 1, city);
                        }
                        else
                        {
                            if (guideIndex == guideTour.Stops.Count - 1)
                            {
                                tour2.Stops.Insert(tour2.Stops.Count, city);
                            }
                            else
                            {
                                int sucessor = guideTour.Stops[guideIndex + 1];
                                initIndex = tour2.Stops.IndexOf(sucessor);
                                if (initIndex != -1)
                                {
                                    tour2.Stops.Insert(initIndex, city);
                                }
                                else
                                {
                                    tour2.Stops.Insert(random.Next(tour2.Stops.Count + 1), city);
                                }
                            }
                        }
                    }
                }
                else
                {
                    Tour tour2 = new Tour();
                    tour2.Stops.Add(city);
                    initiator.Tours.Add(tour2);
                }

                if (tour.Stops.Count == 0)
                {
                    initiator.Tours.Remove(tour);
                }
            }
        }
Esempio n. 12
0
 public static PotvinEncoding SequenceBasedXOver(PotvinEncoding initiator, PotvinEncoding guide, IRandom random, IVRPProblemInstance problemInstance)
 {
     return(PotvinSequenceBasedCrossover.Apply(random, initiator, guide, problemInstance, false));
 }