关键路径求解
基于CPN的求解关键路径的新方法

l 引言
关键 路径法( C r i t i c a l P a t h Me ho t d , C P M) [ I J 最早出 现于 2 O世纪 5 0年代,它是通过分析 项 目过程 中哪个
使用 关键路径法成了一个瓶Байду номын сангаас 问题. 而 且, 在有些情况
下,从 同一个 工程 出发到达 另外一个工程可 能有多个 选择, 也就是所 谓的环路或回路 问题, 对于这种问题从 根本上 是无法求解其 关键路径 的,而且现在存 在 的算 法大 多 由于无法解 决这个 问题 因此避 而不谈,但这种
he t s o rc u e t o s i n k . I n h t e me a n t i me , w e g e t a l l h t e t i me h t a t a l l r e a c h a b l e p a t h s h a v e c o n s u m e ,a d nd he t b i g g e s t t i me i s
C P N ( C o l o r e d P e u i Ne t s ) 模 型不 合理 的地方进行合理性 的修 改. 再利用编 写的函数求出从源 点到汇 点的所有 的可 达路径,在获得所有 可达 路径的 同时也获取 了所有 可达路径所花 费的时间,那么时 间最大的就是关键路径.该方
法不仅简 便直观,而且能够在保证 正确 性合理性的前提 下提 高执 行效率, 减 小时间复杂度.
关键词 : 关键路径;颜色 P e t r i 网;消息序列 图;时间复杂度;状态空间
A Ne w Me t h o d f o r F i n d i n g t h e Cr i t i e a l P a t h s Ba s e d o n Co l o r e d Pe t r i Ne t s
项目管理的关键路径公式

项目管理的关键路径公式
项目管理的关键路径(Critical Path)是项目计划中耗时最长、对项目总时间影响最大的路径,它决定了项目的总持续时间。
关键路径的确定主要基于以下公式:
1. 任务持续时间:每个任务都有一个预计的完成时间。
这是从任务开始到结束所需的总时间。
2. 任务之间的逻辑关系:任务之间可能存在先后关系,这决定了任务执行的顺序。
这些逻辑关系可以用“AND”或“OR”关系表示。
3. 计算路径的总时间:对于每条路径(即一系列任务的执行顺序),需要计算其总时间。
这可以通过将路径上所有任务的时间相加来完成。
4. 确定关键路径:具有最长总时间的路径是关键路径。
关键路径上的任何延迟都会直接影响项目的总完成时间。
在实际的项目管理软件中,例如Microsoft Project,这些计算通常是自动完成的,项目经理只需要输入每个任务的时间和它们之间的逻辑关系,软件就会自动找出关键路径。
然而,如果你需要手动计算,你通常会使用表格或电子表格程序(如Excel)来列出所有任务和它们的时间,然后通过逻辑关系和简单的数学运算(加法)来找出关键路径。
关键路径算法

(4)根据各顶点的ve和vl值,求每条弧s的最早开 始时间e(s)和最迟开始时间 l(s)。若某条弧满足条 件e(s)=l(s),则为关键活动。
先将拓扑排序算法7.12改写成算法7.13,则算法 7.14便为求关键路径的算法。
typedef float AdjType;
typedef struct ArcNode
{ int adjvex;
/* 相邻顶点字段 */
AdjType weight; struBiblioteka t ArcNode *nextarc;
/* 链字段 */
}ArcNode;
/* 边表中的结点 */
&top)
{ int k;
while(p)
/* 删除以该顶点为起点的边 */
{ k=p->adjvex;
indegree[k]--;
if(indegree[k]==0) /* 将新的入度为零的边 入栈 */
{ indegree[k]=top;
top=k;
}
p=p->nextarc;
p=p->nextarc;
}
}
}
void countvl(ALGraph G,int *topo,AdjType *ve, AdjType *vl) /* 计算各事件的最迟发生时间*/
{ int i,j,k; ArcNode *p; for(i=0;i<G.vexnum;i++) //求事件vi允许的最迟发生时间vl(i) vl[i]=ve[G.vexnum-1]; /*每个事件的最迟发生时间赋初值
关键路径法--计算方法

关键路径法--计算方法关键路径法定义关键路径法(Critical Path Method, CPM)是一种基于数学计算的项目计划管理方法,是网络图计划方法的一种,属于肯定型的网络图。
关键路径法将项目分解成为多个独立的活动并确定每个活动的工期,然后用逻辑关系(结束-开始、结束-结束、开始-开始和开始结束)将活动连接,从而能够计算项目的工期、各个活动时间特点(最早最晚时间、时差)等。
在关键路径法的活动上加载资源后,还能够对项目的资源需求和分配进行分析。
关键路径法是现代项目管理中最重要的一种分析工具。
关键路径法的分类根据绘制方法的不同,关键路径法可以分为两种,即箭线图(ADM)和前导图(PDM)。
箭线图(ADM)法又称为双代号网络图法,它是以横线表示活动而以带编号的节点连接活动,活动间可以有一种逻辑关系,结束-开始型逻辑关系。
在箭线图中,有一些实际的逻辑关系无法表示,所以在箭线图中需要引入虚工作的概念。
绘制箭线图时主要有以下一些规则:1、在箭线图(ADM)中不能出现回路。
如上文所述,回路是逻辑上的错误,不符合实际的情况,而且会导致计算的死循环,所以这条规则是必须的要求。
2、箭线图(ADM)一般要求从左向右绘制。
这虽然不是必须的要求,但是符合人们阅读习惯,可以增加箭线图(ADM)的可读性。
3、每一个节点都要编号,号码不一定要连续,但是不能重复,且按照前后顺序不断增大。
这条规则有多方面的考虑,在手工绘图时,它能够增加图形的可读性和清晰性,另外,在使用计算机运行箭线图(ADM)这一条就非常重要,因为在计算机中一般通过计算节点的时间来确定各个活动的时间,所以节点编号不重复是必须的。
4、一般编号不能连续,并且要预留一定的间隔。
主要是为了在完成的箭线图(ADM)中可能需要增加活动,如果编号连续,新增加活动就不能满足编号由小到大的要求。
5、表示活动的线条不一定要带箭头,但是为了表示的方便,一般推荐使用箭头。
这一条主要是绘制箭线图(ADM)时可以增加箭线图(ADM)的可读性。
关键路径法简洁的方法

1、ES:最早开始时间(earliest start time)是指某项活动能够开始的最早时间。
2、EF:最早结束时间(earliest finish time)是指某项活动能够完成的最早时间。
EF=ES+工期估计规则:某项活动的最早开始时间=直接指向这项活动的最早结束时间中的最晚时间。
正向推出取最大值。
3、LF:最迟结束时间(latest finish time)是指为了使项目在要求完工时间内完成,某项活动必须完成的最迟时间。
4、LS:最迟开始时间(latest start time)是指为了使项目在要求完工时间内完成,某项活动必须开始的最迟时间。
LS=LF-工期估计规则:某项活动的最迟结束时间=该活动直接指向的所有活动(紧后活动)最迟开始时间的最早(小)时间。
(LS和LF通过反向推出取最小值)3、TF:总时差(用TFi-j表示),双代号网络图时间计算参数,指一项工作在不影响总工期的前提下所具有的机动时间。
用工作的最迟开始时间LSi-j与最早开始时间ESi-j之差表示。
也等于工作的最迟完成时间LFi-j - 工作的最早完成时间EFi-j(当前节点,本工作)总时差TF=最迟开始时间LS-最早开始时间ES(开始-开始)总时差TF=最迟完成时间LF-最早完成时间EF(完成-完成)延误小于总时差不会影响工期TF=LS-ES=LF-EF4、FF:自由时差,指一项工作在不影响后续工作的情况下所拥有的机动时间。
是研究本工作与紧后工作的关系。
自由时差FF=紧后工作的最早开始时间ES-本工作的最早完成时间EFFF=ES(后一节点)-EF(当前工作)以网络计划的终点节点为箭头节点的工作,其:自由时差FF=计划工期-本工作最早完成时间EF延期超过自由时差,会影响其紧后工作的最早开始时间。
注意:最早,从前向后,先算出最早开始时间ES,加上持续时间,就是最早完成时间EF。
最迟,从后向前,先算出最迟完成时间LF,减去持续时间,就是最迟开始时间LS。
关键路径计算简单例题讲解

关键路径计算简单例题讲解关键路径计算简单例题讲解计划是人类行动的基础。
对于工程项目而言,计划更是必不可少的。
关键路径方法(CPM)是一种重要的工程计划方法,通过分析一个项目中所有任务之间的时间关系和依赖关系,确定整个项目的关键路径,从而实现对项目时间进度和资源的控制。
本文通过一个简单的例子来介绍如何计算关键路径。
1. 建立项目网络图首先,我们需要根据项目的任务及其完成顺序,建立项目网络图。
以项目“完成一篇短文”为例,该项目包括5个任务:主题确定、资料搜集、草稿写作、文章修改和定稿。
它们的完成顺序如下:主题确定-----> 资料搜集-----> 草稿写作-----> 文章修改-----> 定稿在建立项目网络图时,需要将各个任务用活动节点(A)表示,在每个活动节点上标明活动的名称;同时,需要使用箭头(Arrow)表示各个任务之间的联系,即需要完成一个任务才能开始下一个任务。
在箭头上标明任务之间的时间。
例如,主题确定任务需要1天完成,那么从主题确定的活动节点向资料搜集的活动节点画一条箭头并在箭头上标明时间为1天。
如此,可以完成整个项目的网络图绘制。
2. 确定活动的持续时间接下来,我们需要确定每个活动的最短时间,即该活动所需的最小时间。
以“完成一篇短文”为例,各个活动的持续时间如下:主题确定(1天)-----> 资料搜集(3天)-----> 草稿写作(2天)-----> 文章修改(2天)-----> 定稿(1天)3. 计算最早开始时间和最晚开始时间计算最早开始时间和最晚开始时间是确定关键路径的重要一步。
在这一步中,我们需要确定任务的开始时间和结束时间。
其中,最早开始时间是指一个任务开始的最早时间,最晚开始时间是指一个任务可以推迟的最晚时间,而不影响项目的整体完成时间。
以“完成一篇短文”为例,我们可以算出各个任务的最早开始时间和最晚开始时间如下表所示:任务名称最早开始时间最晚开始时间主题确定 0 0资料搜集 1 4草稿写作 4 4文章修改 6 6定稿 8 84. 计算总时差和自由时差最后,我们需要计算总时差和自由时差,从而确定关键路径。
数据结构——手工求解关键路径

数据结构——⼿⼯求解关键路径这⾥先回顾⼀下⼏个概念:AOE⽹AOE⽹是活动在边上的⽹(Activity On Edge network,AOE)的英⽂简称。
AOE⽹是⽤有向图来表⽰的,在有向图中,边表⽰活动,边具有权值,边的权值代表了活动的持续时间。
顶点表⽰事件,事件是图中新活动开始或者旧活动结束的标识。
与AOV⽹相同的是,AOE⽹也是有向⽆环图,不同的是在AOV⽹中顶点表⽰活动,边⽆权值,边代表活动之间的先后关系。
对于⼀个表⽰⼯程的AOE⽹,只存在⼀个⼊度为0的顶点,成为源点,表⽰整个⼯程的开始;也只有⼀个出度为0的顶点,称为汇点,表⽰整个⼯程的结束。
关键路径在AOE⽹中,从源点到汇点的所有路径中,具有最⼤路径长度的路径成为关键路径。
关键路径所代表的时间就是完成整个⼯期的最短时间。
关键路径上的活动(边)称为关键活动。
事件最早发⽣时间ve(k)设ve(k)代表事件(顶点)k的最早发⽣时间,即从源点到顶点k的路径中的最长者,即ve(k)=max{ve(j)+<j,k>},其中j为k的前驱事件,且j可能有多个。
初始时,将源点事件的最早发⽣时间ve(0)设置为0。
事件最晚发⽣时间vl(k)设vl(k)代表事件(顶点)k的最晚发⽣时间,即在不推迟整个⼯程完成的前提下,事件k最迟必须发⽣的时间,即vl(k)=min{vl(j)-<k,j>},其中j 为k的后继事件,j可能有多个。
对于汇点时间来说,它的最早发⽣时间是整个⼯程的结束时间,因此他的最早发⽣时间也是最迟发⽣时间,即初始时将汇点事件的最晚发⽣时间vl(n)设置为ve(n)。
活动最早发⽣时间e(i)设e(ak)代表当前活动(边)ak的最早发⽣时间,由于事件代表⼀个新活动的开始或⼀个旧活动的结束,因此事件的最早发⽣时间就是有这个事件所发出的活动的最早时间。
即若存在边ak1:<i,j>,ak2:<k,j>,则e(ak1)=e(ak2)=ve(i)。
求关键路径的简单方法

求关键路径的简单方法引言在项目管理中,关键路径是指项目中最长的路径,决定了项目的最短完成时间。
关键路径分析是项目管理中的一项重要技术,通过确定关键路径可以帮助项目团队合理安排资源和时间,保证项目按时完成。
本文将介绍求关键路径的简单方法,帮助读者理解和应用该技术。
什么是关键路径关键路径是指在项目网络图中,连接起始事件和结束事件的路径,该路径上的活动都是项目的关键活动,其总时差为0。
关键路径决定了整个项目的最短完成时间,如果关键路径上的任何一个活动延误,整个项目的完成时间都会延误。
活动的时差在关键路径分析中,活动的时差是指活动的最早开始时间与最晚开始时间之差。
如果一个活动的最早开始时间等于最晚开始时间,则该活动为关键活动,对项目的完成时间有直接影响。
求关键路径的简单方法求关键路径的简单方法包括以下几个步骤:步骤一:绘制项目网络图首先,需要将项目的活动及其依赖关系绘制成网络图。
网络图由节点和箭头组成,节点表示活动,箭头表示活动之间的依赖关系。
步骤二:确定活动的持续时间对于每个活动,需要确定其持续时间。
持续时间是指完成该活动所需的时间,可以根据历史数据或专家判断进行估算。
步骤三:计算最早开始时间(ES)和最晚开始时间(LS)根据活动的依赖关系和持续时间,可以计算出每个活动的最早开始时间(ES)和最晚开始时间(LS)。
最早开始时间(ES)是指在没有任何限制的情况下,活动可以开始的最早时间。
对于起始事件,其最早开始时间为0。
对于其他活动,其最早开始时间等于前置活动的最早开始时间加上前置活动的持续时间。
最晚开始时间(LS)是指在不影响项目完成时间的前提下,活动可以开始的最晚时间。
对于结束事件,其最晚开始时间等于项目的最早完成时间。
对于其他活动,其最晚开始时间等于后继活动的最晚开始时间减去自身的持续时间。
步骤四:计算总时差(TF)总时差(TF)是指活动的最晚开始时间减去最早开始时间,即LS减去ES。
总时差表示了活动的弹性,即该活动可以延误的时间。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构中关键路径算法的实现与应用摘要介绍求关键路经的算法,对于给出的事件结点网络,要求求出从起点到终点的所有路径,经分析、比较后找出长读最大的路径,从而得出求关键路径的算法,并给出计算机上机实现的源程序。
关键词关键路径最少时间1:引言通常把计划、施工过程、生产流程、程序流程的都当成一个工程。
除了很小的工程外、一般都把工程分为若干个叫做“活动”的子工程。
完成了这些“活动”的子工程,这个工程就可以完成了。
通常我们用有向图表示一个工程。
在这种有向图中,用顶点表示活动,用有向边<Vi,Vj>表示活动Vi必须先于活动Vj进行。
如果在无有向环的带权有向图中用有向边表示一个工程中的各项活动(ACTIVITY),用有向边上的权值表示活动的持续时间(DURATION),用顶点表示事件(EVENT),则这种的有向图叫做用边表示活动的网络,简称AOE(active on edges)网络。
AOE网络在某些工程估算方面非常有用。
他可以使人们了解:(1):研究某个工程至少需要多少时间?(2):那些活动是影响工程进度的关键?在AOE网络中,有些活动可以并行的进行。
从源点到各个顶点,以至从源点到汇点的有向路径可能不止一条。
这些路径的长度也可能不同。
完成不同路径的活动所需的时间虽然不同,但只有各条路径上所有活动都完成了,这个工程才算完成。
因此,完成整个工程所需的时间取决于从源点到汇点的最长路径长度,即在这条路径上所有活动的持续时间之和。
这条路径长度就叫做关键路径(criti cal path)。
2:设计步骤:1: 以某一工程为蓝本,采用图的结构表示实际的工程计划的时间。
2: 调查以分析和预测这个工程计划个阶段的时间。
3: 用调查的结果建立AOE网(Activity On Edge Network),即边表示活动的网络,并用图的形式表示。
4: 用图来存储这些信息。
5: 用CreateGraphic();函数建立AOE图。
6: 用SearchMapPath();函数求出最大路径,并打印出关键路径。
7:编写代码8: 测试3: 设计代码:#include<stdio.h>#include<stdlib.h>#include<iomanip.h>#include <process.h>//#define PROJECTNUMBER 9//10//#define PLANNUMBER 11//13typedef struct node{int adjvex;int dut;struct node *next;}edgenode;typedef struct{int projectname;int id;edgenode *link;}vexnode;//vexnode Graphicmap[PROJECTNUMBER];void CreateGraphic(vexnode* Graphicmap,int projectnumber,int activenu mber){int begin,end,duttem;edgenode *p;for(int i=0;i<projectnumber;i++){Graphicmap[i].projectname=i;Graphicmap[i].id =0;Graphicmap[i].link =NULL;}printf("某项目的开始到结束在图中的节点输入<vi,vj,dut>\n");printf("如:3,4,9 回车表示第三节点到第四节点之间的活动用了9个单位时间\n");for(int k=0;k<activenumber;k++){scanf("%d,%d,%d",&begin,&end,&duttem);p=(edgenode*)malloc(sizeof(edgenode));p->adjvex =end-1;p->dut =duttem;Graphicmap[end-1].id ++;p->next =Graphicmap[begin-1].link ;Graphicmap[begin-1].link =p;}}int SearchMapPath(vexnode* Graphicmap,int projectnumber,int activenum ber,int& totaltime){int i,j,k,m=0;int front=-1,rear=-1;int* topologystack=(int*)malloc(projectnumber*sizeof(int));//用来保存拓扑排列int* vl=(int*)malloc(projectnumber*sizeof(int));//用来表示在不推迟整个工程的前提下,VJ允许最迟发生的时间int* ve=(int*)malloc(projectnumber*sizeof(int));//用来表示Vj最早发生时间int* l=(int*)malloc(activenumber*sizeof(int));//用来表示活动A i最迟完成开始时间int* e=(int*)malloc(activenumber*sizeof(int));//表示活动最早开始时间edgenode *p;totaltime=0;for(i=0;i<projectnumber;i++) ve[i]=0;for(i=0;i<projectnumber;i++){if(Graphicmap[i].id==0){topologystack[++rear]=i;m++;}> }while(front!=rear){front++;j=topologystack[front];m++;p=Graphicmap[j].link ;while(p){k=p->adjvex ;Graphicmap[k].id --;if(ve[j]+p->dut >ve[k])ve[k]=ve[j]+p->dut ;if(Graphicmap[k].id ==0)topologystack[++rear]=k;p=p->next ;}}if(m<projectnumber){printf("\n本程序所建立的图有回路不可计算出关键路径\n ");printf("将退出本程序\n");return 0;}totaltime=ve[projectnumber-1];for(i=0;i<projectnumber;i++)vl[i]=totaltime;for(i=projectnumber-2;i>=0;i--){j=topologystack[i];p=Graphicmap[j].link ;while(p){k=p->adjvex ;if((vl[k]-p->dut )<vl[j])vl[j]=vl[k]-p->dut ;p=p->next ;}}i=0;printf("| 起点 | 终点 | 最早开始时间 | 最迟完成时间 | 差值 | 备注 |\n");for(j=0;j<projectnumber;j++){p=Graphicmap[j].link;while(p){k=p->adjvex ;e[++i]=ve[j];l[i]=vl[k]-p->dut;printf("| %4d | %4d | %4d| %4d | %4d |",Graphicmap[j].projectname +1,Graphicmap [k].projectname +1,e[i],l[i],l[i]-e[i]);if(l[i]==e[i])printf(" 关键活动 |");printf("\n");p=p->next ;}}return 1;}void seekkeyroot(){int projectnumber,activenumber,totaltime=0;system("cls");printf("请输入这个工程的化成图形的节点数:");scanf("%d",&projectnumber);printf("请输入这个工程的活动个数:");scanf("%d",&activenumber);vexnode* Graphicmap=(vexnode*)malloc(projectnumber*sizeof(vexnod e));CreateGraphic(Graphicmap,projectnumber,activenumber);SearchMapPath(Graphicmap,projectnumber,activenumber,totaltime); printf("整个工程所用的最短时间为:%d个单位时间\n",totaltime);system("pause");}int main(){char ch;for(;;){do{system("cls");printf("| 欢迎进入求关键路径算法程序 |");for(int i=0;i<80;i++)printf("*");printf("%s","(S)tart开始输入工程的节点数据并求出关键路径\n");printf("%s","(E)xit退出\n");printf("%s","请输入选择:");scanf("%c",&ch);ch=toupper(ch);}while(ch!='S'&&ch!='E');switch(ch){case'S':seekkeyroot();break;case'E':return 1;}}}4: 总结:至此,全部的设计过程完毕,上面所有代码已经在VC6.0+Win2000平台下调试成功。