You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
4.2 KiB
138 lines
4.2 KiB
using System; |
|
using System.Diagnostics; |
|
using Combinatorics.Collections; |
|
using System.Collections.Generic; |
|
using static System.Console; |
|
using System.Threading.Tasks; |
|
|
|
namespace komvo |
|
{ |
|
class Program |
|
{ |
|
static void Main(string[] args) |
|
{ |
|
Beginig: |
|
|
|
List<Point> Points = new List<Point>(); |
|
Random random = new Random(); |
|
int pCount = 0; |
|
Write("Введите количество точек: "); |
|
|
|
Retry: |
|
try |
|
{ |
|
pCount = Convert.ToInt32(ReadLine()); |
|
} |
|
catch |
|
{ |
|
Write("Введите натуральное число: "); |
|
goto Retry; |
|
} |
|
Stopwatch stopwatch = new Stopwatch(); |
|
stopwatch.Start(); |
|
|
|
for(int i = 0; i < pCount; i++) |
|
{ |
|
int x = random.Next(80); |
|
int y = random.Next(70); |
|
Points.Add(new Point { X = x, Y = y }); |
|
WriteLine("Точка {0} [{1};{2}]", i + 1, x, y); |
|
} |
|
WriteLine("\n"); |
|
|
|
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(); |
|
} |
|
int[] toSwap = new int[Points.Count - 1]; |
|
for (int i = 0; i <= toSwap.Length - 1; i++) toSwap[i] = i + 2; |
|
|
|
bool first = true; |
|
double opLength = 0, prevResult = 0; |
|
string opRoute = string.Empty; |
|
|
|
Permutations<int> perm = new Permutations<int>(toSwap); |
|
foreach(IList<int> p in perm) |
|
{ |
|
int[] route = new int[Points.Count - 1]; |
|
for (int i = 0; i < toSwap.Length; i++) route[i] = p[i]; |
|
prevResult = CountLength(Matrix, route); |
|
//WriteLine(opLength); |
|
|
|
if (first) |
|
{ |
|
opLength = prevResult; |
|
first = false; |
|
} |
|
|
|
if(opLength > prevResult) |
|
{ |
|
opLength = prevResult; |
|
opRoute = string.Empty; |
|
foreach (int i in route) opRoute += i + ";"; |
|
} |
|
} |
|
|
|
|
|
//int[] toSwapNew = new int[Points.Count - 1]; |
|
//for (int i = 0; i <= toSwap.Length - 1; i++) toSwapNew[i] = i + 2; |
|
//foreach (int i in toSwapNew) Write(i + " "); |
|
|
|
|
|
|
|
|
|
|
|
|
|
WriteLine("\n\n1;{1}1 - оптимальный маршрут длинной {0:00.00}\nИз {2} маршрутов при {3} точках\nПосчитано за {4} мс\n\n", |
|
opLength, opRoute, Fact(Points.Count-1), Points.Count, stopwatch.ElapsedMilliseconds); |
|
stopwatch.Stop(); |
|
|
|
Write("Ещё раз? (y/n)"); |
|
char answer = ReadKey().KeyChar; |
|
if (answer == 'y') |
|
{ |
|
Points.Clear(); |
|
WriteLine("\n"); |
|
goto Beginig; |
|
} |
|
} |
|
|
|
public static double CountLength(double[,] mtr, int[] route) |
|
{ |
|
double result = 0; |
|
|
|
for (int j = 0; j < route.Length - 1; j++) |
|
{ |
|
if (j == 0) result += mtr[0, route[j] - 1]; |
|
else if (j == route.Length - 1) |
|
{ |
|
result += mtr[route[j - 1] - 2, route[j] - 2]; |
|
result += mtr[0, route[j] - 2]; |
|
} |
|
else |
|
{ |
|
result += mtr[route[j - 1] - 2, route[j] - 2]; |
|
} |
|
} |
|
return result; |
|
} |
|
|
|
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); |
|
} |
|
} |