【问题标题】:Use Dijkstras to find the "k" shortest path使用 Dijkstras 找到“k”最短路径
【发布时间】:2014-08-05 18:14:09
【问题描述】:

我已经可以使用 Dijkstra 算法找到两个顶点之间的最短路径:wiki Dijkstra's

但是。我的一些边缘旨在用作“检查点”,因为您必须通过至少一个检查点才能获得可用的路线。

有时,算法会找到一条不包含这些边缘检查点的路径。在那种情况下,我想找到第二个。最短路线 - 如果该路线也不包含检查点,则找到第三条。最短路径等等。

任何想法如何让我开始?

编辑:

是否可以在第一条路线上遍历所有的前辈,然后从前辈跑到目的地的Dijkstras(并排除前辈的下一个goto顶点的原始选择)。这样我就可能找到所有可能的路线,然后将它们相互比较?

示例。

A = 来源 Z = 目的地

最短路径:A -> B -> C -> D -> Z

第二。最短路径:A -> B -> C -> D ->“成本最低的顶点,不是 Z”(如果在当前尝试中找不到可用路径,则循环遍历所有 D 的未访问邻居)

如果是第二个。最短路径也不包含检查点,尝试第三个最短路径

第三。最短路径:A -> B -> C -> 成本最低的顶点,不是 D

或者这个解决方案无论如何都不可能?

编辑 2:

可能很难看到,但紫色 1x3 像素是顶点。黄色的道路是边缘,粉红色的 3x3 像素也是如此。粉红色的也是所谓的检查站。所以我必须找到最短的路线,并且至少要经过一个检查站。

【问题讨论】:

  • 您还有其他关于图形地形的信息吗?它是一个有向图吗?如果是,它可以包含循环吗?
  • 请在问题中明确说明您必须使用 Dijkstra 算法。
  • 还有,怎么去Greenalnd?

标签: c# algorithm dijkstra path-finding


【解决方案1】:

您可以尝试几种方法来完成这项工作。

我们称S为起始节点,D为目的节点,I为中间节点。

[单个中间节点] 一个简单但次优的解决方案是使用从 S 到 I 的 Dijkstra,然后将 Dijkstra 的结果从 I 附加到 D。

[多个中间节点] 正如 Niklas B. 指出的那样,一种可行的方法是“从 S 和 D 构建最短路径树。对于每个中间节点 A,检查 d(S, A) + d(T, A)。最小值是解决方案。运行时间是 Dijkstra 的两倍,例如 O((n+m) log n) with binary heaps".

【讨论】:

  • 很好的解决方案,但如果有多个“检查点”,它就不会真正起作用。从问题中的复数来看,我认为有这种情况。
  • 你能解释一下“中间节点”是什么意思吗?是要设置一个节点,还是每次搜索最近邻节点都要设置一个?
  • 有大约 10 个可用的检查点,但它只需要通过其中一个。
  • 好的,感谢您的编辑,但我不能只选择一个中间节点,因为有几个可用的检查点,而且它必须是最近的。
  • Dijkstra 不错。从 S 和 D 构建最短路径树。对于每个中间节点 A,检查 d(S, A) + d(D,A)。最低限度是解决方案。运行时间是 Dijkstra 的两倍,例如O((n+m) log n) 与二进制堆
【解决方案2】:

根据图表的变化频率,您可以尝试 Floyd Warshall 算法。它将帮助您构建一个矩阵,该矩阵将向您显示任何节点对之间的最短路径。一旦你有了它,你就可以使用 Saverio Terracciano 的答案迭代你的检查点,以确定哪个检查点是最好的检查点。

【讨论】:

    【解决方案3】:

    对于每个节点,不是成本最低,而是有 n 个最低成本,其中 n 是需要访问的检查点的数量。假设你说你需要 N/M 和顺序,哪个 N 无关紧要。

    然后,当您传播成本时,您跟踪检查点并更新相应的 n 槽以获得所需的信息。您可能希望将 n 限制在最小值,因为如果您需要 2 个检查点并通过 3 个检查点,您仍然有 2 个,但额外的没有任何价值。

    【讨论】:

      【解决方案4】:

      我的建议是 - 添加更多维度来存储通过的检查点。

      因此,(x1,x2) 状态将替换为:(x1,x2,c1...c_n) 其中c1..cn 是每个检查点的布尔标志。

      而边 (x1,x2)->(y1,y2) 将被替换为:

      • (x1,x2, c1..cn)->(y1,y2, c1..cn) 用于非检查点状态
      • (x1,x2, c1..cn)->(y1,y2, c1..c(x-1), true ,c(x+1)..cn) 检查点状态 cx

      对于任何c1..cn

      搜索算法本身是相同的,但状态数将乘以2^n

      编辑: 此外,如果需要匹配至少一个(不是几个不同的)检查点,向量c1..cn 可以替换为一个标志,该标志将描述至少一个检查点已通过。

      【讨论】:

      • 感谢您的回答,但我必须承认我真的不太了解您在这里解释的内容。我不是那种铁杆,只是个学生。
      • @SimonSondrupKristensen,没有像乍一看那样多的硬核......你只是通过添加关于通过检查点的额外信息来改变你的图表......换句话说是就像在地图上为每个通过的检查点组合添加图层一样
      【解决方案5】:

      您也可以将其转换为 TSP 问题以获得最佳路线:

      • 对起始节点 S 和中间节点 I 使用正常权重
      • 使用从 S 到结束节点 E 的无限权重(我们想简单地删除/忽略连接起点和终点的往返)
      • 使用0权重连接终点E和起点S

      现在对于每个检查点:

      • 将检查点作为中间点添加到基本行程
      • 使用 TSP 计算行程长度,使用 Dijkstra 计算节点之间的距离,并记住通过此检查点的长度

      这些旅行中最短的是最佳旅行,并且只通过一个检查点。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-02
        • 1970-01-01
        • 1970-01-01
        • 2015-09-12
        • 2023-04-06
        相关资源
        最近更新 更多