拓扑排序和关键路径Word下载.docx
《拓扑排序和关键路径Word下载.docx》由会员分享,可在线阅读,更多相关《拓扑排序和关键路径Word下载.docx(19页珍藏版)》请在冰豆网上搜索。
:
从源点到汇点的路径长度最长的路径叫关键路径。
(6)活动的最早开始时间e(i);
(7)活动的最晚开始时间l(i);
(8)定义e(i)=l(i)的活动叫关键活动;
(9)事件的最早开始时间ve(i);
(10)事件的最晚开始时间vl(i)。
3文章编辑的设计
3.1概要设计
structSqStack////栈部分
{
SElemType*base;
//栈底指针
SElemType*top;
//栈顶指针
intstacksize;
//栈的大小
intelement_count;
//栈中元素个素
};
/////////AOE网的存储结构
structArcNode//表结点
intlastcompletetime;
//活动最晚开始时间
intadjvex;
//点结点位置
intinfo;
//所对应的弧的权值
structArcNode*next;
//指向下一个表结点指针
structVNode//点结点
VertexTypedata;
//结点标志
intindegree;
//该结点入度数
intve;
//记录结点的最早开始时间
intvl;
//记录结点的最晚开始时间
structArcNode*first_out_arc;
//存储下一个出度的表结点
structArcNode*first_in_arc;
//存储下一个入度的表结点
structALGraph
{VNode*vertices;
//结点数组
intvexnum;
//结点数
intarcnum;
//弧数
intkind;
//该图的类型};
3.3调试分析
测试数据,测试输出的结果,时间复杂度分析,和每个模块设计和调试时存在问题的思考(问题是哪些?
问题如何解决?
),算法的改进设想。
3.4用户手册(略)
3.5测试结果(略)
4总结
一开始整个程序不知道怎么开始,而且算法是怎么样的都不知道,不过经过一番的查书、翻阅资料、上网查找之后终于了解到整个算法流程以及实现。
5、程序清单:
(见附录)
#include<
stdio.h>
stdlib.h>
#defineVertexTypeint
#defineSTACK_ADDITIONsizeof(SElemType)
#defineSElemTypeint
#defineOKtrue
#defineERRORfalse
#defineStatusbool
structSqStack
SElemType*base;
SElemType*top;
intstacksize;
intelement_count;
//元素个素
StatusInitStack(SqStack&
S)//初始化栈
S.base=(SElemType*)malloc(STACK_ADDITION);
S.stacksize=STACK_ADDITION;
S.element_count=0;
if(S.base==NULL)
{
printf("
mallocerror\n"
);
exit(0);
}
else
S.top=S.base;
returnOK;
}
StatusDestroyStack(SqStack&
S)//销毁栈
if(S.base==NULL)
Stackisnotexistent\n"
delete(S.base);
StatusClearStack(SqStack&
S)//清空栈
elseif(S.base==S.top)
SackisNULL\n"
S.element_count=0;
StatusStackEmpty(SqStackS)//判断是否为空
returnfalse;
if(S.top==S.base)
returntrue;
StatusPush(SqStack&
S,SElemTypee)//增加元素
SElemType*temp1=S.base;
SElemType*temp2=S.top;
if(S.stacksize-(S.element_count*STACK_ADDITION)==STACK_ADDITION)
S.base=(SElemType*)realloc(S.base,(S.stacksize+STACK_ADDITION));
S.stacksize+=STACK_ADDITION;
S.top=S.base+(temp2-temp1);
*S.top=e;
S.top=S.top+1;
S.element_count++;
S.top=S.top+1;
StatusPop(SqStack&
S,SElemType&
e)//弹出元素
if(S.top==S.base)
Stackisnull!
Poperror!
\n"
e=*--S.top;
S.element_count--;
returnOK;
intStackLength(SqStackS)
returnS.element_count;
StatusGetElement(SqStack&
S,intposition,SElemType&
e)//取元素,非弹出,i为要去元素位置
SElemType*temp;
temp=S.top;
GetElementerror!
elseif(position<
=S.element_count)
e=*(temp-position);
error!
由于输入位置比栈元素数目大"
//===================================================================//表结点
structArcNode{
//活动最晚完成时间
//下一个表结点
//标志
//记录最早开始时间
//记录最晚开始时间
VNode*vertices;
//弧数
intkind;
//该图的类型
voidCreateALGraph(ALGraph&
graph)
inttemp1=1;
inttemp2=0;
inttemp3=0;
//权
inti=0;
structArcNode*arc1=NULL;
structArcNode*arc2=NULL;
printf("
请输入结点数(结点由1开始)和图的类型:
scanf("
%d%d"
&
graph.vexnum,&
graph.kind);
graph.vertices=(VNode*)malloc((graph.vexnum+1)*sizeof(VNode));
for(i=0;
i<
=graph.vexnum;
i++)
(graph.vertices+i)->
data=i;
first_in_arc=NULL;
first_out_arc=NULL;
ve=0;
vl=0;
indegree=0;
请输入(格式:
点,点,两点之间的权值\n"
graph.arcnum=-1;
while(!
(temp1==0&
&
temp2==0&
temp3==0))
graph.arcnum++;
//图的弧数
scanf("
%d%d%d"
temp1,&
temp2,&
temp3);
((graph.vertices+temp2)->
indegree)++;
if((graph.vertices+temp2)->
first_in_arc==NULL)
{
(graph.vertices+temp2)->
first_in_arc=(ArcNode*)malloc(sizeof(ArcNode));
first_in_arc->
adjvex=temp1;
info=temp3;
lastcompletetime=0;
//活动最晚完成时间初始化
next=NULL;
}
else
arc2=(graph.vertices+temp2)->
first_in_arc;
while(arc2->
next!
=NULL)//如果下一个不为空的话就存储下一个地址
{
arc2=arc2->
next;
}
arc2->
next=(ArcNode*)malloc(sizeof(ArcNode));
next->
if((graph.vertices+temp1)->
first_out_arc==NULL)
(graph.vertices+temp1)->
first_out_arc=(ArcNode*)malloc(sizeof(ArcNode));
first_out_arc->
adjvex=temp2;
arc1=(graph.vertices+temp1)->
first_out_arc;
while(arc1->
arc1=arc1->
arc1->
StatusTopologicalSort(ALGraph&
graph,SqStack&
ToPoReverseSort)//求拓扑排序
SqStackS;
structArcNode*p=NULL;
intk=0;
intcounter;
//计算拓扑序列的个数
int*indegree_copy=(int*)malloc(sizeof(int)*graph.vexnum);
graph.vexnum;
*(indegree_copy+i)=(graph.vertices+i+1)->
indegree;
if(!
InitStack(S))
初始化栈失败"
for(i=1;
if(!
((graph.vertices+i)->
indegree))
Push(S,i);
counter=0;
i=0;
StackEmpty(S))
Pop(S,i);
Push(ToPoReverseSort,i);
//用栈ToPoReverseSort存放拓扑逆序序列
counter++;
for(p=((graph.vertices+i)->
first_out_arc);
p;
p=p->
next)
k=p->
adjvex;
if(!
(--((graph.vertices+k)->
indegree)))
Push(S,k);
DestroyStack(S);
(graph.vertices+i+1)->
indegree=*(indegree_copy+i);
if(counter<
graph.vexnum)
returnERROR;
StatusPutInfoToPoSort(SqStacktemp,ALGraphgraph)//输出拓扑顺序排序(当拓扑序列存在时)
SElemTypee=0;
intj=temp.element_count;
for(inti=1;
=j;
Pop(temp,e);
该结点为V%d:
数组下标为:
%d\n"
(graph.vertices+e)->
data,e);
StatusGetVeAndVl(ALGraph&
graph,SqStackOrderSort,SqStackRevSort)//求出结点和活动的最晚开始时间和最早开始时间
inti=0,j=0;
intkk=0;
SElemTypee1;
SElemTypee2;
Pop(OrderSort,e1);
(graph.vertices+e1)->
ve=1;
kk=OrderSort.element_count;
=kk;
Pop(OrderSort,e2);
for(j=1,p=((graph.vertices+e2)->
first_in_arc);
j<
=(graph.vertices+e2)->
j++,p=p->
if((graph.vertices+e2)->
ve<
(graph.vertices+p->
adjvex)->
ve+p->
info)
(graph.vertices+e2)->
ve=(graph.vertices+p->
info;
Pop(RevSort,e1);
//弹出拓扑序列最后一个元素
=graph.vexnum;
vl=2147483647;
vl=(graph.vertices+e1)->
ve;
//最晚开始时间=最早开始时间
kk=RevSort.element_count;
Pop(RevSort,e2);
for(p=((graph.vertices+e2)->
p->
lastcompletetime=((graph.vertices+p->
vl)-(p->
info);
vl>
((graph.vertices+p->
info))
vl=((graph.vertices+p->
///////////////////////////////////////
\n\n--------------结点信息-------------\n"
结点\t最早开始时间\t最晚开始时间\t入度数\n"
V%d\t%2d\t\t%2d\t\t%2d\n"
(graph.vertices+i)->
data,(graph.vertices+i)->
ve,(graph.vertices+i)->
vl,(graph.vertices+i)->
indegree);
\n---------------活动信息--------------\n"
活动最早开始时间最晚开始时间为\n"
printf("
<
V%d,V%d>
\t\t%d\t\t%d\n"
i,p->
adjvex,(graph.vertices+i)->
ve,p->
lastcompletetime);
\n\n"
StatusCriticalPath(ALGraph&
graph,SqStackRevSort)//求出关键活动和关键事件并输出
inti,j;
intm=0;
InitStack(S);
Pop(RevSort,e1);
if((graph.vertices+e1)->
ve==(graph.ver