public static PointList ClosestPair(PointList inputList) { PointList endpoints = inputList.Clone(); List<PointList> vertexChains = new List<PointList>(); while (endpoints.Count > 2) { PairOfPoints closestPair = findClosestPair(forEachPair(endpoints).Where(pair => !inSameVertexChain(pair.A, pair.B, vertexChains))); PointList chainA = findChainWithEndpoint(closestPair.A, vertexChains); PointList chainB = findChainWithEndpoint(closestPair.B, vertexChains); if (chainA != null && chainB != null) { vertexChains.Remove(chainA); vertexChains.Remove(chainB); chainA.Reverse(); vertexChains.Add(new PointList(chainA.Concat(chainB))); endpoints.Remove(closestPair.A); endpoints.Remove(closestPair.B); continue; } if (chainB != null) { closestPair = closestPair.Invert(); chainA = chainB; chainB = null; } if (chainA != null) { chainA.Insert(0, closestPair.B); endpoints.Remove(closestPair.A); continue; } vertexChains.Add(new PointList(new List<Point>() { closestPair.A, closestPair.B })); } if (vertexChains.Count > 1) throw new ApplicationException("More than one vertex chain was obtained."); vertexChains[0].Add(vertexChains[0][0]); return vertexChains[0]; }
private static PointList nearestNeighbor(PointList inputList, Point startingPoint) { Point last = startingPoint; PointList visited = new PointList() { last }; PointList unvisited = inputList.Clone(); unvisited.Remove(last); while (unvisited.Count > 0) { Point next = findClosestPair(unvisited.ConvertAll(p => new PairOfPoints(last, p))).B; visited.Add(next); unvisited.Remove(next); last = next; } visited.Add(visited[0]); return visited; }