关键路径问题的C++实现:从理论到代码详解
创作时间:
作者:
@小白创作中心
关键路径问题的C++实现:从理论到代码详解
引用
CSDN
1.
https://blog.csdn.net/2301_79822831/article/details/140069528
关键路径问题在项目管理和软件工程中具有重要应用,它帮助我们确定项目中最关键的活动序列,从而确保项目按时完成。本文将通过C++代码实现,详细介绍关键路径问题的算法原理和具体实现步骤。
介绍
关键路径是项目网络图中一系列代表最长任务序列的活动或任务,这些任务决定了项目的最短完成时间。任何关键路径上的活动的延迟都会导致整个项目的延迟。因此,项目管理人员会特别关注关键路径上的活动,以确保项目按时完成。
大体思路
- 理解AOE网络:
- AOE网络(Activity On Edges)是一个有向无环图(DAG),其中顶点表示事件(event),有向边表示活动(activity),边上的权值表示活动的持续时间。
- 计算最早发生时间(ve):
- 从起始节点开始,按照拓扑排序的顺序,计算每个节点的最早发生时间。对于每个节点,其最早发生时间为其所有前置节点(通过有向边指向该节点的节点)的最早发生时间中的最大值加上当前边的权值。
- 初始时,起始节点的最早发生时间设为0。
- 计算最迟发生时间(vl):
- 从终止节点开始,逆着拓扑排序的顺序,计算每个节点的最迟发生时间。对于每个节点,其最迟发生时间为其后继节点(由该节点通过有向边指向的节点)的最迟发生时间中的最小值减去当前边的权值。
- 初始时,终止节点的最迟发生时间等于其最早发生时间加上从该节点到终止节点的最长路径长度。
- 确定关键活动:
- 对于每条边(活动),如果其最早开始时间等于其最晚开始时间,则该活动为关键活动。
- 关键活动构成了关键路径,即从起始节点到终止节点具有最大路径长度的路径。
- 优化项目时间:
- 缩短关键路径上的关键活动时间可以缩短整个项目的完成时间。
- 如果有多条关键路径,需要同时缩短这些路径上的关键活动时间,以有效缩短整个项目的周期。
实现步骤
1.0结构体等定义
2.0 (拓扑排序)
目的是为了求活动实现路径,同时在其中顺便将vet(最早发生时间)数组求出。
3.0 核心算法
这个算法中,根据topo求出的路径,先初始化vlt(最晚发生时间)数组为抽象最大值,然后把vlt[vexnum-1]赋为vet[vexnum-1],这个必不可少,因为他是接下来逆拓扑排序求vlt数组的起点。求出vlt数组后,for循环遍历所有边,寻找余量为0活动(余量为0,也就对映关键活动。可以理解为现实中的容错时间,或者说“墨迹时间”)。eet最早开始时间,elt是最晚开始时间。两者相减即为余量。最后打印。
源代码
#include<stack>
#include<iostream>
#include<vector>
using namespace std;
const int MAX = 1e5+10;
int vexnum,arcnum;
//最早发生时间,最晚发生时间
int vet[MAX] = {0}, vlt[MAX];
struct EdgeNode{
int adjvex;
int value;
EdgeNode*nextarc;
};
struct VexNode{
int indegree;
EdgeNode*firstarc;
};
VexNode Vex[MAX];
bool TopoSort(vector<int>&topo){
stack<int>stack;
for(int i = 0;i < vexnum;i++){
if(Vex[i].indegree == 0){
stack.push(i);
}
}
while(!stack.empty()){
int top = stack.top();
stack.pop();
topo.push_back(top);
for(EdgeNode*p = Vex[top].firstarc;p!=nullptr;p = p->nextarc){
int end = p ->adjvex;
if(!(--Vex[end].indegree)){
stack.push(end);
}
if(vet[top]+p->value > vet[end]){
vet[end] = vet[top]+p->value;
}
}
}
if(int(topo.size())<vexnum){
return false;
}
return true;
}
void CriticalPath(){
std::vector<int>topo;
TopoSort(topo);
for(int i=0;i<vexnum;i++){
vlt[i] = MAX;//********************* */
}
// vlt[topo[0]] = 0;/*非必要,代码逻辑最后可以计算出来 */
//逆向求vlt值
vlt[vexnum-1] = vet[vexnum-1];//*************************** */
for(int i = topo.size()-2;i>=0;i--){
int pre = topo[i];
for(EdgeNode*p = Vex[pre].firstarc;p!=nullptr;p = p->nextarc){
int end = p->adjvex;
if(vlt[end] - p->value <vlt[pre]){
vlt[pre] = vlt[end] - p->value;
}
}
}
std::cout << "The following is the critical path" << std::endl;
for(int i = 0;i<vexnum;i++){///-------------------------------
for(EdgeNode*p = Vex[i].firstarc;p!=nullptr;p = p->nextarc){
int end = p->adjvex;
int eet = vet[i];
int elt = vlt[end] - p->value;
if(eet == elt){
std::cout << "v"<<i<<"-->"<<"v"<<end<<"=="<<p->value<<std::endl;
}
}
}
}
int main()
{
std::cout <<"please input the nodenum and arcnum : ";
std::cin >> vexnum>>arcnum;
for(int i = 0;i<arcnum;i++){
int x,y,z;//弧尾,弧头,权重
std::cin >> x>>y>>z;
Vex[y].indegree++;
EdgeNode*p = new EdgeNode;
p->adjvex = y;
p->value = z;
p->nextarc = Vex[x].firstarc;
Vex[x].firstarc = p;
}
CriticalPath();
//
// 6 8
// 1 2 3
// 1 3 2
// 3 4 4
// 4 6 2
// 2 5 3
// 2 4 2
// 3 6 3
// 5 6 1
return 0;
}
热门推荐
20年收藏家教你:5种方法辨别绿松石真伪
从权力象征到唐卡颜料:绿松石与藏传佛教的千年因缘
二仙丸治疗冬季风湿性关节炎,临床验证安全有效
二仙丸的功效与禁忌:补肝益肾的传统中药制剂
摔跤冠军的三大秘诀:姿态、技巧、心理
股市国家队最新动向:规模回升至3.8万亿元,理性看待减持
2025年开年A股大幅波动,国家队300亿ETF操作稳定市场
国家队增持ETF超2500亿,创业板估值优势显现,机构看好春季行情
万亿资金护盘,解密证金公司市场稳定机制
美联储降息50个基点,中国LPR报价为何岿然不动?
心理健康,内外兼修的魅力
秋日户外活动,让你魅力升级
奥硝唑优于甲硝唑:药效强、持续久、安全性高
研究证实:奥硝唑治疗厌氧菌感染效果优于甲硝唑
拒绝敏感性:为何我们如此惧怕被拒?
法式马卡龙
上海多家老字号变身“长者餐厅”,老人用餐享受专属优惠
扒龙船、祭盘瓠:怀化六县市上演500队龙舟竞渡
黄穗平教授教你正确食用山东阿胶
阿胶一周吃几次最合适?
秋冬进补,阿胶怎么吃才科学?
揭秘《复仇者联盟》:AI特效如何打造震撼人心的视觉盛宴
物价温和回升折射经济态势,政策加力护航供需平衡
2024年企业火灾敲警钟,系统消防培训成安全关键
ABC干粉灭火器:提拔握压四步使用法
南京火灾后,家用灭火器选购与使用全攻略
“罢黜百家,独尊儒术”:董仲舒奠定汉代思想一统
济宁政德学院创新“四位一体”教学法,成全国干部培训重要基地
世界肥胖日:全球糖尿病患者超8亿,专家解析科学饮食管理方案
赛黄晶:能量提升与养生调理的稀世宝石