static void MakePermutations(Point[] checkpoints, int[] permutation, int position, double currentPathLength, List <int[]> result) { if (position == permutation.Length) { if (currentPathLength < minPathLength) { minPathLength = currentPathLength; } result.Add(permutation.ToArray()); return; } for (int i = 1; i < permutation.Length; i++) { var index = Array.IndexOf(permutation, i, 1, position - 1); if (index == -1) { permutation[position] = i; double addedPath = PointExtensions.DistanceTo(checkpoints[permutation[position]], checkpoints[permutation[position - 1]]); if (currentPathLength > minPathLength) { return; } MakePermutations(checkpoints, permutation, position + 1, currentPathLength + addedPath, result); } } }
public static int[] FindBestCheckpointsOrder(Point[] checkpoints) { if (tempListBestOrder.Count == checkpoints.Length) { MakeTrivialAction(checkpoints); CloseMethod(); return(outListBestOrder.ToArray());//проблема здесь } if (PointExtensions.GetPathLength(checkpoints, tempListBestOrder.ToArray()) <= minPathLength) { for (int i = 1; i < checkpoints.Length; i++) { var index = Array.IndexOf(tempListBestOrder.ToArray(), i, 0, position); if (index == -1) { tempListBestOrder.Add(i); position += 1; FindBestCheckpointsOrder(checkpoints); } } } if (position == 1) { minPathLength = double.MaxValue; return(outListBestOrder.ToArray()); } CloseMethod(); return(new int[0]); }
public static int[] MakePermutations(int[] order, int position, Point[] checkpoints, ref double shortestDistance, ref int[] bestOrder) { var currentOrder = new int[position]; Array.Copy(order, currentOrder, position); var pathLength = PointExtensions.GetPathLength(checkpoints, currentOrder); if (pathLength < shortestDistance) { if (position == order.Length) { shortestDistance = pathLength; bestOrder = (int[])order.Clone(); return(order); } for (int i = 1; i < order.Length; i++) { var index = Array.IndexOf(order, i, 0, position); if (index != -1) { continue; } order[position] = i; MakePermutations(order, position + 1, checkpoints, ref shortestDistance, ref bestOrder); } } return(order); }
private static void MakePermutations(Point[] checpoints, int[] orders, int[] bestOrder, int position, ref double minCost) { var currCost = PointExtensions.GetPathLength(checpoints, orders); if (position == orders.Length) { if (minCost == 0 || minCost > currCost) { minCost = currCost; orders.CopyTo(bestOrder, 0); } return; } for (int i = 1; i < orders.Length; i++) { var index = Array.IndexOf(orders, i, 1, position); if (index != -1) { continue; } orders[position] = i; var currOrders = new int[position + 1]; Array.Copy(orders, currOrders, position + 1); currCost = PointExtensions.GetPathLength(checpoints, currOrders); if (currCost > minCost && minCost != 0) { continue; } MakePermutations(checpoints, orders, bestOrder, position + 1, ref minCost); } }
static void MakePermutations(int[] permutation, int position, List <int[]> result, Point[] checkpoints, double[] minValue) { if (position == permutation.Length) { minValue[0] = PointExtensions.GetPathLength(checkpoints, permutation); result.Add(permutation.ToArray()); } else { for (int i = 1; i < permutation.Length; i++) { var index = Array.IndexOf(permutation, i, 0, position); if (index != -1) { continue; } permutation[position] = i; if (PointExtensions.GetPathLength(checkpoints, permutation.Take(position + 1).ToArray()) >= minValue[0]) { continue; } MakePermutations(permutation, position + 1, result, checkpoints, minValue); } } }
public static int[] FindCheckpointsOrder(Point[] checkpoints) { var way = new int[checkpoints.Length]; way[0] = 0; var min = double.MaxValue; var minindex = 0; for (var i = 1; i < checkpoints.Length; i++) { for (var j = 1; j < checkpoints.Length; j++) { if (Array.IndexOf(way, j) != -1) { continue; } var dist = PointExtensions.DistanceTo(checkpoints[i - 1], checkpoints[j]); if (dist < min) { min = dist; minindex = j; } } way[i] = minindex; } return(way); }
public static bool IsThisWayBetter(Point[] checkpoints, List <int> bestOrder, List <int> permutation) { if (permutation.Count < 2) { return(true); } var len1 = PointExtensions.GetPathLength(checkpoints, permutation.ToArray()); var len2 = PointExtensions.GetPathLength(checkpoints, bestOrder.ToArray()); return(len1 < len2); }
static void ChoosingBestPath(int[] bestPath, int[] order, int position, Point[] checkpoints) { int iteration = 0; double orderLength = 0; if (iteration > 0) { orderLength += checkpoints[order[iteration - 1]].DistanceTo(checkpoints[order[iteration]]); } if (orderLength > Maximum) { return; } if (position == order.Length) { double currentLength = 0; for (var i = 0; i < position - 1; i++) { currentLength += PointExtensions.DistanceTo(checkpoints[order[i]], checkpoints[order[i + 1]]); } if (currentLength < Maximum) { Maximum = currentLength; for (var i = 0; i < order.Length; i++) { bestPath[i] = order[i]; } } return; } double length = 0; for (var i = 0; i < position - 1; i++) { length += PointExtensions.DistanceTo(checkpoints[order[i]], checkpoints[order[i + 1]]); } if (length > Maximum) { return; } for (var i = 1; i < order.Length; i++) { var index = Array.IndexOf(order, i, 1, position - 1); if (index != -1) { continue; } order[position] = i; ChoosingBestPath(bestPath, order, position + 1, checkpoints); } }
public static void MakeTrivialAction(Point[] checkpoints) { if (PointExtensions.GetPathLength(checkpoints, tempListBestOrder.ToArray()) < minPathLength) { outListBestOrder.Clear(); foreach (var e in tempListBestOrder) { outListBestOrder.Add(e); } minPathLength = PointExtensions.GetPathLength(checkpoints, tempListBestOrder.ToArray()); } }
public static int[] FindBestCheckpointsOrder(Point[] checkpoints) { minPathLength = double.MaxValue; var currentPath = new int[checkpoints.Length]; currentPath[0] = 0; var bestOrder = new List <int[]>(); MakePermutations(checkpoints, currentPath, 1, 0, bestOrder); for (int i = 0; i < bestOrder.Count; i++) { if (PointExtensions.GetPathLength(checkpoints, bestOrder[i]) == minPathLength) { currentPath = bestOrder[i]; } } return(currentPath); }
static void MakePermutation(int[] order, double size, int position, int[] bestOrder, Point[] checkpoints) { if (position == order.Length) { order.CopyTo(bestOrder, 0); return; } for (int i = 1; i < order.Length; i++) { if (Array.IndexOf(order, i, 0, position) != -1) { continue; } order[position] = i; var newSize = size + PointExtensions.DistanceTo(checkpoints[order[position - 1]], checkpoints[order[position]]); if (newSize < checkpoints.GetPathLength(bestOrder)) { MakePermutation(order, newSize, position + 1, bestOrder, checkpoints); } } }
public static int[] MakePermutations(int[] order, int position, Point[] checkpoints, ref double shortestDistance, ref int[] bestOrder) { var currentOrder = new int[position]; Array.Copy(order, currentOrder, position); var pathLength = PointExtensions.GetPathLength(checkpoints, currentOrder); // J: PointExtension - класс с расширениями. GetPathLength можно вызвать у checkpoints // Подробнее: //https://docs.microsoft.com/ru-ru/dotnet/csharp/programming-guide/classes-and-structs/extension-methods if (pathLength < shortestDistance) { if (position == order.Length) { shortestDistance = pathLength; bestOrder = (int[])order.Clone(); return(order); // Метод возвращает значение, которое не используется. // Метод безболезненно может стать void. } for (int i = 1; i < order.Length; i++) { var index = Array.IndexOf(order, i, 0, position); if (index != -1) { continue; } order[position] = i; MakePermutations(order, position + 1, checkpoints, ref shortestDistance, ref bestOrder); } } return(order); // }