【问题标题】:Dijkstra's Algorithm and the greedy strategyDijkstra 算法和贪心策略
【发布时间】:2018-12-03 22:37:19
【问题描述】:

我似乎有点难以理解贪婪策略的工作原理以及 Dijkstra 算法如何跟踪最短路径。作为参考,这里是 Dijkstra 算法的伪代码

DijkstrasAlgorithm(G, w, s)
    InitalizeSingleSource(G, s)
    S = 0
    Q = G.V
    while Q != 0
        u = ExtractMin(Q)
        S = S∪{u}
        for each vertex v ∈ G.Adj[u]
            Relax(u, v, w)

请考虑以下重量方向图。

有5个顶点:s、t、x、y、z 有 10 条边:

s->t = 3
s->y = 5
t->y = 2
t->x = 6
y->t = 1
y->x = 4
y->z = 6
x->z = 2
z->x = 7
z->s = 3

我们的目标是找到从 s 到 x 的最短路径。我的答案是长度为 9 的 s->t->y->x,我假设伪代码中的“S”是最短路径,并且将 minQ 中的每个 ExtractMin 添加到路径中。

然而,我的老师告诉我这是错误的。正确答案是 s->t->x,长度为 9。我们答案的不同在于是否包含 y。我的老师说既然s->t->x是“先找到”的,就不更新为s->t->y->x,就是等长了。

这让我很困惑。 Dijkstra 算法使用贪心策略,我认为贪心策略总是选择当时可用的最短路径。而当在 t->y 和 t->x 之间选择时,t->y 更短,因此应该选择。

我的问题是:

1) 贪心策略在什么情况下不会为最终结果选择最直接的最短路径?

2) 如果在 minQ 上使用 ExtractMin 不是我们跟踪从 s 到 x 的整体路径的方式,那么我们如何跟踪完整路径?

【问题讨论】:

  • 我不同意 Dijkstra 算法是一种贪心算法。该算法最重要的特征是Relax 函数,它甚至没有显示出来。从s开始,算法发现在3中可以到达t,在5中到达y。从t开始,算法发现在5中可以到达y(但是忽略了,因为我们可以已经在 5) 中到达 y,在 9 中到达 x。从 y 开始,您也可以在 9 中到达 x,但这被忽略了。所以你老师是对的,路径是stx
  • 那么你如何跟踪路径呢?
  • 我将有一个与每个顶点关联的from 成员变量。 t.from = sy.from = sx.from = t。算法完成后,从目的地向后工作。 Relax 函数需要在缩短距离的任何时候更新 from
  • 那么“如果(变量 = 目标)则返回源”?另外,伪代码中的 S 应该是什么?我认为这就是跟踪路径的原因。
  • 看来S是访问过的顶点集合。不确定它有什么用途,因为算法从不使用它,并且当算法完成时,它包含所有可到达的顶点。

标签: c++ algorithm dijkstra


【解决方案1】:

您的老师的回答假设我们按“最短优先,先见先断”的顺序探索路径。

首先,我们探索s->t,我们将x 以成本9 从s->t->x 放到“有一天”要探索的事物列表中。但我们首先探索s->t->y,因为它更短。在这一点上,我们看到s->t->y->x 是一个选项,成本也为 9。但是因为这不是一个改进,所以我们放弃了它。

因此,一旦我们到达长度为 9 的路径,我们会发现 s->t->x 出局,因为它首先进入队列。

如果您修改Relax 以保存可能的路径(如果它优于或等于迄今为止发现的最佳路径),您将得到答案。这将得到一个正确的答案。

至于路径是如何从末端提取出来的,每个节点都知道你是如何到达的。所以从头开始,沿着 cookie trail 倒过来找路径,然后倒过来得到实际路径。

【讨论】:

  • 那么像“如果(变量=目的地)然后保存当前路径”?以后再参考?
  • @Damerian No. 对于每个节点,保存对 (length, prev_node)。您可以从中重建最终路径,因为x 将具有(9, t),而 t 将具有(3, s),这足以确定您使用x from t from s。反过来,你会得到s -> t -> x
  • 所以,为了确保我理解,我会在最初找到 x 时执行此操作?如果我再次找到 x 并且它是一条较短的路径,我只会重复它?
  • @Damerian 您为找到的路径较短的每个节点执行此操作。一旦找到x,就可以找出路径。
猜你喜欢
  • 1970-01-01
  • 2012-12-11
  • 2023-04-02
  • 2012-03-29
  • 2022-12-07
  • 2019-04-27
  • 1970-01-01
  • 1970-01-01
  • 2021-11-19
相关资源
最近更新 更多