关键路径问题
具体要解决的问题有如下四个:
1)将项目中的各项活动视为有一个时间属性的结点,从项目起点到终点进行排列;
2)用有方向的线段标出各结点的紧前活动和紧后活动的关系,使之成为一个有方向的网络图;
3)用正推法和逆推法计算出各个活动的最早开始时间,最晚开始时间,最早完工时间和最迟完工时间,并计算出各个活动的时差;
void seekkeyroot()//求关键路径的主函数
{
int projectnumber,activenumber,totaltime=0;
printf("\n");
printf("输入符合标准,欢迎进入求关键路径的系统!\n");
printf("\n");
printf("请输入这个项目的AOE-网的节点数: ");
{
int projectname;//顶点域
int id;//顶点的入度信息
edgenode *link; //边表头指针
}vexnode;
void CreateGraphic(vexnode* Graphicmap,int projectnumber,int activenumber)//创建图
{
CreateGraphic(Graphicmap,projectnumber,activenumber);//创建邻接图
SearchMapPath(Graphicmap,projectnumber,activenumber,totaltime);//求出最大路径,并打印出关键路径
printf("\n");
edgenode *p; //边表头的指针
totaltime=0; //存放整个工程的最短时间
for(i=0;i<projectnumber;i++) ve[i]=0;//先把每个工程的最早发生时间初始化为零
for(i=0;i<projectnumber;i++)
{
if(Graphicmap[i].id==0)
(5)关键路径:从源点到汇点的路径长度最长的路径叫关键路径。
(6)活动开始的最早时间e(i);
(7)活动开始的最晚时间l(i);
(8)定义e(i)=l(i)的活动叫关键活动;
(9)事件开始的最早时间ve(i);
(10)事件开始的最晚时间vl(i)。
设活动ai由弧<j,k>(即从顶点j到k)表示,其持续时间记为dut(<j,k>),则:
printf(" 欢迎进入求关键路径算法程序 \n");
printf("☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★ \n");
printf("%s","\ns(start)开始输入工程的节点数据并求出关键路径\n");
printf("\n");
printf("%s","e(exit)退出\n");
,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));//用来表示活动Ai最迟完成开始时间
int* e=(int*)malloc(activenumber*sizeof(int));//表示活动最早开始时间
4)找出所有时差为零的活动所组成的路线,即为关键路径;
三、概要设计
算法分析:
(1)求关键路径必须在拓扑排序的前提下进行,有环图不能求关键路径;
(2)只有缩短关键活动的工期才有可能缩短工期;
(3)若一个关键活动不在所有的关键路径上,减少它并不能减少工期;
(4)只有在不改变关键路径的前提下,缩短关键活动才能缩短整个工期。
topologystack[++rear]=k;
p=p->next ; //指向下一个节点
}
}
if(m<projectnumber)//如果有环,则不能遍历每个节点
{
printf("\n本程序所建立的图有回路不可计算出关键路径!\n");
printf("将退出本程序!\n");
return 0;
}
totaltime=ve[projectnumber-1];//最短完成时间即为最后一个节点所累加的时间之和
一、课题内容和要求
关键路径问题。
二、设计思路分析
(1)选取建图的一种算法建立图,有邻接矩阵,邻接表,十字链表,邻接多重表等多种方法,要选取一种适当的方法建立图,才能提高算法效率,降低时间复杂度和空间复杂度。
(2)两个相邻顶点与它们之间的边表示活动,边上的数字表示活动延续的时间。对于给出的事件AOE网络,要求求出从起点到终点的所有路径,经分析、比较后找出长读最大的路径,从而得出求关键路径的算法,并给出计算机上机实现的源程序。完成不同路径的活动所需的时间虽然不同,但只有各条路径上所有活动都完成了,这个工程才算完成。
#include<iomanip.h>
#include <process.h>
typedef struct node//边表结点
{
int adjvex; //邻接点编号
int dut; //弧的信息
struct node *next; //下一条弧指针
}edgenode;
typedef struct //顶点表结点
for(i=0;i<projectnumber;i++)
vl[i]=totaltime;
for(i=projectnumber-2;i>=0;i--)// 用逆拓扑排序来求活动Ai最迟完成开始时间,即从最后一个节点减去最短的时间
{
j=topologystack[i];
p=Graphicmap[j].link ;
Graphicmap[i].link =NULL;
}
printf("\n");
printf("请输入某项目的信息,并请用整形数字表示(格式:弧头,弧尾,权值):\n");
printf("例如:输入1,2,4 即代表结点1与4之间的活动需要4个时间单位。\n");
printf("\n");
for(int k=0;k<activenumber;k++) //activenumber为活动的数目,即弧的条数
p->dut =duttem; //该弧的活动时间为duttem
Graphicmap[end-1].id ++; //入度加一
p->next =Graphicmap[begin-1].link ;
Graphicmap[beg}
}
int SearchMapPath(vexnode* Graphicmap,int projectnumber,int activenumber
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");
printf("| 起点 | 终点 | 最早开始时间 | 最迟完成时间 | 差值 | 备注 \n");
for(j=0;j<projectnumber;j++)
(4)根据各顶点的ve和vl值,求每条弧s(活动)的最早开始时间e(s)和最晚开始时间l(s),其中e(s)=l(s)的为关键活动。
四、详细设计
主要函数的核心代码:
1.创建图的函数
2.求出最大路径,并打印出关键路径的函数
3.球关键路径的函数
4.主函数
#include<stdio.h>
#include<stdlib.h>
<i,j>S, 1<=i<=n-1
其中,S是所有以i为弧尾的弧的集合。
两个递推公式是在拓扑有序和逆拓扑有序的前提下进行。
算法步骤:
(1)输入e条弧<j,k>,建立AOE网的存储结构。
(2)从源点v1出发,令ve(1)=0,求 ve(j),2<=j<=n。
(3)从汇点vn出发,令vl(n)=ve(n),求 vl(i) 1<=i<=n-1。
{
p=Graphicmap[j].link;
while(p)
{
k=p->adjvex ;
e[++i]=ve[j];
l[i]=vl[k]-p->dut;
printf("| %4d | %4d | %11d | %11d | %3d |",Graphicmap[j].projectname +1,Graphicmap[k].projectname +1,e[i],l[i],l[i]-e[i]);