I need do find a cycle beginning and ending at given point. It is not guaranteed that it exists.
I use bool[,] points to indicate which point can be in cycle. Poins can be only on grid. points indicates if given point on grid can be in cycle.
I need to find this cycle using as minimum number of points.
One point can be used only once.
Connection can be only vertical or horizontal.
Let this be our points (red is starting point):
removing dead ImageShack links
I realized that I can do this:
while(numberOfPointsChanged)
{
//remove points that are alone in row or column
}
So i have:
removing dead ImageShack links
Now, I can find the path.
removing dead ImageShack links
But what if there are points that are not deleted by this loop but should not be in path?
I have written code:
class MyPoint
{
public int X { get; set; }
public int Y { get; set; }
public List<MyPoint> Neighbours = new List<MyPoint>();
public MyPoint parent = null;
public bool marked = false;
}
private static MyPoint LoopSearch2(bool[,] mask, int supIndexStart, int recIndexStart)
{
List<MyPoint> points = new List<MyPoint>();
//here begins translation bool[,] to list of points
points.Add(new MyPoint { X = recIndexStart, Y = supIndexStart });
for (int i = 0; i < mask.GetLength(0); i++)
{
for (int j = 0; j < mask.GetLength(1); j++)
{
if (mask[i, j])
{
points.Add(new MyPoint { X = j, Y = i });
}
}
}
for (int i = 0; i < points.Count; i++)
{
for (int j = 0; j < points.Count; j++)
{
if (i != j)
{
if (points[i].X == points[j].X || points[i].Y == points[j].Y)
{
points[i].Neighbours.Add(points[j]);
}
}
}
}
//end of translating
List<MyPoint> queue = new List<MyPoint>();
MyPoint start = (points[0]); //beginning point
start.marked = true; //it is marked
MyPoint last=null; //last point. this will be returned
queue.Add(points[0]);
while(queue.Count>0)
{
MyPoint current = queue.First(); //taking point from queue
queue.Remove(current); //removing it
foreach(MyPoint neighbour in current.Neighbours) //checking Neighbours
{
if (!neighbour.marked) //in neighbour isn't marked adding it to queue
{
neighbour.marked = true;
neighbour.parent = current;
queue.Add(neighbour);
}
//if neighbour is marked checking if it is startig point and if neighbour's parent is current point. if it is not that means that loop already got here so we start searching parents to got to starting point
else if(!neighbour.Equals(start) && !neighbour.parent.Equals(current))
{
current = neighbour;
while(true)
{
if (current.parent.Equals(start))
{
last = current;
break;
}
else
current = current.parent;
}
break;
}
}
}
return last;
}
But it doesn’t work. The path it founds contains two points: start and it’s first neighbour.
What am I doing wrong?
EDIT:
Forgot to mention… After horizontal connection there has to be vertical, horizontal, vertical and so on…
What is more in each row and column there need to be max two points (two or none) that are in the cycle. But this condition is the same as “The cycle has to be the shortest one”.
That is what I have done. I don’t know if it is optimised but it does work correctly. I have not done the sorting of the points as @marcog suggested.