private void GoGeneticAlgorithm(LocationGA startLocation, LocationGA[] destinations) { 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 = (LocationGA[])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 LocationGA". // This is rarely the shortest path, yet it is already a "somewhat good" path. //destinations = _GetFakeShortest(destinations); _populationWithDistances = new KeyValuePair <LocationGA[], double> [_populationCount]; // Create initial population. for (int solutionIndex = 0; solutionIndex < _populationCount; solutionIndex++) { var newPossibleDestinations = (LocationGA[])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 = LocationGA.GetTotalDistance(startLocation, newPossibleDestinations); var pair = new KeyValuePair <LocationGA[], double>(newPossibleDestinations, distance); _populationWithDistances[solutionIndex] = pair; } Array.Sort(_populationWithDistances, _sortDelegate); }