📜  有向无环图中的最长路径|设置 2(1)

📅  最后修改于: 2023-12-03 15:40:17.748000             🧑  作者: Mango

有向无环图中的最长路径

在图论中,有向无环图(Directed Acyclic Graph,简称DAG)是一种无环有向图。DAG在实际应用中非常广泛,例如任务调度、编译优化、建筑物结构设计等领域都有应用。本文将介绍如何求解有向无环图中的最长路径。

问题描述

假设给定一个有向无环图G,每条边都有一个权值,求图G中从起点到终点的最长路径。

算法思想

我们可以运用动态规划的思想来解决这个问题。 设$dp[i]$表示从起点到节点$i$的最长路径。 则:$$|dp[i]=\max_{j \in E(i)} dp[j] + w_{i,j}|$$ 其中$E(i)$为节点$i$的入边集合,$w_{i,j}$为从节点$j$到节点$i$的边的权值,因为是有向无环图,所以没有环 ,不存在死循环的情况。

算法实现

我们可以使用拓扑排序的方式实现这个算法。

  1. 将图G拓扑排序,将所有节点按照拓扑序排列。
  2. 对于排列后的每个节点$i$,更新其最长路径:$$|dp[i]=\max_{j \in E(i)} dp[j] + w_{i,j}|$$
  3. 最终$dp[end]$即为从起点到终点的最长路径。

在实现时,我们可以使用一个队列来保存拓扑序列,队列的初值为所有入度为0的节点。每次从队列中弹出一个节点$i$,更新其所有直接后继节点$j$的入度,如果入度变为0,则将其加入队列中。直到队列为空。

下面是使用Python实现算法的代码:

# Python code:

from collections import deque

def DAG_longest_path(G, start, end):
    # 拓扑排序
    in_degree = [0] * len(G)
    Topology_queue = deque([start])  
    while Topology_queue:
        u = Topology_queue.popleft()
        for v in G[u].keys():
            in_degree[v] -= 1  
            if in_degree[v] == 0:
                Topology_queue.append(v)
        # 更新最长路径
        for v, w in G[u].items():
            if dp[v] < dp[u] + w:
                dp[v] = dp[u] + w
    return dp[end]

# 例子:
G = {
    0: {1: 6, 2: 4},
    1: {3: 7},
    2: {1: 2, 3: 5},
    3: {4: -4},
    4: {2: 4}
}
start = 0
end = 4
dp = [0] * len(G)
dp[start] = 0
print(DAG_longest_path(G, start, end)) #输出6+4+2+4=16
时间复杂度

由于要进行拓扑排序,所以时间复杂度为$O(|E|+|V|)$,其中$|E|$为边数,$|V|$为节点数。

总结

本文介绍了如何使用动态规划的思想解决有向无环图中的最长路径问题,并给出了算法的具体实现。算法的核心是拓扑排序和更新最长路径的动态规划式子。对于有向无环图,该算法可以得到$O(|E|+|V|)$的时间复杂度。