GetTotalDistance() public static method

public static GetTotalDistance ( Location startLocation, Location locations ) : double
startLocation Location
locations Location
return double
        public TravellingSalesmanAlgorithm(Location startLocation, Location[] destinations, int populationCount)
        {
            if (startLocation == null)
            {
                throw new ArgumentNullException("startLocation");
            }

            if (destinations == null)
            {
                throw new ArgumentNullException("destinations");
            }

            if (populationCount < 2)
            {
                throw new ArgumentOutOfRangeException("populationCount");
            }

            if (populationCount % 2 != 0)
            {
                throw new ArgumentException("The populationCount parameter must be an even value.", "populationCount");
            }

            _startLocation = startLocation;
            destinations   = (Location[])destinations.Clone();

            foreach (var destination in destinations)
            {
                if (destination == null)
                {
                    throw new ArgumentException("The destinations array can't contain null values.", "destinations");
                }
            }

            // This commented method uses a search of the kind "look for the nearest non visited location".
            // This is rarely the shortest path, yet it is already a "somewhat good" path.
            destinations = _GetFakeShortest(destinations);

            _populationWithDistances = new KeyValuePair <Location[], double> [populationCount];

            // Create initial population.
            for (int solutionIndex = 0; solutionIndex < populationCount; solutionIndex++)
            {
                var newPossibleDestinations = (Location[])destinations.Clone();

                // Try commenting the next 2 lines of code while keeping the _GetFakeShortest active.
                // If you avoid the algorithm from running and press reset, you will see that it always
                // start with a path that seems "good" but is not the best.
                //for(int randomIndex=0; randomIndex<newPossibleDestinations.Length; randomIndex++)
                //RandomProvider.FullyRandomizeLocations(newPossibleDestinations);

                var distance = Location.GetTotalDistance(startLocation, newPossibleDestinations);
                var pair     = new KeyValuePair <Location[], double>(newPossibleDestinations, distance);

                _populationWithDistances[solutionIndex] = pair;
            }

            Array.Sort(_populationWithDistances, _sortDelegate);
        }
Ejemplo n.º 2
0
        private void generateLines()
        {
            Location[] bestSolutionSoFar = _bestSolutionSoFar;
            Location.GetTotalDistance(_startLocation, bestSolutionSoFar);

            _tspSegments.Clear();

            if (bestSolutionSoFar.Length > 0)
            {
                var actualLocation = _startLocation;
                int index          = 0;
                int dropCount      = 0;

                foreach (var destination in _AddEndLocation(bestSolutionSoFar))
                {
                    var line = new TSPSegment()
                    {
                        start = new Vector2(actualLocation.X, actualLocation.Y), end = new Vector2(destination.X, destination.Y)
                    };
                    if (line.LineLength() > kJumpThreshold)
                    {
                        line.type = TSPSegment.LineType.Jump;
                    }
                    else
                    {
                        line.type = TSPSegment.LineType.Draw;
                    }

                    _tspSegments.Add(line);

                    actualLocation = destination;
                    index++;
                }

                Debug.WriteLine("Total long jumps: " + dropCount);
                Debug.WriteLine("Segments added: " + _tspSegments.Count);
            }
        }
        public void Reproduce()
        {
            var bestSoFar = _populationWithDistances[0];

            int halfCount = _populationWithDistances.Length / 2;

            for (int i = 0; i < halfCount; i++)
            {
                var parent = _populationWithDistances[i].Key;
                var child1 = _Reproduce(parent);
                var child2 = _Reproduce(parent);

                var pair1 = new KeyValuePair <Location[], double>(child1, Location.GetTotalDistance(_startLocation, child1));
                var pair2 = new KeyValuePair <Location[], double>(child2, Location.GetTotalDistance(_startLocation, child2));
                _populationWithDistances[i * 2]     = pair1;
                _populationWithDistances[i * 2 + 1] = pair2;
            }

            // We keep the best alive from one generation to the other.
            _populationWithDistances[_populationWithDistances.Length - 1] = bestSoFar;

            Array.Sort(_populationWithDistances, _sortDelegate);
        }
        public void MutateDuplicates()
        {
            bool needToSortAgain = false;
            int  countDuplicates = 0;

            var previous = _populationWithDistances[0];

            for (int i = 1; i < _populationWithDistances.Length; i++)
            {
                var current = _populationWithDistances[i];
                if (!previous.Key.SequenceEqual(current.Key))
                {
                    previous = current;
                    continue;
                }

                countDuplicates++;

                needToSortAgain = true;
                RandomProvider.MutateRandomLocations(current.Key);
                _populationWithDistances[i] = new KeyValuePair <Location[], double>(current.Key, Location.GetTotalDistance(_startLocation, current.Key));
            }

            if (needToSortAgain)
            {
                Array.Sort(_populationWithDistances, _sortDelegate);
            }
        }