【问题标题】:Shortest path in matrix with obstacles with cheat paths矩阵中的最短路径,带有作弊路径的障碍物
【发布时间】:2017-04-11 11:23:02
【问题描述】:

首先,这是一个评估,我不是在寻找直接的答案,而是在寻找您可能认为的最佳解决方案的复杂性。

这是已知的问题,即矩阵中的 2 个点(起点和终点)之间的最短路径,但途中有障碍物。移动可接受的是上、下、左和右。假设移动时 i 携带某物,每次移动的成本为 2 。矩阵中有一些点(我们将它们命名为 B 点),我可以将它留在一个 B 点中,然后从另一个 B 点拾取它。在 B 点倾倒某物的成本是 1,从 B 点重新捡起某物的成本是 1。每当我没有这个东西搬家时,我现在搬家的成本是1。 我认为解决方案是将矩阵转换为树并应用 BFS。然而,这在没有 B 点的情况下有效。

每当我考虑到 B 点复杂性时,最坏的情况就是 N^2。 这是一个例子:

S - - -
- - - -
B - - B
- - O E

S = 开始 , E = 结束 , B = B 点放下某事, O = 障碍物 所以我从S开始向下移动到B点(2 * 2 = 4点)在B点(1点)右移(2 * 1 = 2点),拿起它(1点),下移 2 点 = 共 10 点。

我的想法是构建每个 B 点都有节点的树,但是这将创建一个非常密集的几乎 (V-1)*(V-1) 边的循环图,它采用 N^2 边界中的算法只是为了创建图表。 这是上面最坏的情况:

S b b b
b b b b
b b b b 
b b b E

我认为的另一个选择是首先计算没有 B 点的最短路径。 然后在每次迭代中进行迭代: 首先在 S 和最近的 B 上有 bfs 在 E 和最近的 B 上有 BFS 然后看看在最接近 S 的 B 和最接近 E 的 B 之间是否存在路径。 如果有,那么我会看看路径是否小于有障碍物的常规最短路径。 如果它更大,那么就没有最短路径(没有贪心测试)。 如果 2 个 B 点之间没有路径,请尝试第二个最接近 S 的点,然后重试。 如果再没有路径,第二个最接近E,最接近S。 但是,在最坏的情况下,我无法计算这一复杂性,而且没有贪婪的测试来评估它。 任何有关计算复杂性甚至指出最佳复杂性解决方案(不是解决方案,而是复杂性)的帮助将不胜感激

【问题讨论】:

  • 使用你的图形是一个网格这一事实可能会更好,但如果不使用它,你至少可以在 O(n^2 * log(n)) 中得到一个解决方案,如果 n 是正方形的边,所以如果 V~n^2 是顶点数,则 O(V log V)。该解决方案的提示:您可以使用更大的图,其中一个节点是原始问题的完整状态,因此一对 (position, haveObject)...
  • 您的解决方案比最坏情况下的解决方案更糟糕:如果您到处都有 B,您将尝试每一对 B 点,您不想为每个点计算最短路径,并且从一开始就一起计算所有这些(例如 Floyd-Warshall)也太长了
  • 重要的是要注意,多次丢弃和拿起您的物品是不好的。例如。看看这个:S-b-b-b-b-E,你会在第一个 b 下车然后直接走到最后一个 b 然后再上车,在第二个 b 上上车然后在第三个下车是没有意义的。但最接近 S 和 E 的 bs 不一定是最好的。
  • @gdelab 我不知道有什么算法可以更有效地计算矩阵中的距离,所以如果你知道的话,只要说出它的名字。您的 O(V log V) 正是最短路径问题,在非常密集的图的情况下,作为输入,您有矩阵(输入为 n * n = V)并且构建密集图是计算 V * V- 1~V^​​2。因此,对于您的计算逻辑,它是 O(n ^ 4 log(n ^ 2)) 或 O(V ^ 2 log V) 。复杂性总是与 input 成比例。问题是验证贪婪测试,因此您不必测试所有路径
  • @maraca 我认为这是暗示的,但这并没有太大的帮助。我已经提到过我的方法没有贪心测试。

标签: algorithm path breadth-first-search shortest


【解决方案1】:

您的矩阵是图形的表示。没有作弊路径,很容易实现一个好的 BFS。实施作弊路径并不是什么大问题。只需在第一个顶部添加与另一个“层”相同的矩阵。底层是'carry',顶层是'no carry'。对于给定的成本,您只能在 B 点移动到另一层。这是具有第三个维度的相同 BFS。

每层有 n^2 个节点和 (n-1)^2 个边,另外最多有 n^2 个连接层的边。那是 O(n^2)。

【讨论】:

  • 只是澄清一下,使用 dijkstra (ElogV) 版本的总复杂度是
【解决方案2】:

您可以用 (N, w) 标记的节点构建一个新图,其中 N 是原始图中的一个节点(因此是矩阵中的一个位置),w=0 或 1 是您是否携带重量。然后很容易在这个图中添加所有可能的边

这个新图的大小为 2*V,而不是 V^2(边数约为 4*V+number(B))。

然后您可以使用最短路径算法,例如 Dijkstra 算法:复杂度 O(E + V log(V)),在您的情况下为 O(V log(V))。

【讨论】:

  • 我的输入是 N (V 个节点) 而不是具有 V-1 个边的 V 个节点,所以在最坏的情况下,总复杂度再次是 V^2,每个点都是一个 B 点,只是为了创建图形.
  • 不。即使在这种最坏的情况下,典型的节点也有一条边向右,一条向下,一条向左,一条向上,一条通往另一个节点,具有相同的 (x, y) 值但 w 的值不同。它们每个都被计算两次,总共有 2*V 个节点和 5*V 个边(忽略边界和障碍物的影响)
猜你喜欢
  • 2015-05-28
  • 2011-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多