图的关键路径

本文介绍了一种用于确定项目中关键路径的算法。通过构建AOE网络表示项目活动及其持续时间,该算法能够找出决定项目总时长的关键路径,并提供源代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

摘 要  介绍求关键路经的算法,对于给出的事件结点网络,要求求出从起点到终点的所有路径,经分析、比较后找出长读最大的路径,从而得出求关键路径的算法,并给出计算机上机实现的源程序。
关键词  关键路径 最少时间
1:引言
通常把计划、施工过程、生产流程、程序流程的都当成一个工程。除了很小的工程外、一般都把工程分为若干个叫做“活动”的子工程。完成了这些“活动”的子工程,这个工程就可以完成了。
通常我们用有向图表示一个工程。在这种有向图中,用顶点表示活动,用有向边
<Vi,Vj>表示活动Vi必须先于活动Vj进行。如果在无有向环的带权有向图中用有向边表示一个工程中的各项活动(ACTIVITY),用有向边上的权值表示活动的持续时间(DURATION),用顶点表示事件(EVENT),则这种的有向图叫做用边表示活动的网络,简称AOE(active on edges)网络。
    AOE网络在某些工程估算方面非常有用。他可以使人们了解:
         (1):研究某个工程至少需要多少时间?
         (2):那些活动是影响工程进度的关键?
在AOE网络中,有些活动可以并行的进行。从源点到各个顶点,以至从源点到汇点的有向路径可能不止一条。这些路径的长度也可能不同。完成不同路径的活动所需的时间虽然不同,但只有各条路径上所有活动都完成了,这个工程才算完成。因此,完成整个工程所需的时间取决于从源点到汇点的最长路径长度,即在这条路径上所有活动的持续时间之和。这条路径长度就叫做关键路径(critical 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//13
typedef 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 activenumber)
{
       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 activenumber,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));//表示活动最早开始时间
       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(vexnode));
    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);
              }






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值