关键路径.docx
《关键路径.docx》由会员分享,可在线阅读,更多相关《关键路径.docx(35页珍藏版)》请在冰豆网上搜索。
![关键路径.docx](https://file1.bdocx.com/fileroot1/2023-8/4/743e8ea3-ac7c-45c7-9b29-36e53722c890/743e8ea3-ac7c-45c7-9b29-36e53722c8901.gif)
关键路径
南通大学数据结构实践课
实验报告册
姓名:
耿智
班级:
软件工程092
学号:
0913063042
实验名称:
关键路径
指导老师:
丁卫平
南通大学杏林学院
2011年5月28日
1.程序设计简介
本程序实现AOE网关键路径求解。
图存储采用了邻接表。
本程序使用了顺序栈。
程序提供有向网的创建和关键路径求解功能。
运行结果为:
一条关键路径及辅助变量计算值,通过该值,很容易找到那些活动为关键活动及关键路径的选择原则。
2.算法设计
AdjLGraph.h
#include"SqStack.h"
#ifndefALGRAPH
#defineALGRAPH
#ifndefMAX_VERTEX_NUM
#defineMAX_VERTEX_NUM20//最大顶点数
#endif
structArcNode{
intadjvex;//该弧所指向的顶点的位置
structArcNode*nextarc;//指向下一条弧的指针
int*info;//该弧相关信息的指针(权值)
};
template
structVNode{
Tdata;//顶点信息
ArcNode*firstarc;//指向第一条依附该顶点的指针
};
template
struct_ALGraph{
VNodevertices[MAX_VERTEX_NUM];
intvexnum;
intarcnum;
intkind;
};
#ifndefCSNODE
#defineCSNODE
template
structCSTree{
//树的二叉链表存储
Tdata;
CSTree*firstchild;//孩子
CSTree*nextsibling;//兄弟
};
#endif
template
classALGraph{
_ALGraphalgraph;
boolvisited[MAX_VERTEX_NUM];
intve[MAX_VERTEX_NUM];//各顶点最早发生时间
public:
voidCreateGraph();//v是图的顶点集vr是图的边集//构造函数
voidDestroyGraph();//析构函数销毁图
intLocateVex(Tu);//图存在,图中存在顶点u则返回该顶点在图中的位置
TGetVex(intindex);//图存在,index是图中某个顶点的序号:
返回v的值
voidPutVex(Tv,Tvalue);//图存在,v是图中某个顶点则对v赋值value
intFirstAdjVex(Tv);//图存在,v是G中某个顶点返回v的第一个临接点的序号若无领接点则返回空
intNextAdjVex(Tv,Tw);//图存在,v是图中某个顶点,w是v的邻接点返回v的相对于w的下一个邻接点的序号,若w是v的最后一个邻接点则返回空
voidInsertVex(Tv);//图存在在图中增加新顶点v
boolDeleteVex(Tv);//图存在删除顶点v及其相关的弧
boolInsertArc(Tv,Tw);//图存在,V,w是图的两个顶点在图中添加弧若是无向图,则还应增加对称弧
voidDeleteArc(Tv,Tw);//图存在,V,w是图的两个顶点在图中删除弧若是无向图,则还应删除对称弧
bool(*VisitFunc)(Tv);//访问顶点v的方式
voidDFS(intindex);//从第index个顶点出发递归的深度优先遍历图
boolDFSTraverse(bool(*visit)(Tv));//图存在,对图进行深度优先遍历
boolBFSTraverse(bool(*visit)(Tv));//图存在,对图进行广度优先遍历
voidDisPlay();//输出图
voidFindInDegree(intindegree[]);//求顶点的入度
boolTopologicalSort();//若图无回路,则输出图的顶点的一个拓扑序列并返回true,否则返回false
boolTopologicalOrder(SeqStack&T);//求各顶点事件的最早发生时间ve
boolCriticalPath();//输出图的各项关键活动
};
template
intALGraph:
:
LocateVex(Tu)
{
for(inti=0;i{
if(algraph.vertices[i].data==u)
{
returni;
}
}
return-1;
}
template
voidALGraph:
:
CreateGraph()
{
inti,j,k;
intw;//权值
Tv1,v2;
cout<<"请输入图的顶点数,边数:
";
cin>>algraph.vexnum>>algraph.arcnum;
cout<<"请输入"<";
for(i=0;i//初始化顶点结点
{
cin>>algraph.vertices[i].data;
algraph.vertices[i].firstarc=false;
}
cout<<"请输入每条弧(边)的权值、弧尾、弧头:
"<//构造表结点链表
for(k=0;k{
cout<<"请输入一条弧(边)的权值、弧尾、弧头:
";
cin>>w>>v1>>v2;
i=LocateVex(v1);
j=LocateVex(v2);
ArcNode*p=newArcNode;//创建一个新的弧结点
p->adjvex=j;p->nextarc=false;
p->info=newint;
*(p->info)=w;
p->nextarc=algraph.vertices[i].firstarc;//插在表头
algraph.vertices[i].firstarc=p;
}
}
template
voidALGraph:
:
DestroyGraph()
{
inti;
ArcNode*p,*q;
for(i=0;i//从顶点序号为0的顶点开始依次释放掉相应的邻接表
{
p=algraph.vertices[i].firstarc;
while(p)
{
q=p->nextarc;
if(algraph.kind%2)
//网,则释放权值信息
{
deletep->info;
}
deletep;//删除弧结点
p=q;
}
}
algraph.arcnum=0;
algraph.vexnum=0;
}
template
TALGraph:
:
GetVex(intindex)
{
if(index<0||index>=algraph.vexnum)
returnfalse;
returnalgraph.vertices[index].data;
}
template
voidALGraph:
:
PutVex(Tv,Tvalue)
{
inti=LocateVex(v);
if(i<0)//该顶点不存在
return;
algraph.vertices[i].data=value;
}
template
intALGraph:
:
FirstAdjVex(Tv)
{
inti=LocateVex(v);
ArcNode*p=algraph.vertices[i].firstarc;//p指向下标为i的第一个邻接点
if(p)
{
returnp->adjvex;
}
else
{
return-1;
}
}
template
intALGraph:
:
NextAdjVex(Tv,Tw)
{
ArcNode*p;
inti=LocateVex(v);
intj=LocateVex(w);
p=algraph.vertices[i].firstarc;
while(p&&(p->adjvex!
=j))
//让p指向顶点w
{
p=p->nextarc;
}
if(!
p||!
p->nextarc)//没找到w或w是最后一个顶点
return-1;
else
//找到w且w不是最后一个顶点
{
returnp->nextarc->adjvex;
}
}
template
voidALGraph:
:
InsertVex(Tv)
{
if(algraph.vexnum>MAX_VERTEX_NUM)
return;//无法插入
if(LocateVex(v)>=0)
return;
algraph.vertices[algraph.vexnum].data=v;
algraph.vertices[algraph.vexnum].firstarc=false;
algraph.vexnum++;
}
template
boolALGraph:
:
DeleteVex(Tv)
{
if(algraph.vexnum>=MAX_VERTEX_NUM)
returnfalse;
inti,j;ArcNode*p,*q;
i=LocateVex(v);
if(i<0)
returnfalse;
p=algraph.vertices[i].firstarc;
while(p)
//删除以v为出度的弧或边
{
q=p;
p=p->nextarc;
if(algraph.kind%2)
//网
{
deleteq->info;
}
deleteq;
algraph.arcnum--;
}
algraph.vexnum--;
for(j=i;j//顶点v后面的顶点前移
{
algraph.vertices[j]=algraph.vertices[j+1];
}
for(j=0;j//删除以v为入度的弧或边
{
p=algraph.vertices[j].firstarc;
while(p)
//有弧或边
{
if(p->adjvex==i)
//找到待删结点
{
if(p==algraph.vertices[j].firstarc)
//待删除结点为第一个邻接点
{
algraph.vertices[j].firstarc=p->nextarc;
if(algraph.kind%2)
//网
{
deletep->info;
}
deletep;
p=algraph.vertices[j].firstarc;
if(algraph.kind<2)
//有向
{
algraph.arcnum--;
}
}
else
{
q->nextarc=p->nextarc;
if(algraph.kind%2)
//网
{
deletep->info;
}
deletep;
p=q->nextarc;
if(algraph.kind<2)
//有向
{
algraph.arcnum--;
}
}
}
else
{
if(p->adjvex>i)
//修改表结点的顶点位置序号
{
p->adjvex--;
}
q=p;
p=p->nextarc;
}
}
}
returntrue;
}
template
boolALGraph:
:
InsertArc(Tv,Tw)
{
ArcNode*p;
inti,j;
intw1;
i=LocateVex(v);
j=LocateVex(w);
if(i<0||j<0)
returnfalse;
algraph.arcnum++;
if(algraph.kind%2)
//网
{
cout<<"请输入弧(边)"<"<cin>>w1;
}
p=newArcNode;
p->adjvex=j;p->nextarc=false;
if(algraph.kind%2)
//网
{
p->info=newint;
*(p->info)=w1;
}
else
//图
{
p->info=false;
}
//插在表头
p->nextarc=algraph.vertices[i].firstarc;
algraph.vertices[i].firstarc=p;
if(algraph.kind>1)//无向
{
p=newArcNode;
p->adjvex=i;p->nextarc=false;
if(algraph.kind==3)
//无向网
{
p->info=newint;
*(p->info)=w1;
}
else
//无向图
{
p->info=false;
}
//插在表头
p->nextarc=algraph.vertices[j].firstarc;
algraph.vertices[j].firstarc=p;
}
returntrue;
}
template
voidALGraph:
:
DeleteArc(Tv,Tw)
{
ArcNode*p,*q;
inti,j;
i=LocateVex(v);
j=LocateVex(w);
if(i<0||j<0||i==j)
return;
p=algraph.vertices[i].firstarc;
while(p&&p->adjvex!
=j)
//p不空且q指向的不是待删弧结点
{
q=p;
p=p->nextarc;
}
if(p&&p->adjvex==j)
//找到弧
{
if(p==algraph.vertices[i].firstarc)
{
algraph.vertices[i].firstarc=p->nextarc;
}
else
{
q->nextarc=p->nextarc;
}
if(algraph.kind%2)
//网
{
deletep->info;
}
deletep;
algraph.arcnum--;
}
if(algraph.kind>1)
//无向则删除对称弧
{
p=algraph.vertices[j].firstarc;
while(p&&p->adjvex!
=i)
//p不空且q指向的不是待删弧结点
{
q=p;
p=p->nextarc;
}
}
if(p&&p->adjvex==i)
//找到弧
{
if(p==algraph.vertices[j].firstarc)
{
algraph.vertices[j].firstarc=p->nextarc;
}
else
{
q->nextarc=p->nextarc;
}
if(algraph.kind==3)
//无向网
{
deletep->info;
}
deletep;
}
}
template
voidALGraph:
:
DFS(intindex)
{
Tv1;inti;
visited[index]=true;//已访问
VisitFunc(algraph.vertices[index].data);//访问index的顶点
v1=GetVex(index);
for(i=FirstAdjVex(v1);i>=0;i=NextAdjVex(v1,GetVex(i)))
{
if(!
visited[i])
DFS(i);
}
}
template
boolALGraph:
:
DFSTraverse(bool(*visit)(Tv))
{
inti;
VisitFunc=visit;
for(i=0;i{
visited[i]=false;
}
for(i=0;i//对每个未被访问的顶点进行深度优先遍历
{
if(!
visited[i])
DFS(i);
}
cout<returntrue;
}
template
boolALGraph:
:
BFSTraverse(bool(*visit)(Tv))
{
LinkedQueueq;inti,j,receive;Tu1;
for(i=0;i{
visited[i]=false;
}
for(i=0;i//对每个未被访问的顶点进行广度优先遍历
{
if(!
visited[i])
{
visited[i]=true;
if(!
visit(algraph.vertices[i].data))
returnfalse;
q.EnQueue(i);
while(!
q.IsEmpty())
{
q.DeQueue(receive);//对头元素出队并置为receive
u1=GetVex(receive);
for(j=FirstAdjVex(u1);j>=0;j=NextAdjVex(u1,GetVex(j)))
{
if(!
visited[j])
{
visited[j]=true;
if(!
visit(algraph.vertices[j].data))
returnfalse;
q.EnQueue(j);
}
}
}
}
}
cout<returntrue;
}
template
voidALGraph:
:
DisPlay()
{
inti;
ArcNode*p;
switch(algraph.kind)
{
case0:
cout<<"有向图"<break;
case1:
cout<<"有向网"<break;
case2:
cout<<"无向图"<break;
case3:
cout<<"无向网"<break;
}
cout<"<//输出顶点
for(i=0;i{
cout<}
cout<cout<"<for(i=0;i{
p=algraph.vertices[i].firstarc;
while(p)
{
if(algraph.kind<2)
//有向
{
cout<"<adjvex].data<<'\t';
if(algraph.kind==1)
//有向网
{
cout<<*(p->info);
}
cout<}
else
//无向
{
if(iadjvex)