问题描述:
计划评审技术PERT (Program Evaluation and Review Technique)是用于项目管理的先进方法,它把一个工程项目的各项活动,它们之间的联系和约束(各活动之间在物理上、工程上和逻辑上的制约),经过组合分解、统筹安排,有机地构成一个整体,用网络模型直观地反映出来,力求在一定的资源约束条件下,使得工程周期最短。PERT具有较强的预测、计划、协调和控制能力。
在PERT网络图中,顶点表示项目对象,有向边表示活动,有向边上的数字表示完成边的起点项目对象到开始终点项目对象所花费的时间代价(在本题中单位为天)。因此,利用PERT网络图,就能确定完成工程的关键路径,从而可以有效地组织计划实施,并进行协调与控制。下图是一个工程的PERT网络图(虚线表示时间代价为0)示例。
具体的计算方法是:
• 总时间:从起点到终点的所有路线中活动时间的最大值;
• 最早开始时间:从起点到达该点的所有路线的活动时间的最大值;
• 最早结束时间=最早开始时间+活动时间;
• 最晚开始时间=总时间-从该点到终点的所有路线中活动时间的最大值;最早开始时间和最晚开始时间相同的就是关键路径上的顶点;
• 最晚结束时间=最晚开始时间+活动时间;
• 总时差=最晚开始时间-最早开始时间。
实现要求:
⑴ 以(Vi ,Vj ,d)的形式从键盘输入PERT图的数据并以正邻接链表方式保存;
⑵ 以二维矩阵方式输出所输入的PERT图;
⑶ 对PERT图进行拓扑排序,然后输出拓扑序列;
⑷ 对PERT图进行逆拓扑排序,然后输出逆拓扑序列;
⑸ 完成网络计算(计算表格如下)并输出;
⑹ 应设计一个菜单,具有以上要求的功能和退出系统等功能;
//pert图的输入函数
PERT* readPERT()
{ PERT *Pert;
int n,i;
printf("请输入节点数:");
scanf("%d",&n);
Pert=new PERT(n);
printf("请输入有向边数:");
scanf("%d",&Pert->b);
printf("请逐条输入有向边:格式如下\n\n起点 终点 时间权值\n");
i=Pert->b;
int f,t,v;
while(i--)
{ scanf("%d%d%d",&f,&t,&v);//输入起点 终点 时间权值
Pert->pert[f][t]=v;
Pert->cdu[f]++;//出度统计
Pert->rdu[t]++;//入度统计
}
printf("###输入结束###\n");
return Pert;
}
// pert图的输出函数
void printPERT(PERT *Pert)
{ int i,j;
printf("所输入的PERT图为:\n 顶点");
for(i=1;i<=Pert->n;i++)//
printf("%5d",i);
for(i=1;i<=Pert->n;i++)
{ printf("\n%4d ",i);
for(j=1;j<=Pert->n;j++)
if(Pert->pert[i][j]>=0)
printf("%5d",Pert->pert[i][j]);
else
printf(" **");//无边
}
printf("\n###输出结束###\n");
}
// 输出网络计算的结果
void printinformation(PERT *Pert,Informatiom *p)
{ int i,j,k;
printf("总时间为: %d(天)\n",p->maxtime);
printf("活动名 最早开始 最早结束 最晚开始 最晚结束 总时差 关键路径\n");
k=Pert->n;
memset(visit,0,sizeof(visit));
for(i=0;i<=Pert->n;i++)//入度统计
du[i]=Pert->rdu[i];
while(k--)
{ for(i=1;i<=Pert->n;i++)//查找未历遍且入度为0的顶点
if(!visit[i]&&du[i]==0)
break;
if(i>Pert->n)
{ printf("该PERT图不完整\n");
return ;
}
visit[i]=1;
printf("%4d%8d%8d%10d%10d%8d",i,p->Lstarttime[i],p->Lendtime[i],p->Rstarttime[i],p->Rendtime[i],p->slacktime[i]);
if(p->slacktime[i]==0)//时差为0就是关键路径上的顶点
printf(" 是\n");
else
printf(" 不是\n");
for(j=1;j<=Pert->n;j++) //消除以i为起点的边统计
if(Pert->pert[i][j]>=0)
du[j]--;
}
}
//网络计算(并输出结果)
void work(PERT *Pert)
{ int i,j,k,e;
memset(visit,0,sizeof(visit));
Informatiom *pp;
pp=new Informatiom(Pert->n);
k=Pert->n;
for(i=0;i<=Pert->n;i++)//入度统计
du[i]=Pert->rdu[i];
//计算最早开始时间
while(k--)
{ for(i=1;i<=Pert->n;i++)//查找未历遍且入度为0的顶点
if(!visit[i]&&du[i]==0) break;
if(i>Pert->n)
{ printf("该PERT图不完整\n");
return ;
}
visit[i]=1;
for(j=1;j<=Pert->n;j++)//消除以i为起点的边统计
if(Pert->pert[i][j]>=0)
{ //最早开始时间=从起点到达该点的所有路线的活动时间的最大值
if(pp->Lstarttime[j]<pp->Lstarttime[i]+Pert->pert[i][j])
pp->Lstarttime[j]=pp->Lstarttime[i]+Pert->pert[i][j];
du[j]--;
}
}
e=i; //结束点
pp->maxtime=pp->Lstarttime[e];//总时间=从起点到终点的所有路线中活动时间的最大值
pp->Rstarttime[e]=pp->Lstarttime[e];//结束点的最晚开始时间
memset(visit,0,sizeof(visit));
for(i=0;i<=Pert->n;i++)//初度统计
du[i]=Pert->cdu[i];
k=Pert->n;
//计算最晚开始时间
while(k--)
{ for(i=1;i<=Pert->n;i++)//查找未历遍且出度为0的顶点
if(!visit[i]&&du[i]==0) break;
if(i>Pert->n)
{ printf("该PERT图不完整\n");
return ;
}
visit[i]=1;
for(j=1;j<=Pert->n;j++)//消除以i为终点的边统计
if(Pert->pert[j][i]>=0)
{ //最晚开始时间=总时间-从该点到终点的所有路线中活动时间的最大值 if(pp->Rstarttime[j]>pp->Rstarttime[i]-Pert->pert[j][i])
pp->Rstarttime[j]=pp->Rstarttime[i]-Pert->pert[j][i];
du[j]--;
}
}
//计算最早(晚)结束时间
for(i=1;i<=Pert->n;i++)
{ k=0;
for(j=1;j<=Pert->n;j++)
if(Pert->pert[i][j]>k)// 查找i顶点的最大活动时间
k=Pert->pert[i][j];
pp->Lendtime[i]=pp->Lstarttime[i]+k;//最早结束时间=最早开始时间+活动时间;
pp->Rendtime[i]=pp->Rstarttime[i]+k;//最晚结束时间=最晚开始时间+活动时间;
}
//计算时间差
for(i=1;i<=Pert->n;i++) //时差=最晚开始时间-最早开始时间。
pp->slacktime[i]=pp->Rstarttime[i]-pp->Lstarttime[i];
printinformation(Pert,pp); //输出计算结果
printf("\n###网络计算结束###\n");
}
//主函数(含界面)
int main()
{ //freopen("pert.in","r",stdin);
//freopen("out.txt","w",stdout);
int menu,i,j;
PERT *Pert;//
printf("(^_^) 欢迎使用计划评审技术PERT系统 (^_^)\n");
while(1)
{ printf(" ***************** PERT系统菜单 ********************\n");
printf("* 序号 对应功能 *\n");
printf("* [1] : 输入PERT图数据 *\n");
printf("* [2] : 输出PERT图 *\n");
printf("* [3] : 网络计算并输出结果 *\n");
printf("* [0] : 退出系统 *\n");
printf(" ****************************************************\n");
printf("#请输入操作序号(1, 2, 3, 0):");
scanf("%d",&menu);//输入操作序号
switch(menu)
{case 0: printf("按任意键跳出");scanf("%c%c",&i,&j);return 0;
case 1: printf("\n ***您选的操作是输入PERT图数据***\n"); Pert=readPERT(); break;
case 2: printf("\n ***您要输出的PERT图如下***\n");
printPERT(Pert); break;
case 3: printf("\n ***网络计算结果如下*** 时间单位为(天)\n"); work(Pert); break;
default :printf("\n ***您的输入有误;请重新输入***\n"); break;
}
}
return 0;
}
这是我的一部分代码,可是剩下的几个要求不会,求大神帮忙
图片是网址里面的一个叫课程设计的相册:
http://user.qzone.qq.com/496466490/infocenter#!app=4&via=QZ.HashRefresh
8 个解决方案
#1
#2
这属于劳务报酬的范围
#3
其实我没看懂这个程序有什么意思
#4
楼主需要自食其力.. 在CSDN看看有没有相关资源。
#5
这个算XX管理系统么……
#6
#7
估计给钱才有高手考虑!
#8
如果楼主给些报酬 必定有人回应啊
#1
#2
这属于劳务报酬的范围
#3
其实我没看懂这个程序有什么意思
#4
楼主需要自食其力.. 在CSDN看看有没有相关资源。
#5
这个算XX管理系统么……
#6
#7
估计给钱才有高手考虑!
#8
如果楼主给些报酬 必定有人回应啊