using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using static System.Console; namespace komvo { class Program { public static List Points = new List(); public static List Infinitives = new List(); static void Main(string[] args) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); string file = "coord.txt"; using (StreamReader cr = new StreamReader(file)) { string line; while ((line = cr.ReadLine()) != null) { string[] str = line.Split(); Points.Add(new Point { X = int.Parse(str[0]), Y = int.Parse(str[1]) }); WriteLine(str[0] + " " + str[1]); } } WriteLine(); int matr = Points.Count; double[,] Matrix = new double[matr, matr]; for (int i = 0; i < Points.Count; i++) for (int j = i; j < Points.Count - 1; j++) Matrix[i, j + 1] = Matrix[j + 1, i] = Math.Sqrt(Math.Pow(Points[j + 1].X - Points[i].X, 2) + Math.Pow(Points[j + 1].Y - Points[i].Y, 2)); for (int i = 0; i < matr; i++) { for (int j = 0; j < matr; j++) Write("{0:00.00} ", Matrix[i, j]); WriteLine(); } string formP = string.Empty; for (int i = 2; i <= Points.Count; i++) formP += i.ToString(); int fct = Fact(Points.Count - 1); WriteLine("\n{0} {1}\n\n\n", formP, fct); int[] routes = new int[fct]; double[] leng = new double[fct]; int waves = fct / 6; double optim = leng[0]; int oIndex = 0; string inf = formP; Swapper(0, inf, ref routes, waves); CountLen(ref leng, Matrix, routes); SearchBest(ref optim, ref oIndex, routes, leng); Debug(routes); WriteLine("\n\n1{1}1 - оптимальный маршрут длинной {0:00.00}\nВсего маршрутов {2}\n{4} {3}", optim, routes[oIndex], routes.Length, fct, Points.Count); WriteLine(stopwatch.ElapsedMilliseconds + "ms"); stopwatch.Stop(); ReadKey(); } public static string Swap(string value, int first, int second) { char[] res = value.ToCharArray(); res[first] = value[second]; res[second] = value[first]; value = new string(res); return value; } public static string Swap(string value, int first, int second, int debug) { int d = debug; char[] res = value.ToCharArray(); res[first] = value[second]; res[second] = value[first]; value = new string(res); return value; } public static void CountLen (ref double[] result, double[,] mtr, int[] rts) { for (int i = 0; i < rts.Length; i++) { double res = 0; char[] ch = rts[i].ToString().ToCharArray(); for (int j = 0; j < ch.Length; j++) { int db = int.Parse(ch[j].ToString()) - 1; //debug string db1 = rts[i].ToString(); //debug if (j == 0) res += mtr[0, int.Parse(ch[j].ToString()) - 1]; else if (j == ch.Length - 1) { res += mtr[int.Parse(ch[j - 1].ToString()) - 1, int.Parse(ch[j].ToString()) - 1]; res += mtr[0, int.Parse(ch[j].ToString()) - 1]; } else { res += mtr[int.Parse(ch[j - 1].ToString()) - 1, int.Parse(ch[j].ToString()) - 1]; } } result[i] = res; } } public static void Swapper(int counter, string inf, ref int[] routes, int waves) { string formP = inf; if (counter >= waves) WriteLine("\nEnd"); else { if (counter == 0) { Infinitives.Add(inf); formP = Infinitives[0]; } else if (counter % 4 == 0) { Infinitives.Add(Swap(inf, counter / 4 - 1, inf.Length - 1, counter)); formP = Infinitives[counter / 4]; } else if (waves > 1) { formP = Swap(Infinitives[counter / 4], counter % 4 - 1, 3); } BlockOfSix(formP, ref routes, counter); Swapper(counter + 1, inf, ref routes, waves); } } public static void BlockOfSix(string formP, ref int[] routes, int start) { for (int j = 0; j < 6; j++) { if (j == 0) { routes[j + start * 6] = int.Parse(formP); WriteLine(routes[j + start * 6]); } else if (j % 2 == 0) { routes[j + start * 6] = int.Parse(formP = Swap(formP, 0, j / 2)); WriteLine(routes[j + start * 6]); } else { routes[j + start * 6] = int.Parse(Swap(formP, 1, 2)); WriteLine(routes[j + start * 6]); } } } public static void SearchBest(ref double optim, ref int oIndex, int[] routes, double[] leng) { optim = leng[0]; oIndex = 0; for (int i = 0; i < leng.Length; i++) { WriteLine("{0:N2} - {1}", leng[i], routes[i]); if (optim > leng[i]) { optim = leng[i]; oIndex = i; } } } public static void Debug (int[] routes) { for (int i = 0; i < routes.Length; i++) { for (int j = i + 1; j < routes.Length - 1; j++) if (routes[i].Equals(routes[j])) WriteLine("{0} {2}:: {1} {3}!!!!", routes[i], routes[j], i, j); } } public partial struct Point { public int X { get; set; } public int Y { get; set; } } static int Fact(int a) => a <= 1 ? 1 : a * Fact(a - 1); } }