关键路径(Java)

一、四个核心时间(必须背)

符号 全称 含义 对象
etv 事件最早发生时间 事件最早什么时候能发生 顶点
ltv 事件最晚发生时间 事件最晚什么时候必须发生 顶点
ete 活动最早开始时间 活动最早什么时候能开始
lte 活动最晚开始时间 活动最晚什么时候必须开始

二、计算公式

1. etv(正向,取最大)

复制代码
etv[v] = max(etv[u] + w)

一个事件必须等所有前置活动都完成才能发生 → 取最大值

2. ltv(反向,取最小)

复制代码
ltv[u] = min(ltv[v] - w)

一个事件不能拖累后续事件 → 取最小值

3. ete(活动最早开始)

复制代码
ete = etv[活动起点]

4. lte(活动最晚开始)

复制代码
lte = ltv[活动终点] - 活动耗时

三、判断关键活动

复制代码
ete == lte  →  该活动是关键活动

所有关键活动组成的路径就是 关键路径,决定了整个项目的最短工期。


四、计算步骤(四步法)

复制代码
1. 拓扑排序,得到拓扑序列
2. 正向遍历拓扑序,计算每个顶点的 etv
3. 反向遍历拓扑序,计算每个顶点的 ltv
4. 遍历每条边,计算 ete 和 lte,输出 ete == lte 的边

五、图解记忆

text 复制代码
      活动(边)
   u -----w----> v

   etv[u] 已知          etv[v] = max(etv[u] + w)
   ltv[u] = min(ltv[v] - w)   ltv[v] 已知

   ete = etv[u]
   lte = ltv[v] - w

六、代码骨架(Java)

java 复制代码
// 1. 正向:计算 etv
for (int u : topo) {
    for (Edge e : graph[u]) {
        etv[e.to] = Math.max(etv[e.to], etv[u] + e.w);
    }
}

// 2. 反向:计算 ltv
Arrays.fill(ltv, etv[n-1]);
for (int i = topo.size() - 1; i >= 0; i--) {
    int u = topo.get(i);
    for (Edge e : graph[u]) {
        ltv[u] = Math.min(ltv[u], ltv[e.to] - e.w);
    }
}

// 3. 输出关键活动
for (int u = 0; u < n; u++) {
    for (Edge e : graph[u]) {
        int ete = etv[u];
        int lte = ltv[e.to] - e.w;
        if (ete == lte) {
            System.out.println(u + " -> " + e.to);
        }
    }
}

七、一句话总结

etv 正向取最大,ltv 反向取最小
ete = etv起点,lte = ltv终点 - w
ete == lte 的活动,就是关键路径

八、课

相关推荐
snow@li8 分钟前
HikariCP:高性能数据库连接池全景深入梳理
java·数据库
edwarddamon43 分钟前
Spring Cloud 配置热更新与 Bean 代理机制梳理
java·后端
Raas1001 小时前
MAIGateway,魔芋企业级AI网关的FinAPI成本竞争力设计
java·后端·网关·api网关·魔芋ai·finapi·mai gateway
Ivanqhz1 小时前
php8 use-def链
算法·php
evans在进步2 小时前
Spring AI 从入门到实战:用 Java 实现大模型对话与 Tool Calling
java·人工智能·spring
evans在进步2 小时前
LeetCode 189 轮转数组:三次反转原地解决,图解 Java 实现
java·算法·leetcode
歌_顿2 小时前
Drawing_To_Model
算法
龍德明宇2 小时前
AI不会疼-龍德明宇
人工智能·算法·大语言模型llm·负主体性·ai存在论
302wanger3 小时前
程序员写 SOP:把脑子里的流程固化下来
算法
科学实验家3 小时前
完全背包
算法