AOE网与关键路径详解:概念、算法及代码实现
创作时间:
作者:
@小白创作中心
AOE网与关键路径详解:概念、算法及代码实现
引用
CSDN
1.
https://m.blog.csdn.net/weixin_45034895/article/details/143965927
1. 概念
AOE网(Activity On Edge Network):边表示活动的网。边是活动,顶点是事件(活动完成)。边带权,表示活动完成需要的时间。
源点:入度为0的点。
汇点:出度为0的点。
关键路径:从源点到汇点的最长路径。该路径的时间是整个工程完成的时间。
关键活动:关键路径上的活动。这些活动制约了工程的工期。
2. 关键路径算法
事件的最早发生时间:某个点k的ve(k)等于其前驱点加对应边权的最大值。表示该事件发生的最早时间。
ve(源点)=0
ve(k) = max{ve(i)+cost(i,k)}
事件的最晚发生时间:某个点k的vl(k)等于其后继点-对应边权的最小值,表示在不影响工期的前提下该事件发生的最晚时间。
vl(汇点) = ve(汇点)
vl(k) = min{vl(j) - cost(k, j)}
活动的最早发生时间:某条边i的最早发生事件为起点的事件的最早发生时间。
活动为(k, j),则 e(i) = ve(k)
活动的最晚发生时间:某条边i的最早发生事件为终点的事件的最迟发生时间减该边i的时间。
活动为(k, j),则 l(i) = vl(j) - cost(k, j)
3. 代码实现
3.1 关键路径
从源点求事件的最早发生时间ve->从汇点求事件的最晚发生时间vl->求活动的最早发生时间e->求活动的最晚发生时间l->找出e=l的边即为关键路径。
int n,m;
int G[N][N];//邻接矩阵
int in[N];//入度
int ve[N];//事件vk的最早发生时间
int vl[N];//事件vk的最晚发生时间
int ee[N];//活动ai的最早开始时间
int el[N];//活动ai的最晚开始时间
int Stack[N];//栈
struct Edge {
int x,y;
int dis;
Edge(){}
Edge(int x,int y,int dis):x(x),y(y),dis(dis){}
}edge[N];
bool vis[N];
void getVe(){//求ve
int cnt=0;
for(int i=1;i<=n;i++){
int k=-1;
for(int j=1;j<=n;j++){
if(in[j]==0){
Stack[++cnt]=j;
k=j;
in[j]=-1;
break;
}
}
for(int j=1;j<=n;j++){
if(G[k][j]!=INF){
ve[j]=max(ve[j],ve[k]+G[k][j]);
in[j]--;
}
}
}
}
void getVl(){//求vl
memset(vl,INF,sizeof(vl));
vl[Stack[n]]=ve[Stack[n]];
for(int i=n;i>=1;i--){
for(int j=1;j<=n;j++){
if(G[Stack[i]][j]!=INF) {
vl[Stack[i]]=min(vl[j]-G[Stack[i]][j],vl[Stack[i]]);
}
}
}
}
void getEe(){//求ee
for(int i=1;i<=m;i++)
ee[i]=ve[edge[i].x];
}
void getEl(){//求el
for(int i=1;i<=m;i++)
el[i]=vl[edge[i].y]-edge[i].dis;
}
void printEdge(){//以边输出
for(int i=1;i<=m;i++)
if(ee[i]==el[i])
printf("<%d,%d>:%d\n", edge[i].x, edge[i].y, edge[i].dis);
}
void printNode(){//以点输出
priority_queue<int,vector<int>,greater<int> > Q;
memset(vis,false,sizeof(vis));
for(int i=1;i<=m;i++){
if(ee[i]==el[i]){
int x=edge[i].x;
int y=edge[i].y;
if(!vis[x]){
Q.push(x);
vis[x]=true;
}
if(!vis[y]){
Q.push(y);
vis[y]=true;
}
}
}
while(!Q.empty()){
int temp=Q.top();
Q.pop();
printf("v%d ",temp);
}
}
int main() {
memset(G,INF,sizeof(G));
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int x,y,dis;
scanf("%d%d%d",&x,&y,&dis);
edge[i].x=x;
edge[i].y=y;
edge[i].dis=dis;
G[x][y]=dis;
in[y]++;
}
getVe();
getVl();
getEe();
getEl();
printf("以边输出:\n");
printEdge();
printf("以点输出:\n");
printNode();
return 0;
}
3.2 关键路径的长度
实际上求出ve,然后找打汇点的ve值就可以了
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
// 关键路径算法
int criticalPath(int n, vector<vector<int>>& edges) {
// 邻接表表示图
vector<vector<pair<int, int>>> graph(n);
// 入度数组
vector<int> inDegree(n, 0);
// 最长路径数组
vector<int> dist(n, 0);
// 建立图
for (const auto& edge : edges) {
int u = edge[0], v = edge[1], w = edge[2];
graph[u].emplace_back(v, w);
inDegree[v]++;
}
// 拓扑排序队列
queue<int> q;
// 将入度为0的节点加入队列
for (int i = 0; i < n; ++i) {
if (inDegree[i] == 0) {
q.push(i);
}
}
// 拓扑排序并计算最长路径
while (!q.empty()) {
int node = q.front();
q.pop();
for (const auto& neighbor : graph[node]) {
int v = neighbor.first;
int weight = neighbor.second;
// 更新最长路径
dist[v] = max(dist[v], dist[node] + weight);
// 入度减1
inDegree[v]--;
// 如果入度为0,加入队列
if (inDegree[v] == 0) {
q.push(v);
}
}
}
// 找到最长路径的长度
return *max_element(dist.begin(), dist.end());
}
int main() {
// 示例输入:节点数量和边
int n = 6;
vector<vector<int>> edges = {
{0, 1, 3}, {0, 2, 2}, {1, 3, 2}, {2, 3, 4},
{3, 4, 2}, {3, 5, 3}, {4, 5, 1}
};
int result = criticalPath(n, edges);
cout << "关键路径的长度为: " << result << endl;
return 0;
}
热门推荐
佟丽娅带娃进剧组体验乡村生活,演绎另类“见世面”
桑叶:秋冬养生的天然良方
珠海临时身份证办理攻略:珠海公安&粤省事
珠海临时身份证办理全攻略:线上预约+现场办理,一文掌握!
殷墟博物馆新馆开馆:3000件文物首次亮相,再现商代文明
金荞麦胶囊长期使用会有哪些危害?医生提醒:这4点要注意
金荞麦胶囊的功效与使用注意事项
凝血酶原时间检查:11-15秒是关键,异常解读看这里
《北京爱情故事》主演分手:当理想照进现实
宝马闭店,BBA销量断崖下跌,进口车为何集体“失速”?
别再被骗了,红糖不补血!它最大的好处有两个,没几个人知道
国产宝马和进口宝马的区别:价格、质量与选择指南
重返价格战,宝马反悔了
太突然,宝马首家5S店关门,“提不了车,也不给退钱”
白砂糖和红糖哪个营养价值高?红糖比白糖更营养?答案让人意外!
生活中的“减糖”核心信息
5岁后仍尿床怎么办?专家详解病因、危害与应对策略
儿童尿床莫轻视:五大误区家长需警惕
5岁后还尿床怎么办?专家解析原因并提供治疗方案
5岁以上还在尿床?这种常见儿童疾病有科学解决方案
5岁后还尿床怎么办?专家建议从这三方面入手
5岁以上孩子还尿床?遗尿症识别与专业治疗指南
专家:5岁以上儿童频繁尿床需重视,中医调治有良方
海运国际小包实用指南:价格表+寄送流程详解
哪些食物是天然“二甲双胍”,糖友坚持吃,血糖悄悄降!
体检发现“蛋白尿”一定是肾脏出现问题了吗?
尿蛋白高是什么原因引起的
尿蛋白高饮食应该注意什么
告别童装尺码困扰:这份详细对照表请收好
秋季养生神器:玉竹、桑叶和葛根