【问题标题】:Shortest path for a weighted graph, but the weights are a bit special加权图的最短路径,但权重有点特殊
【发布时间】:2022-01-22 23:34:09
【问题描述】:

我试图在加权多向图中找到一条最短路径(最便宜),其中顶点是城市,边是城市之间的路线,权重是价格。

每条路线/边缘由 3 家公司之一拥有。公司拥有的所有边缘的价格相同。因此,公司“A”拥有的所有边的价格都是 X。

因此,如果最终路径经过 A 公司的 2 条路线和 B 公司的 1 条路线,则最终价格为 2PriceofA + 1PriceOfB。此外,优势的权重就是关联公司的价格。

到目前为止,这是一个正常的情况,但是,以下额外的规则让我很难:

第 3 家公司“C”无论在最终路径中有多少条路线,都应用其价格 ONCE,但其价格通常高于之前的公司。因此,C 的路线最适合较长的路径,而 A 和 B 最适合较短的路径。

这是我到目前为止所做的(以及为什么它不起作用):

我正在使用 Dijkstra 来获得最便宜的路径,并且我只是将每个边的权重设置为公司的价格。即使是 C。

然后,如果算法访问 C 拥有的节点,它将 C 拥有的所有其他边的权重设置为 0。否则算法照常继续。

问题在于 Dijkstras 算法总是优先考虑直接的最佳选择,并且由于公司 A 和 B 的价格低于 C,所以它会尽量避开 C。有时这会导致算法认为最短的路径/最便宜,但实际上如果一开始就选择 C,可能会便宜得多。

在这种情况下,我怎样才能获得真正最便宜的路径?

我应该改用另一种算法吗?如果有,是哪一个?

【问题讨论】:

  • 如果你使用 Dijkstra,C 边应该在你访问过 xA 或 xB 之后出现,无论 A 或 B 的倍数使它们大于 C。然后包括C的路径优先向前移动并被检查。或者如果它从未被检查过,这意味着 A 或 B 的倍数仍然小于一个 C。或者我错过了什么?
  • "那么如果算法访问 C 拥有的一个节点,它会将 C 拥有的所有其他边的权重设置为 0。" 如果 C 拥有的边未被选中,您是否重置权重? IE。如果发现另一条路径没有经过该边缘?
  • 我将尝试改写 user1984 和 AloisChisten 已经指出的内容:Dijkstra 在这种情况下工作正常,但重置 C 边缘不是正确的方法。相反,除了跟踪到目前为止的路径长度之外,您还需要跟踪它是否越过 C 边缘。如果你愿意,我可以用 Python 画出它
  • 你说edges归公司所有,那么“一个node归C所有”是什么意思呢?如果你走一条像 CAC 这样的三边路径,你只需要支付一个 C 还是两个?如果有,那么我看不到问题所在。要么支付 C,要么不支付,因此运行 Dijkstra 两次,一次没有 C-edge,一次免费使用 C-edge(但将 C-cost 添加到总数中)。

标签: algorithm shortest-path dijkstra


【解决方案1】:

这里的一个选项是转换原始航班图,以直接编码这样的想法:一旦您乘坐 C 航班,未来所有 C 航班都是免费的。

对于每个机场 x,创建两个节点 x1 和 x2。这个想法是节点 x1 对应于在机场 x 中没有乘坐过 C 航班,而 x2 对应于在机场 x 中至少乘坐过一次 C飞行。

现在添加边如下。对于从机场 x 以价格 p 到机场 y 的每个 A 或 B 航班,以价格 p 和从 x 添加从 x1 到 y1 的边2 到 y2,价格为 p。这些对应于以既定价格乘坐 A 和 B 航班。然后,对于从机场 x 以价格 p 到机场 y 的每个 C 航班,以价格 p 添加从 x1 到 y2 的边(这是您支付的地方使用 C 航班的一次性费用)以及以 0 价格从 x2 到 y2(此航班免费,因为您已经支付了预付款使用 C 航班的费用)。

如果您在此修改后的图表中从节点 x1 开始运行 Dijkstra 算法,您可以通过查看到达 y1(不使用任何 C 航班)和 y2(使用至少一个 C 航班)。新图表中的路径将告诉您要乘坐哪些航班。

这会使输入图的大小加倍,这会稍微减慢 Dijkstra 的算法,但不会渐近地影响运行时间。

【讨论】:

    【解决方案2】:

    我认为您可以在每个节点的成本旁边保留一个标志,表明您是否已经使用过C 航班。此标志将决定下一次 C 航班是否会花费您。

    换句话说,当您使用 C 边时,不要将所有 C 边设置为零,而是将其保持在每个已尝试路径的状态的本地。

    您可以将设置了标志的路径优先于具有相同成本但未设置标志的其他路径。这是一种启发式方法,可帮助您的算法更快地找到解决方案,但它最终还是会这样做。

    现在,当您启动 Dijkstra 时,包含 C 成本的路径将在优先级队列中出现,只要 AB 路径的成本至少与 C 路径一样多包括C。据我所知,从那里它只是一个标准的 Dijkstra。

    【讨论】:

      猜你喜欢
      • 2012-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-26
      • 1970-01-01
      • 2017-07-06
      • 1970-01-01
      相关资源
      最近更新 更多