コード例 #1
0
        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);
        }
コード例 #2
0
        private Location[] _Reproduce(Location[] parent)
        {
            var result = (Location[])parent.Clone();

            if (!MustDoCrossovers)
            {
                // When we are not using cross-overs, we always apply mutations.
                RandomProvider.MutateRandomLocations(result);
                return result;
            }

            // if you want, you can ignore the next three lines of code and the next
            // if, keeping the call to RandomProvider.MutateRandomLocations(result); always
            // invoked and without crossovers. Doing that you will not promove evolution through
            // "sexual reproduction", yet the good result will probably be found.
            int otherIndex = RandomProvider.GetRandomValue(_populationWithDistances.Length/2);
            var other = _populationWithDistances[otherIndex].Key;
            RandomProvider._CrossOver(result, other, MustMutateFailedCrossovers);

            if (!MustMutateFailedCrossovers)
                if (RandomProvider.GetRandomValue(10) == 0)
                    RandomProvider.MutateRandomLocations(result);

            return result;
        }