using System.Diagnostics; using AntColony.Algorithm; namespace AntColony; class Program { /// /// Путь до файла с ребрами /// Файл содержит заголовок /// Количество итераций /// Количество муравьев /// Значение α (определяет вес феромонов) /// Значение β (определяет вес расстояния) /// Скорость испарения феромонов /// Значение Q public static void Main(FileInfo file, bool hasHeader = false, int iterations = 100, int ants = 20, double alpha = 1, double beta = 2, double evaporationRate = 0.1, double q = 100) { Console.Write("Чтение файла..."); var sw = new Stopwatch(); sw.Start(); double[][] distances = ParseEdgeFile(file.FullName, hasHeader); Console.WriteLine($"\rСчитано {distances.Length} вершин за {sw.Elapsed} ({sw.ElapsedMilliseconds} мс).\n"); var aco = new AntColonyOptimizer( distances: distances, numberOfAnts: 20, alpha: 1, beta: 2, evaporationRate: 0.1, Q: 100 ); sw.Restart(); var (bestTour, bestDistance) = aco.Solve(iterations); Console.WriteLine($"Задача решена за {sw.Elapsed} ({sw.ElapsedMilliseconds} мс)."); Console.WriteLine($"Лучший путь: {string.Join(" -> ", bestTour)}."); Console.WriteLine($"Итоговое расстояние: {bestDistance}."); } private static double[][] ParseEdgeFile(string filePath, bool skipHeader) { List lines = [.. File.ReadAllLines(filePath)]; if (skipHeader) lines.RemoveAt(0); HashSet vertices = []; int maxVertex = 0; foreach (string line in lines) { string[] parts = line.Split(); if (parts.Length != 3) continue; if (int.TryParse(parts[0], out int v1)) vertices.Add(v1); if (int.TryParse(parts[1], out int v2)) vertices.Add(v2); maxVertex = int.Max(maxVertex, v1); maxVertex = int.Max(maxVertex, v2); } double[][] adjacencyMatrix = new double[maxVertex + 1][]; for (int i = 0; i < maxVertex + 1; i++) { adjacencyMatrix[i] = new double[maxVertex + 1]; for (int j = 0; j < maxVertex + 1; j++) { adjacencyMatrix[i][j] = 0.0; } } foreach (string line in lines) { string[] parts = line.Split(); if (parts.Length != 3) continue; if (int.TryParse(parts[0], out int v1) && int.TryParse(parts[1], out int v2) && double.TryParse(parts[2], out double distance)) { adjacencyMatrix[v1][v2] = distance; adjacencyMatrix[v2][v1] = distance; } } return adjacencyMatrix; } }