/* * Return tour[] as the result * Get information about result from Events */ public int[] Run() { LinkedListNode <int> nextCityIndex = null; while (notVisited.Count != 0)// while there are cities to visit { double minDistance = double.MaxValue; // foreach unvisited city for (var cityIndex = notVisited.First; cityIndex != null; cityIndex = cityIndex.Next) { City current = Cities[tour[CurrentTourCityIndex]]; City next = Cities[cityIndex.Value]; // find the shortest way double currentDistance = CityModel.distance(current, next); lookAtCity?.Invoke(this, new HillClimbingArgs(tour[CurrentTourCityIndex], cityIndex.Value, currentDistance)); if (currentDistance < minDistance) { minDistance = currentDistance; nextCityIndex = cityIndex; } } // the shortest way has been found ChooseACity?.Invoke(this, new HillClimbingArgs(tour[CurrentTourCityIndex], nextCityIndex.Value, minDistance)); tour[++CurrentTourCityIndex] = nextCityIndex.Value; notVisited.Remove(nextCityIndex); } return(tour); }
/* * Does not return the tour[], should use propery for that * Get information about process from result, works as Enumerator */ public IEnumerable <HillClimbingArgs> RunIter() { compleated = false; LinkedListNode <int> nextCityIndex = null; while (notVisited.Count != 0)// while there are cities to visit { double minDistance = double.MaxValue; // foreach unvisited city for (var cityIndex = notVisited.First; cityIndex != null; cityIndex = cityIndex.Next) { City current = Cities[tour[CurrentTourCityIndex]]; City next = Cities[cityIndex.Value]; // find the shortest way double currentDistance = CityModel.distance(current, next); yield return(new HillClimbingArgs(tour[CurrentTourCityIndex], cityIndex.Value, currentDistance)); if (currentDistance < minDistance) { minDistance = currentDistance; nextCityIndex = cityIndex; } } // the shortest way has been found yield return(new HillClimbingArgs(tour[CurrentTourCityIndex], nextCityIndex.Value, minDistance, true)); tour[++CurrentTourCityIndex] = nextCityIndex.Value; notVisited.Remove(nextCityIndex); } compleated = true; }
// BTN / CLICK / DOUBLE CLICK / ... private void ChooseCityMap_MouseDown(object sender, MouseEventArgs e) { // rewrite indexes lookAtPrevCityIndex = lookAtCurrentCityIndex; lookAtCurrentCityIndex = StartCityIndex; // find the closest city to the click CityModel.City pointer = new CityModel.City(e.X, e.Y); double minDistance = double.MaxValue; for (int i = 0; i < Cities.Length; ++i) { double cutDistance = CityModel.distance(Cities[i], pointer); if (minDistance > cutDistance) { minDistance = cutDistance; lookAtCurrentCityIndex = i; } } // redraw cities into their color DrawCity(Cities[lookAtPrevCityIndex], CityRedPen); DrawCity(Cities[lookAtCurrentCityIndex], CityBluePen); // set city index in UpDown Control StartCityIndex = lookAtCurrentCityIndex; }
// Calculate tour cost as a sum of distances between cities public static double Cost(int[] tour, CityModel.City[] cities) { double Length = 0; for (int i = 0; i < tour.Length - 1; ++i) { int CurrentCity = tour[i]; int NextCity = tour[i + 1]; Length += CityModel.distance(cities[CurrentCity], cities[NextCity]); } // dont forget to calculate path from last city to first // we need to return to our home Length += CityModel.distance(cities[tour.First()], cities[tour.Last()]); return(Length); }