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; }
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); } } }
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; }