具有移动约束的网格探索算法

时间:2015-05-27 03:59:13

标签: c# algorithm recursion

最近我一直坚持使用算法来探索网格"。我想根据可能在网格上任何位置的起始方块绘制在网格的某个部分内有效的所有移动。我最初的计划是在4个方向标记网格中使用递归拆分,直到它达到边界或移动限制。探索"分支"不能沿对角线移动:

*注意:箭头不表示在堆栈中出现,它们用于可视化算法的概念

enter image description here

private void Explore(byte moves, byte row, char col) {
        if (row >= Grid[0].Count || col >= Grid.Count || row + col + 2 > moves) {//var < 0 handled b/c byte b = 0; (byte)(b-1) == 255
            return;
        }
        Grid[row][col].color = ...;//mark it

        if (Grid[row + 1][col + 1] == notVisited) Explore((byte) (moves - 1), (byte)(row + 1), (char) (col + 1));
        if (Grid[row - 1][col + 1]== notVisited) Explore((byte)(moves - 1), (byte)(row - 1), (char) (col + 1));
        if (Grid[row - 1][col - 1] == notVisited) Explore((byte)(moves - 1), (byte)(row - 1), (char) (col - 1));
        if (Grid[row + 1][col - 1] == notVisited) Explore((byte)(moves - 1), (byte)(row + 1), (char) (col - 1));
    }

我知道这个算法没有工作b / c我做了一个快速运行的样本here,其中算法卡在值之间,直到它触发运行时错误。

所以此时:

  1. 递归仍然是可能的(切换到迭代)?

  2. 这个问题有更好的替代算法吗?

  3. 我的算法是否关闭,但需要进行一些调整?

2 个答案:

答案 0 :(得分:1)

您似乎希望实施depth-first search。维基文章甚至提供了一些伪代码,您可以使用它们来实现算法。

请注意,这将标记所有可到达的方块,但不会打印出所有(冗余)移动,除非您修改算法。

答案 1 :(得分:1)

搜索的想法应该可以正常工作,但代码不起作用的原因是因为它正在检查对角线。

if (Grid[row + 1][col + 1] == notVisited)
if (Grid[row - 1][col + 1]== notVisited) 
if (Grid[row - 1][col - 1] == notVisited) 
if (Grid[row + 1][col - 1] == notVisited)

我认为你的意思是:

if (Grid[row + 1][col] == notVisited)
if (Grid[row - 1][col]== notVisited) 
if (Grid[row][col + 1] == notVisited) 
if (Grid[row][col - 1] == notVisited)

问题:

1:递归很好。迭代会更快,但它不会产生太大的差异。

2:可能有很多不同的方法,但目前的方法应该没问题。

3:除了改变这四个条件外,这个条件

|| row + col + 2 > moves)

可能会导致程序奇怪地执行,具体取决于放置的位置。 moves参数对于所有递归路径都不相同,因此程序大多数时间都会绘制整个网格。除此之外,该计划应运行良好。