public void FixIt(TspSolution solution) { var route = solution.Route; double largestDistance = 0; TsPoint largest1 = null; TsPoint largest2 = null; for (var i = 0; i < route.Count; ++i) { TsPoint last; if (i == 0) { last = solution.Route[i]; ++i; } else { last = solution.Route[i - 1]; } TsPoint current = solution.Route[i]; var distance = last.DistanceFrom(current); if (distance > largestDistance) { largestDistance = distance; largest1 = last; largest2 = current; } } Console.WriteLine("largest distance is between {0} and {1} with distance {2}", largest1, largest2, largestDistance); var closest1 = solution.Route.Aggregate(solution.Route.First(p => p != largest1), (min, curr) => curr != largest1 && (curr.DistanceFrom(largest1) < min.DistanceFrom(largest1)) ? curr : min); Console.WriteLine("closest to {0} is {1} with distance of {2}", largest1, closest1, closest1.DistanceFrom(largest1)); var closest2 = solution.Route.Aggregate(solution.Route.First(p => p != largest2), (min, curr) => curr != largest2 && (curr.DistanceFrom(largest2) < min.DistanceFrom(largest2)) ? curr : min); Console.WriteLine("closest to {0} is {1} with distance of {2}", largest2, closest2, closest2.DistanceFrom(largest2)); TsPoint c1Left = null; TsPoint c1Right = null; for (int i = 0; i < solution.Route.Count; i++) { if (solution.Route[i].Id != closest1.Id) continue; c1Left = solution.Route[i - 1]; c1Right = solution.Route[i + 1]; } if (c1Left == null || c1Right == null) Console.WriteLine("didnt find for c1"); else Console.WriteLine("{0} has left {1} with distance of {2} and right {3} with distance of {4}", closest1, c1Left, closest1.DistanceFrom(c1Left), c1Right, closest1.DistanceFrom(c1Right)); }
private void CreateSolution(IEnumerable<TsPoint> points, TspSolution solution, TsPoint firstPoint) { var notVisited = new List<TsPoint>(points.Where(p => p.Id != firstPoint.Id)); var last = firstPoint; while (notVisited.Any()) { var next = GetClosestPoint(last, notVisited); //check for potential orphans var pointsAbove = notVisited.Where(p => p != next && p.Y > last.Y).ToArray(); var pointsBelow = notVisited.Where(p => p != next && p.Y < last.Y).ToArray(); var pointsRight = notVisited.Where(p => p != next && p.X > last.X).ToArray(); var pointsLeft = notVisited.Where(p => p != next && p.X < last.X).ToArray(); TsPoint theAbove = null; TsPoint theBelow = null; TsPoint theRight = null; TsPoint theLeft = null; if (pointsAbove.Length == 1) { theAbove = pointsAbove.Single(); if (next.DistanceFrom(last) / theAbove.DistanceFrom(last) < _threshold) theAbove = null; } if (pointsBelow.Length == 1) { theBelow = pointsBelow.Single(); if (next.DistanceFrom(last) / theBelow.DistanceFrom(last) < _threshold) theBelow = null; } if (pointsRight.Length == 1) { theRight = pointsRight.Single(); if (next.DistanceFrom(last) / theRight.DistanceFrom(last) < _threshold) theRight = null; } if (pointsLeft.Length == 1) { theLeft = pointsLeft.Single(); if (next.DistanceFrom(last) / theLeft.DistanceFrom(last) < _threshold) theLeft = null; } var nextPoints = new[] { theAbove, theBelow, theRight, theLeft }.Where(p => p != null).ToList(); if (nextPoints.Any()) { var unOrphaned = GetClosestPoint(last, nextPoints); notVisited.Remove(unOrphaned); last = unOrphaned; solution.AddNext(unOrphaned); } else { notVisited.Remove(next); last = next; solution.AddNext(next); } } }
public TspSolution Execute(TsPoint[] points) { var sortedPoints = points.OrderBy(p => p.X).ThenBy(p => p.Y); var firstPoint = sortedPoints.First(); var solution = new TspSolution(firstPoint); foreach (var point in sortedPoints.Skip(1)) solution.AddNext(point); solution.Close(); return solution; }
private TspSolution CreateSolution(TsPoint[] points, TsPoint firstPoint) { var solution = new TspSolution(firstPoint); var alreadyVisited = new List<int> { firstPoint.Id }; var last = firstPoint; while (alreadyVisited.Count != points.Length) { var notVisited = points.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; }
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; }
private void CreateSolutionOld(TsPoint[] points, TspSolution solution, TsPoint firstPoint) { var alreadyVisited = new List<int> { firstPoint.Id }; var last = firstPoint; while (alreadyVisited.Count != points.Length) { var notVisited = points.Where(p => !alreadyVisited.Contains(p.Id)).ToArray(); var next = notVisited.Aggregate(notVisited.First(), (min, curr) => curr.DistanceFrom(last) < min.DistanceFrom(last) ? curr : min); if (next.Y < solution.LastItem.Y) { //i went down, so is there only 1 left above me? var above = points.Where(p => !alreadyVisited.Contains(p.Id) && p != next && p.Y > next.Y).ToArray(); if (above.Length == 1) { var theAbove = above.Single(); if (next.DistanceFrom(last) / theAbove.DistanceFrom(last) > .95) next = theAbove; } } else { //i went up, so is there only 1 left below me? var below = points.Where(p => !alreadyVisited.Contains(p.Id) && p != next && p.Y < next.Y).ToArray(); if (below.Length == 1) { var theBelow = below.Single(); if (next.DistanceFrom(last) / theBelow.DistanceFrom(last) > .95) next = theBelow; } } alreadyVisited.Add(next.Id); last = next; solution.AddNext(next); } }
public TspSolution Execute(TsPoint[] points) { var firstPoint = points.First(); var solution = new TspSolution(firstPoint); //var alreadyVisited = new List<int> { firstPoint.Id }; var notVisited = new List<TsPoint>(points.Where(p => p.Id != firstPoint.Id)); var last = firstPoint; //while (alreadyVisited.Count != points.Length) while(notVisited.Any()) { //var notVisited = points.Where(p => !alreadyVisited.Contains(p.Id)).ToArray(); var next = GetClosestPoint(last, notVisited); //var nextNotVisited = points.Where(p => !alreadyVisited.Contains(p.Id) && p != next).ToArray(); //check for potential orphans var pointsAbove = notVisited.Where(p => p != next && p.Y > last.Y).ToArray(); var pointsBelow = notVisited.Where(p => p != next && p.Y < last.Y).ToArray(); var pointsRight = notVisited.Where(p => p != next && p.X > last.X).ToArray(); var pointsLeft = notVisited.Where(p => p != next && p.X < last.X).ToArray(); TsPoint theAbove = null; TsPoint theBelow = null; TsPoint theRight = null; TsPoint theLeft = null; if (pointsAbove.Length == 1) { theAbove = pointsAbove.Single(); if (next.DistanceFrom(last) / theAbove.DistanceFrom(last) < _threshold) theAbove = null; } if (pointsBelow.Length == 1) { theBelow = pointsBelow.Single(); if (next.DistanceFrom(last) / theBelow.DistanceFrom(last) < _threshold) theBelow = null; } if (pointsRight.Length == 1) { theRight = pointsRight.Single(); if (next.DistanceFrom(last) / theRight.DistanceFrom(last) < _threshold) theRight = null; } if (pointsLeft.Length == 1) { theLeft = pointsLeft.Single(); if (next.DistanceFrom(last) / theLeft.DistanceFrom(last) < _threshold) theLeft = null; } var nextPoints = new[] {theAbove, theBelow, theRight, theLeft}.Where(p => p != null).ToList(); if (nextPoints.Any()) { var unOrphaned = GetClosestPoint(last, nextPoints); //alreadyVisited.Add(unOrphaned.Id); notVisited.Remove(unOrphaned); last = unOrphaned; solution.AddNext(unOrphaned); } else { //alreadyVisited.Add(next.Id); notVisited.Remove(next); last = next; solution.AddNext(next); } } solution.Close(); //solution.OutputToDebug(); return solution; }