public void EqualityTests() { var sp1 = new SalesmanPath(new[] {0, 1, 2, 0}, 56); var sp2 = new SalesmanPath(new[] {0, 1, 2, 0}, 56); Assert.AreEqual(true, sp1.Equals(sp2)); //Assert.Equals(false, new SalesmanPath(new[] { 0, 2, 1, 0 }, 56) == new SalesmanPath(new[] { 0, 1, 2, 0 }, 56)); }
/// <summary> /// Решение задачи коммивояжера генетическим алгоритмом /// </summary> /// <param name="maxGeneration">Число итераций до вырождения</param> /// <returns>Оптимальный путь</returns> public SalesmanPath Solve(int maxGeneration) { var bestResult = CurrentGeneration[0]; for (int counter = 0; counter < maxGeneration; counter++) { if (CurrentGeneration.Count == 0) throw new Exception("В текущем поколении нет элементов"); // TODO: селекция (выбор родителей) // скрещивание и мутация // шанс мутации 15% var rand = new Random(DateTime.Now.Millisecond); var newChilds = new List<SalesmanPath>(); CurrentGeneration = CurrentGeneration.OrderBy(g => rand.Next()).ToList(); for (int i = 0; i < CurrentGeneration.Count - 1; i += 2) { //Debug.WriteLine("P1: " + CurrentGeneration[i]); //Debug.WriteLine("P2: " + CurrentGeneration[i + 1]); var p1 = CurrentGeneration[i].Cities; var p2 = CurrentGeneration[i + 1].Cities; p1 = Mutation(p1); p2 = Mutation(p2); var child = _CrossoverHelper.Crossover(p1, p2); SalesmanPath childPath = new SalesmanPath(child, Cities.CalculatePathCost(child)); //if (childPath.Cost > CurrentGeneration[i].Cost && childPath.Cost > CurrentGeneration[i + 1].Cost) // Console.WriteLine("Child better that both parents: "+childPath); //Debug.WriteLine("CH: " + childPath); if (Cities.PathValid(childPath.Cities) && !CurrentGeneration.Contains(childPath)) newChilds.Add(childPath); } //Console.WriteLine("NewChilds: "+newChilds.Count); //Console.WriteLine("GenerationSize: " + CurrentGeneration.Count); CurrentGeneration = Rejection(CurrentGeneration, newChilds.Count); CurrentGeneration.AddRange(newChilds); var bestInCurrentGeneration = CurrentGeneration.OrderBy(path => path.Cost).First(); if (bestResult.Cost > bestInCurrentGeneration.Cost) { bestResult = bestInCurrentGeneration; Console.WriteLine("Generation: " + (counter).ToString("00") + " " + bestResult); } Console.Title = "Осталось: " + (maxGeneration-counter).ToString(); } return bestResult; }