AOE网的关键路径的计算

简介: 求关键路径,只需理解顶点(事件)和边(活动)各自的两个特征属性以及求法即可:    Ø  先根据首结点的Ve(j)=0由前向后(正拓扑序列)计算各顶点的最早发生时间    Ø  再根据终结点的Vl(j)等于它的Ve(j)由后向前(逆序拓扑)依次求解各顶点的最晚发生时间    Ø  根据边的...

求关键路径,只需理解顶点(事件)和边(活动)各自的两个特征属性以及求法即可:

   Ø  先根据首结点的Ve(j)=0由前向后(正拓扑序列)计算各顶点的最早发生时间

   Ø  再根据终结点的Vl(j)等于它的Ve(j)由后向前(逆序拓扑)依次求解各顶点的最晚发生时间

   Ø  根据边的ee(i)等于它的发出顶点的Ve(j)计算各边的最早开始时间(最早开始,对应最早发生)

   Ø  根据边的ll(i)等于它的到达顶点的Vl(j)减去边的权值计算各边的最晚开始时间(最晚开始,对应最晚发生)

#include<iostream>
#include
<cstring> #include<cstdio> #include<cstdlib> #include<vector> #include<stack> #define MAX_NODE_NUM 100 using namespace std; int first[MAX_NODE_NUM]; typedef struct EDGE{ int u, v, w; int nextarc; EDGE(){ } EDGE(int u, int v, int w, int nextarc){ this->u = u; this->v = v; this->w = w; this->nextarc = nextarc; } } edge; vector<edge> g; stack<int> s, t;//s存储入度为零的节点, t存储图的拓扑序列的顶点栈 int ve[MAX_NODE_NUM];//事件的最早发生时间, 或者 活动ai的最早发生时间 int vl[MAX_NODE_NUM];//事件的最晚发生时间 int degIn[MAX_NODE_NUM];//记录每一个节点的入度 int tag[MAX_NODE_NUM][MAX_NODE_NUM]; int n, m;//分别为图的节点的个数,和边的个数 bool topoSort(){ memset(ve, 0, sizeof(ve)); int cnt = 0;//记录 for(int i=1; i<=n; ++i) if(degIn[i] == 0) s.push(i); while(!s.empty()){ int u = s.top(); s.pop(); t.push(u); ++cnt; for(int e=first[u]; ~e; e=g[e].nextarc){ int v = g[e].v; int w = g[e].w; if(--degIn[v] == 0) s.push(v); if(ve[u] + w > ve[v]) ve[v] = ve[u] + w; } } if(cnt < n) return false;//该有向图存在回路 return true; } bool criticalPath() {//寻找关键路径 if(!topoSort()) return false; for(int i=1; i<=n; ++i) vl[i] = ve[t.top()]; while(!t.empty()){//逆序拓扑排序,计算每个节点的最晚的发生时间 int u = t.top(); t.pop(); for(int e=first[u]; ~e; e=g[e].nextarc){ int v = g[e].v; int w = g[e].w; if(vl[v] - w < vl[u]) vl[u] = vl[v] - w; } } for(int i=1; i<=n; ++i){//输出关节点 int ee = ve[i];//活动ai的最早的发生时间 for(int e=first[i]; ~e; e=g[e].nextarc) { int v = g[e].v; int w = g[e].w; int ll = vl[v]-w;//活动ai的最晚的发生时间 ll == ee ? printf(" * ") : printf(" "); printf("%d %d %d %d %d\n", i, v, w, ee, ll);//分别为 u, v, w(这条边所对应的活动), 活动最早发生时间和最晚发生时间 } } return true; } void dfs(int u){ for(int e=first[u]; ~e; e=g[e].nextarc) { int ee = ve[u]; int v = g[e].v; int w = g[e].w; dfs(v); if(tag[u][v]) continue; tag[u][v] = 1; if(vl[v]-w < vl[u]) vl[u] = vl[v]-w; int ll = vl[v]-w;//活动au的最晚的发生时间 ll == ee ? printf(" * ") : printf(" "); printf("%d %d %d %d %d\n", u, v, w, ee, ll); } } bool criticalPathx() {//寻找关键路径,利用dfs可以 if(!topoSort()) return false; for(int i=1; i<=n; ++i) vl[i] = ve[t.top()]; dfs(1);//默认1节点为源点 } void addEdge(int u, int v, int w){ edge e(u, v, w, first[u]); first[u] = g.size(); g.push_back(e); } int main(){ printf("请输入图的节点的个数和边的个数:\n"); scanf("%d%d", &n, &m); memset(first, -1, sizeof(first)); while(m--){ int u, v, w; scanf("%d %d %d", &u, &v, &w); addEdge(u, v, w); ++degIn[v]; } //criticalPath(); /*输出结果: * 1 3 2 0 0 1 2 3 0 1 2 4 2 3 4 2 5 3 3 4 3 6 3 2 5 * 3 4 4 2 2 * 4 6 2 6 6 5 6 1 6 7 */ criticalPathx(); /*输出结果: 3 6 3 2 5 * 4 6 2 6 6 * 3 4 4 2 2 * 1 3 2 0 0 2 4 2 3 4 5 6 1 6 7 2 5 3 3 4 1 2 3 0 1 */ return 0; }

输入数据:

6 8
1 2 3
2 5 3
5 6 1
2 4 2
4 6 2
3 4 4
1 3 2
3 6 3

 

 

目录
相关文章
|
存储 NoSQL 前端开发
jwt与redis,把生成的token放入redis中进行临时存储
jwt与redis,把生成的token放入redis中进行临时存储
968 0
|
Ubuntu Java Linux
alpine Linux与基于alpine制作JDK8镜像
Docker commit 命令 1.下载基础镜像 2.使用此基础镜像创建/启动/进入容器 3.在容器安装自己需要的软件 4.将保存配置完成的容器提交成镜像 语法如下 docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] OPTIONS说明: -a :提交的镜像作者; -c :使用Dockerfile指令来创建镜像; -m :提交时的说明文字; -p :在commit时,将容器暂停。 实例:将容器a404c6c174a2 保存为新的镜像,并添加提交人信息和说明
|
数据可视化 Java uml
IDEA这个功能真强大!一键把整个项目代码绘制成UML类图...
IDEA这个功能真强大!一键把整个项目代码绘制成UML类图...
5656 0
IDEA这个功能真强大!一键把整个项目代码绘制成UML类图...
|
存储 人工智能 移动开发
HTML5 游戏开发实战 | 五子棋
五子棋是一种家喻户晓的棋类游戏,它的多变吸引了无数的玩家。本章首先实现单机五子棋游戏(两人轮流下),而后改进为人机对战版。整个游戏棋盘格数为 15×15,单击鼠标落子,黑子先落。在每次下棋子前,程序先判断该处有无棋子,有则不能落子,超出边界不能落子。任何一方有横向、竖向、斜向、反斜向连到 5 个棋子则胜利。
23971 8
HTML5 游戏开发实战 | 五子棋
|
9月前
|
存储 人工智能 算法
C 408—《数据结构》算法题基础篇—数组(通俗易懂)
408考研——《数据结构》算法题基础篇之数组。(408算法题的入门)
567 23
|
存储 安全 C语言
C语言 二级指针应用场景
本文介绍了二级指针在 C 语言中的应用,
|
机器学习/深度学习 人工智能 数据可视化
号称能打败MLP的KAN到底行不行?数学核心原理全面解析
Kolmogorov-Arnold Networks (KANs) 是一种新型神经网络架构,挑战了多层感知器(mlp)的基础,通过在权重而非节点上使用可学习的激活函数(如b样条),提高了准确性和可解释性。KANs利用Kolmogorov-Arnold表示定理,将复杂函数分解为简单函数的组合,简化了神经网络的近似过程。与mlp相比,KAN在参数量较少的情况下能达到类似或更好的性能,并能直观地可视化,增强了模型的可解释性。尽管仍需更多研究验证其优势,KAN为深度学习领域带来了新的思路。
5835 5
|
数据可视化 网络安全 Windows
下载安装MobaXterm并链接服务器的操作方法
【2月更文挑战第13天】本文介绍在Windows电脑中,下载、配置MobaXterm软件,从而连接、操作远程服务器的方法~
1332 2
下载安装MobaXterm并链接服务器的操作方法
|
XML JSON 监控
深入解析JMeter HTTP 请求头:实战技巧
在深入研究 JMeter 的过程中,任何涉及性能测试或接口验证的专业人员都会认识到,合理配置HTTP请求头部信息是实现精确测试的关键步骤之一。不同情景下,如数据提交形式的不同(例如 JSON、XML 等),或是需要通过 HTTP 头传递特定的认证信息(如使用 JWT 或 OAuth 2.0 令牌)时,了解如何在 JMeter 中灵活设置请求头显得尤为重要。
|
Java 数据库连接 容器
web后端-SSM快速了解和架构介绍
web后端-SSM快速了解和架构介绍