Мне нужно найти цикл, начинающийся и заканчивающийся в данной точке. Не гарантируется, что оно существует.
Я использую bool[,] points
, чтобы указать, какая точка может быть в цикле. Точки могут быть только на сетке. points
указывает, может ли данная точка на сетке находиться в цикле.
Мне нужно найти этот цикл, используя как минимальное количество баллов.
Одна точка может быть использована только один раз.
Соединение может быть только вертикальным или горизонтальным.
Пусть это будут наши точки (красный - отправная точка):
удаление мертвых ссылок ImageShack
Я понял, что могу сделать это:
while(numberOfPointsChanged)
{
//remove points that are alone in row or column
}
Итак, у меня есть:
удаление мертвых ссылок ImageShack
Теперь я могу найти путь.
удаление мертвых ссылок ImageShack
Но что, если есть точки, которые не удаляются этим циклом, но не должны находиться в пути?
Я написал код:
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;
}
Но это не работает. Найденный путь содержит две точки: начало и его первый сосед.
Что я делаю не так?
EDIT:
Забыл упомянуть ... После горизонтального соединения должно быть вертикальное, горизонтальное, вертикальное и так далее ...
Более того, в каждой строке и столбце должно быть максимум две точки (две или ни одной), которые находятся в цикле. Но это условие такое же, как «цикл должен быть самым коротким».