123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- using System.Diagnostics;
- using AntColony.Algorithm;
- namespace AntColony;
- class Program
- {
- /// <summary></summary>
- /// <param name="file">Путь до файла с ребрами</param>
- /// <param name="hasHeader">Файл содержит заголовок</param>
- /// <param name="iterations">Количество итераций</param>
- /// <param name="ants">Количество муравьев</param>
- /// <param name="alpha">Значение α (определяет вес феромонов)</param>
- /// <param name="beta">Значение β (определяет вес расстояния)</param>
- /// <param name="evaporationRate">Скорость испарения феромонов</param>
- /// <param name="q">Значение Q</param>
- 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: ants,
- alpha: alpha,
- beta: beta,
- evaporationRate: evaporationRate,
- Q: q
- );
- sw.Restart();
- var (bestTour, bestDistance) = aco.Solve(iterations);
- Console.WriteLine($"Задача решена за {sw.Elapsed} ({sw.ElapsedMilliseconds} мс).");
- if (bestTour.Count == 0)
- {
- Console.WriteLine("Гамильтонов цикл не найден.");
- return;
- }
- Console.WriteLine($"Лучший путь: {string.Join(" -> ", bestTour)}.");
- Console.WriteLine($"Итоговое расстояние: {bestDistance}.");
- }
- private static double[][] ParseEdgeFile(string filePath, bool skipHeader)
- {
- List<string> lines = [.. File.ReadAllLines(filePath)];
- if (skipHeader) lines.RemoveAt(0);
- HashSet<int> 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;
- }
- }
|