在矩阵中找到两个坐标之间的路径

时间:2013-03-27 07:49:13

标签: algorithm

所以,我有这个问题。 我有这个矩阵:

1 1 1 1 1 1 1 1 1 1
1 1 0 0 0 1 0 T 0 1
H 0 0 1 1 1 0 1 1 1
1 1 0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1 1 1

我需要建立一个从H开始的路径,它有坐标(3.1)到T(2.8) 我需要: 我需要一个程序来读取矩阵A [1..M,1..N],它本身代表一个带有元素[0,1]的迷宫,并且还读取H,T值。值1被设为墙,您无法通过它。 所以我之前发布过这个问题,我需要一些语法方面的帮助。

我在伪代码中如何看待它:

var walkingDirection = up;
var walkingDirection1 = down;
var walkingDirection2 = right;
var walkingDirection3 = left;
while (not at T)
    if (next field in walkingDirection is not 1)
        go to next field in walkingDirection
    else if
       (next field in walkingDirection1 is not 1)
        go to next field in walkingDirection1
else if
       (next field in walkingDirection2 is not 1)
        go to next field in walkingDirection2
else if
         (next field in walkingDirection3 is not 1)
        go to next field in walkingDirection3
    end if
end while

请帮我解释一些语法

int myArray[5][10] = { {1 1 1 1 1 1 1 1 1 1},
                       {1 1 0 0 0 1 0 T 0 1},
                       {H 0 0 1 1 1 0 1 1 1},
                       {1 1 0 0 0 0 0 0 0 1},
                       {1 1 1 1 1 1 1 1 1 1} };
int H = myArray [3][1];
int T = myArray [2][8];

if myArray [a+1][b]==1)

1 个答案:

答案 0 :(得分:3)

不幸的是,您的算法不适用于任何类型的可解决的迷宫。

仔细研究一下您计划进行的不同阶段的逐步操作,您将能够验证它,即使对于给出的示例迷宫也不起作用。

要看到这一点,最好通过示例播放整个算法。

1 1 1 1 1 1 1 1 1 1
1 1 0 0 0 1 0 T 0 1
H 0 0 1 1 1 0 1 1 1
1 1 0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1 1 1

从节点H开始:

  • 首先检查while条件:

    我们不在节点T,因此循环将运行。

  • 检查walkingDirection我们看到有1,因此无法使用此分支。

  • 对于walkingDirection1也是如此,所以这个分支也不能被采用。

    相反,它是walkDirection2分支,算法将进入右侧步骤。

  • 我们已经访问了walkingDirection2分支,因此不再检查walkingDirection3。

  • 控制流程到达while循环的末尾。

    我们必须再次检查条件:仍然不在节点T,所以我们必须继续。

    ...

继续以这种方式逐步播放示例,您很快就会发现问题。这是下图中标有*的行:

1 1 1 1 1 1 1 1 1 1
1 1 * 0 0 1 0 T 0 1
H 0 * 1 1 1 0 1 1 1
1 1 0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1 1 1

一旦你的算法进入地牢的那一部分,它就会不断地上下移动。

  • 取走walkDirection分支,但仍然可以走路。

  • 在walkDirection1中向前迈出一步,一个walkDirection被阻止在下一次运行中转身,因为现在walkDirection再次可以步行。

......那该怎么办?

虽然测试任何可能的方向通常都不是一个坏主意 - 事实上除了测试和希望最好之外没有任何其他选择 - 你的算法缺少某种记忆。

为了防止它在圈子中运行,它必须能够检测到它已经检查过该选项,或者甚至更好地“记住”有趣的点。那些提供尚未经过测试的可能性。

虽然不是最有效的版本,但一个非常简单的想法可能是保留已经检查过的所有字段的列表。保留已经访问的每个字段的记录,例如:字段位于某某位置,我从字段中到达那里,所以你会一次又一次地阻止同样的错误。

保留你能够检查的所有潜在候选人的第二个清单,因为你已经进入了它旁边的一个字段,记住了这样的事情:当我站在某个地方时,我看到了某某某某的情况我可以认为你应该能够继续检查最有趣的领域。

概要

总结到目前为止给出的想法,算法可归结为两个功能:

下一个字段()


从目前为止看到的字段列表中取一个字段。

如果已经检查过,则将其丢弃,因为没有值得再次检查。继续丢弃检查过的字段,直到:

  • 你的清单是空的:迷宫没有解决方案

    然后您可以退出该程序。

  • 您找到一个尚未检查过的字段。

    在这种情况下 inspect()

检查字段()


检查您是否已经在节点T

  • 如果是的话 - 大声朗读“万岁”,因为你刚刚逃离地牢。

    哦,是的 - 你可以在这里退出你的计划。

  • 如果不是

    将新记录输入您的检查字段列表,记住您来自何处。

    检查所有相邻字段是否可以访问,以及是否已经检查过。

    • 如果它们可以访问但尚未检查过,请务必将它们添加到目前为止看到的有趣字段列表中,记住您从哪个字段中看到它们。

      现在继续 next_field()

这样,程序启动后你唯一需要做的就是 inspect()字段H并等待结果。

...另见

为了获得更高的赌注,您可能需要查看以下任何材料: