Algorithm 扭曲网格中的最短路径

Algorithm 扭曲网格中的最短路径,algorithm,dynamic-programming,graph-theory,dijkstra,breadth-first-search,Algorithm,Dynamic Programming,Graph Theory,Dijkstra,Breadth First Search,我试图解决一个基于图形的问题,以下是陈述: 我必须找到从标记位置到标记位置的最短路线。[注意:我标记了s和E只是为了便于理解]。这是一个陷阱问题,我只能穿过标记为0的单元格,标记为1的单元格表示无法通行的墙。此外,我还可以选择只移除一面墙,如果它能缩短我的退出路线移动只能在基本方向上进行;不允许对角移动。 二维网格示例: [ [0(S) 1 1 1 1 ], [0 0 1 1 1 ], [1 0 1 0 1 ], [1

我试图解决一个基于图形的问题,以下是陈述: 我必须找到从标记位置到标记位置的最短路线。[注意:我标记了s和E只是为了便于理解]。这是一个陷阱问题,我只能穿过标记为
0
的单元格,标记为
1
的单元格表示无法通行的墙。此外,我还可以选择
只移除一面墙
,如果它能缩短我的退出路线移动只能在基本方向上进行;不允许对角移动。

二维网格示例:

[
    [0(S) 1  1  1  1   ], 
    [0    0  1  1  1   ],
    [1    0  1  0  1   ],
    [1    1  0  0  0(E)],
]
如果没有拆除墙壁的选项,我可以简单地使用
Bfs
Dijkstra
找到最短路线。这里有人问了这个问题: -他们使用完全穷举搜索,这对大型矩阵非常不利,他们专注于基于语言的优化,这不是解决问题的好方法

-接受的答案有以下方法:

  • 从监狱门口开始进行广度优先搜索,以找到 每个可通行空间与监狱门的距离

  • 从逃生舱开始进行另一次广度优先搜索,以找到 每个可通行空间与逃生舱的距离

  • 现在遍历墙壁,并考虑依次移除每个墙壁。 你知道每个可通行的空间与监狱门的距离 还有逃生舱,所以你可以马上计算出 穿过墙壁留下的空间的最短路线
    你刚刚搬走了

但是我不清楚上面第三步的意思(所以你可以立即计算出穿过墙留下的空间的最短路线的长度)

还有什么更好的方法吗


它可以通过动态规划而不使用图形来解决吗?

我只想对图形进行如下扩充:构建一个新的图形
G'
,它是初始图形
G
的两倍大。G'的每个节点表示一个状态
(v,rem)
,其中
v
是G的一个节点,{0,1}中的
rem\n表示您是否已经删除了一个节点。还要添加一个额外的节点E_new

G'
中的邻接如下:

  • 所有
    (v,0)
    s(分别为
    (v,1)
    s)都像G一样相互链接(如果它们都有值0)
  • 如果v1的值为0,而其相邻的一个v2的值为1,则在
    (v1,0)
    (v2,1)
  • (E,0)
    (E,1)
    都以0的成本链接到
    E\u new
    。(如果不使用成本,只需将1减去最后的长度即可)
现在,您的目标是从
(s,0)
E_new
,Dijkstra(因此,如果所有步骤的成本相同,那么BFS在您的情况下)应该在最短时间内正常工作
O(n)
,其中n是节点数(而不是正方形的边)。A*会更快,但实施起来有点棘手。如果希望不移除墙的解决方案成为首选(等长),则必须注意执行BFS的顺序(首先是rem=0的节点)

这与(实际上是的一个实例)非常相似

编辑: 您上面建议的答案具有相同的复杂性,需要2个BF而不是1个BF,但是在一个比1小两倍的图上,所以可能类似,再加上另一个循环,所以我不知道哪一个更快

(因此,您可以立即计算出 穿过墙留下的空间)

在第1步和第2步中,您一方面计算了源与每面墙之间的分拣路径,另一方面计算了出口与所有墙之间的分拣路径,而无需穿过任何墙。通过为给定墙节点添加这两个值,可以仅获得从s到e穿过该墙的路径长度。通过迭代所有的墙(或者至少是其中的一部分,如果你做得很聪明的话),你可以得到最短的路径,你可以在不穿过任何墙的情况下与最短的(s,e)路径相比较,只保留最好的一条

编辑2

以下是我的方法的一个小示例: 假设您的网格如下所示:

[[0, 0, 1],
 [0, 1, 0]]
其中的节点可以用它们的坐标(1,1)、(1,2)等表示。
唯一存在的边是(1,1)到(1,2)和(1,1)到(2,1)以及(3,1)和(2,2)到(3,2)。向每个节点添加第三维rem,该值可以为0或1。对于rem的每个值,如果(i1,j1)->(i2,j2)在图中,则现在有(i1,j1,rem)->(i2,j2,rem)。对于不在图形中的所有边(i1,j1)->(i2,j2)(由于墙),现在有了(i1,j1,0)->(i2,j2,1)。另外,在最后,(2,3,0)->E_new和(2,3,1)->E_new。您可以在这个新图表中运行BFS。

您能用一个简单的例子来解释它吗。谢谢您的回答哪一部分?我的算法还是你找到的算法?你解释的算法不确定我是否理解你的问题。如果不穿过墙,则无法从S到达此墙,因此您计算的S与未穿过任何墙的墙之间的距离(步骤1)将是有限的(表示为一个非常大的整数big_VAL),因此它与到E的距离(从步骤2得到)之和不能是最小值,除非在0或1墙交叉中没有从S到E的路径。你可以通过检查你的最小路径的长度是否大于BIG_VAL来识别这种情况。我认为“可通行空间”的意思是“墙,如果被移除,会形成一条可能的路径”,即“墙不在其他墙之间”,但你可以对所有墙都这样做(无论如何,BFS将计算到网格中所有可到达点的最短距离,包括墙和非墙)。这就是我的理解,至少在O(n)中是这样工作的