public TspSolution Execute(TsPoint[] points) { var minX = points.Min(p => p.X); var maxX = points.Max(p => p.X); var rangeMinX = 1.1*minX; var rangeMaxX = .9*maxX; TsPoint upperRight = null; TsPoint upperLeft = null; TsPoint lowerRight = null; TsPoint lowerLeft = null; foreach (var point in points.Skip(1)) { if (point.X >= rangeMaxX) { if (upperRight == null || point.Y >= upperRight.Y) upperRight = point; if (lowerRight == null || point.Y <= lowerRight.Y) lowerRight = point; } else if(point.X <= rangeMinX) { if (upperLeft == null || point.Y >= upperLeft.Y) upperLeft = point; if (lowerLeft == null || point.Y <= lowerLeft.Y) lowerLeft = point; } } var solution1 = CreateSolution(points.Where(p => p != upperRight).ToArray(), upperRight); solution1.OutputToDebug(); var solution2 = CreateSolution(points.Where(p => p != upperRight).ToArray(), lowerRight); solution2.OutputToDebug(); if (solution2.Distance < solution1.Distance) solution1 = solution2; var solution3 = CreateSolution(points.Where(p => p != upperRight).ToArray(), upperLeft); solution3.OutputToDebug(); if (solution3.Distance < solution1.Distance) solution1 = solution3; var solution4 = CreateSolution(points.Where(p => p != upperRight).ToArray(), lowerLeft); solution4.OutputToDebug(); if (solution4.Distance < solution1.Distance) solution1 = solution4; return solution1; }
public TspSolution Execute(TsPoint[] points) { var minX = points.Min(p => p.X); var maxX = points.Max(p => p.X); var increment = (maxX - minX) / _steps; TspSolution solution = null; for (int i = 1; i <= _steps; i++) { var range = minX + increment; if (i == _steps) ++range; var thesePoints = points.Where(p => p.X >= minX && p.X < range).ToList(); TsPoint firstPoint; if (solution == null) { firstPoint = thesePoints.OrderBy(p => p.Y).First(); solution = new TspSolution(firstPoint); } else { firstPoint = GetClosestPoint(solution.LastItem, thesePoints); solution.AddNext(firstPoint); } CreateSolution(thesePoints, solution, firstPoint); minX = range; } if (solution != null) { solution.Close(); solution.OutputToDebug(); } return solution; }
public TspSolution Execute(TsPoint[] points) { var minX = points.Min(p => p.X); var maxX = points.Max(p => p.X); var minY = points.Min(p => p.Y); var maxY = points.Max(p => p.Y); const int pageSize = 7; var stepX = (maxX - minX) / pageSize; var stepY = (maxY - minY) / pageSize; var groups = new List<TspGroup>(); var goingDown = false; var sortNumber = 0; for (var x = minX; x < maxX; x = x + stepX) { if (goingDown) sortNumber += pageSize-1; else if (sortNumber > 0) sortNumber += pageSize+1; for (var y = minY; y < maxY; y = y + stepY) { var sort = goingDown ? sortNumber-- : sortNumber++; //Console.WriteLine(sort); var group = new TspGroup {SortNumber = sort, MinX = x, MaxX = x+stepX, MinY = y, MaxY = y+stepY}; groups.Add(group); if ((y + stepY) > (maxY - (stepY / pageSize))) { group.MaxY = maxY + 1; y = maxY; } if ((x + stepX) > (maxX - (stepX / pageSize))) { group.MaxX = maxX + 1; } } if ((x + stepX) > (maxX - (stepX / pageSize))) { x = maxX; } goingDown = !goingDown; } var sortedGroups = groups.OrderBy(g => g.SortNumber).ToArray(); for (var i = 0; i < sortedGroups.Length; i++) { var group = sortedGroups[i]; bool goingUp = ((group.SortNumber / pageSize) % 2) == 0; TsPoint[] pointsPage; var pointsPage1 = points.Where(p => p.X >= group.MinX && p.X < group.MaxX && p.Y >= group.MinY && p.Y < group.MaxY); if (goingUp) pointsPage = pointsPage1.OrderBy(p => p.X).ThenBy(p => p.Y).ToArray(); else pointsPage = pointsPage1.OrderBy(p => p.X).ThenByDescending(p => p.Y).ToArray(); var firstPoint = pointsPage.First(); if (_solution == null) { _solution = new TspSolution(firstPoint); } else { var lastItem = _solution.LastItem; firstPoint = pointsPage.Aggregate(firstPoint, (min, curr) => curr.DistanceFrom(lastItem) < min.DistanceFrom(lastItem) ? curr : min); _solution.AddNext(firstPoint); } var alreadyVisited = new List<int> { firstPoint.Id }; var last = firstPoint; while (alreadyVisited.Count != pointsPage.Length) { var notVisited = pointsPage.Where(p => !alreadyVisited.Contains(p.Id)).ToArray(); var next = notVisited.Aggregate(notVisited.First(), (min, curr) => curr.DistanceFrom(last) < min.DistanceFrom(last) ? curr : min); alreadyVisited.Add(next.Id); last = next; _solution.AddNext(next); } } _solution.Close(); return _solution; }