Мне нужно найти начало цикла и завершение в данной точке. Не гарантируется, что он существует.
Я использую 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 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: Забыл упомянуть... После горизонтального соединения должны быть вертикальные, горизонтальные, вертикальные и так далее... Более того, в каждой строке и столбце должно быть не более двух точек (два или ни одного), которые находятся в цикле. Но это условие такое же, как "Цикл должен быть самым коротким".