数据结构课程设计报告关键路径Word下载.docx
- 文档编号:22008816
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:33
- 大小:103.21KB
数据结构课程设计报告关键路径Word下载.docx
《数据结构课程设计报告关键路径Word下载.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计报告关键路径Word下载.docx(33页珍藏版)》请在冰豆网上搜索。
完成了这些“活动”,这个工程就可以完成了。
我们通常用AOE-网来表示工程。
AOE-网是一个带权的有向无环图,其中,顶点表示事件(EVENT),弧表示活动,权表示活动持续的时间。
AOE-网可以用来估算工程的完成时间。
他可以使人们了解:
(1).研究某个工程至少需要多少时间?
(2).哪些活动是影响工程进度的关键?
由于AOE-网中的有些活动可以并行进行,从开始点到各个顶点,以致从开始点到完成点的有向路径可能不止一条,这些路径的长度也可能不同。
完成不同路径的活动所需的时间虽然不同,但只有各条路径上所有活动都完成了,这个工程才算完成。
因此,完成工程所需的最短时间是从开始点到完成点的最长路径的长度,即在这条路径上的所有活动的持续时间之和.这条路径长度就叫做关键路径(CriticalPath)。
关键路径可以很方便的让我们估算出某个工程最短的时间开销,以及这个工程中哪些活动,即哪些项目是主要的,是影响工程进度的关键,从而让我们对工程的实施做出更好的时间安排,并且可以分清主次,抓住核心工程,做到有的放矢。
总的来说,正因为关键路径可以帮助我们对工程进行非常有必要的估算,让我们得以看清全局,作出更为优化的安排,所以可见关键路径的求出对一项工程而言是非常必要的。
2、需求分析:
◆建立工程网络图:
采用邻接表的算法来建立图,即顺序+链式存储结构。
◆计算出各事件及活动的的相关信息:
如每个事件的最早和最迟开始时间,每项活动的最早最迟开始时间以及完成此活动所需的时间
◆输出工程图的相关信息:
用户可根据自己需要查看相关信息
◆拓扑排序:
以此来判断图中是否有回路,因为图中如果有回路,工程就无法进行
◆找出关键活动并输出
◆找出关键路径并输出
3、概要设计:
相关说明:
设某一活动的起点为i,中点为j,完成该活动所需时间为time;
源点和汇点分别表示整个工程的开始事件和结束事件
ve:
任一事件的最早可发生时间,其值为源点到该点所有路径长度的最大值;
vl:
在不影响整个工程进度的情况下各事件的最晚可发生时间,其值为该点到汇点的最长路径之差;
e:
各项活动的最早开始时间,若以<
i,j>
表示该活动,则e(i,j)=ve(i);
l:
各项活动的最晚开始时间,若以<
表示该活动,则v(i,j)=vl(j)-time;
d:
在不增加整个工程所需总时间的情况下,某项活动可以拖延的时,其值为e-l;
◆采用邻接表的方式建立工程图
◆对AOE网进行排序,若发现回路,则提醒用户数据错误,让其重新输入
◆对于源点,对于源点,置其ve=0,依次计算出各事件的ve;
对于汇点,置其vl=ve,然后依次计算出各事件的vl;
再计算出各活动的e,l,d;
◆找出关键活动和关键路径
4、详细设计:
1、数据结构:
typedefstruct//顶点类型
{
charnum;
//顶点编号
intout_d;
//顶点出度
intin_d;
//顶点入度
intve;
//顶点所表示的事件的最早发生时间
intvl;
//顶点所表示的事件的最迟发生时间
}Vertex;
typedefstructarcnode//弧的结点结构类型
charstart;
//该弧的起点,表示此弧所代表的活动开始事件
charend;
//该弧的终点,表示此弧所代表的活动的结束事件
intvp;
//该弧的终点在邻接表中的位置
inttime;
//完成该弧所表示的活动所需的时间
inte;
//该弧所代表的活动的最早开始时间
intl;
//该弧所代表的活动的最迟开始时间
intd;
//该弧所代表的活动可以拖延的时间,当d=0时表示此活动为关键活动
structarcnode*nextarc;
//指向下一条弧的指针
}ArcNode;
typedefstruct//邻接表头结点的类型
Vertexdata;
//该顶点的相关信息
ArcNode*firstarc;
//指向第一条弧
}VNode;
typedefstruct
intn,e;
//图中顶点数和边数
VNodeadjlist[MAXV];
//邻接链表
}ALGraph;
2、创建有向图的邻接链表:
voidCreateGraph(ALGraph*g)//创建有向图的邻接链表
ArcNode*p;
inti,j,k,n,e,t,sign;
cout<
<
"
\n请输入事件总数和活动总数:
endl;
do
{
sign=1;
cin>
>
n>
e;
if((n==0)||(e<
n-1))
{
cout<
数据有误,请检查后重新输入!
sign=0;
}
}while(!
sign);
g->
n=n;
e=e;
for(i=0;
i<
n;
i++)//初始化顶点信息
g->
adjlist[i].data.num=i+65;
adjlist[i].firstarc=NULL;
adjlist[i].data.in_d=g->
adjlist[i].data.out_d=0;
adjlist[i].data.ve=g->
adjlist[i].data.vl=0;
}
\n请输入各项活动的开始事件和结束事件的编号及所需时间:
\n"
;
for(k=1;
k<
=e;
k++)
{
cout<
第"
k<
项:
i>
j>
t;
p=newArcNode;
p->
start=i+65;
end=j+65;
vp=j;
time=t;
adjlist[i].data.out_d++;
adjlist[j].data.in_d++;
p->
nextarc=g->
adjlist[i].firstarc;
adjlist[i].firstarc=p;
}
3、计算出各事件及活动的的相关信息:
voidEventInfo(ALGraph*g)//计算各事件及活动的相关信息
ArcNode*p=newArcNode;
inti,k;
adjlist[0].data.ve=0;
//对于源点,置其ve=0
for(i=0;
n;
i++)//计算各顶点所表示事件的最早发生时间ve
p=g->
while(p!
=NULL)
{
k=p->
vp;
if(g->
adjlist[k].data.ve!
=0)//如果该事件的ve已经有值,则取源点到该事件的所有路径长度的最大值
{
g->
adjlist[k].data.ve=Max(g->
adjlist[k].data.ve,g->
adjlist[i].data.ve+p->
time);
}
else//否则就取当前计算出来的值
adjlist[k].data.ve=g->
time;
p=p->
nextarc;
adjlist[g->
n-1].data.vl=g->
n-1].data.ve;
//对于汇点,置其vl=ve
for(i=g->
n-1;
i>
=0;
i--)//计算各顶点所表示事件的最迟发生时间vl
adjlist[i].data.vl!
=0)//如果该事件的vl已经有值,则取该事件到汇点的最长路径之差
adjlist[i].data.vl=Min(g->
adjlist[i].data.vl,g->
adjlist[k].data.vl-p->
adjlist[i].data.vl=g->
i++)//计算各弧所代表的活动最早开始e、最迟开始l以及可以拖延的时间d
p->
e=g->
adjlist[i].data.ve;
//某活动的最早开始时间是该活动的起点所表示的事件的最早发生时间:
e=ve
l=g->
//某活动的最迟开始时间l是该活动的终点所表示的事件的最迟开始时间与该活动的所需时间之差:
l=vl-time
d=p->
l-p->
//某活动可以推迟的时间是其最迟开始时间与最早开始时间之差
4、输出工程图的相关信息:
voidOutputGraph(ALGraph*g)//输出工程图的相关信息
event"
\tve:
\tvl"
for(inti=0;
i++)
g->
adjlist[i].data.num<
\t"
adjlist[i].data.ve<
adjlist[i].data.vl<
i++)
ArcNode*p=g->
("
p->
start<
"
end<
)"
\t\te"
\tl"
\td"
\ttime"
\t\t"
e<
\t"
l<
d<
time<
5、判断图中是否有回路:
intTopSort(ALGraph*g)//用来判断图中是否有回路
inti,j,sum=0;
//sum用来记录输出的顶点数,以判断途中是否有回路
intst[MAXV],top=-1;
//栈st的指针为top
if(g->
adjlist[i].data.in_d==0)//入度为0的顶点入栈
top++;
st[top]=i;
while(top>
-1)//栈不为空时就循环
i=st[top];
top--;
//出栈
//cout<
char(i+65)<
"
//输出顶点
sum++;
p=g->
//找第一个相邻顶点
while(p!
j=p->
adjlist[j].data.in_d--;
if(g->
adjlist[j].data.in_d==0)//入度为0的相邻顶点入栈
{
top++;
st[top]=j;
}
p=p->
//找下一个相邻顶点
return(sum==g->
n);
6、计算并输出关键活动:
voidKeyActs(ALGraph*g)//计算并输出关键活动
\n关键活动有:
if(p->
d==0)//如果p指向的活动是关键活动,就将此活动输出
cout<
("
—>
)"
7、计算并输出关键路径:
voidKeyPath(ALGraph*g)//计算并输出关键路径
ArcNodet[MAXV],*p;
//t[MAVX]数组用来存放代表关键活动的边的信息
intj=0;
//j指示t数组下标
intcount=0;
//记录关键路径的条数
\n关键路径有:
d==0)
t[j].start=p->
start;
t[j].end=p->
end;
j++;
if(p->
end==g->
n-1].data.num)//当某活动的结束事件就是整个工程的结束事件时就出现一条关键路径
count++;
intsign;
//sign用来标记关键路径在哪个位置有分叉
intflag;
//一条关键路径计算完的标志
intk=0;
//用于一条关键路径计算完以后从新计算下一条关键路径的入口
//当发生分叉时用于交换的中间变量
while(count>
0)
flag=0;
k=0;
while(flag!
=1)
if(k==0||t[k].start==t[sign].end)//如果活动源点或是上一活动的结束事件此次活动的开始事件则输出
t[k].start<
—>
sign=k;
if(t[k].end==g->
n-1].data.num)
cout<
t[k].end<
flag=1;
count--;
k++;
if(t[k].start==t[sign].start)//如果有分叉即两活动的开始事件相同、结束事件不同时就将两项活动
{//的结束事件交换,以便计算下一条路径时不发生重复
num=t[k-1].end;
t[k-1].end=t[k].end;
t[k].end=num;
}
8、所有操作的入口:
voidInterface()//所有操作的入口,主函数通过调用此函数来完成相关操作
charchoose1,choose2,ch;
intflag1,flag2;
|-------------------------------欢迎使用!
-----------------------------------|"
||"
|------------------开始->
S------------退出->
Q-------------------|"
|---------------------------------------------------------------------------|"
\n请选择:
choose1;
if(choose1=='
S'
||choose1=='
s'
)
ALGraph*G=newALGraph;
do
{
flag1=1;
CreateGraph(G);
if(!
TopSort(G))
图中有回路!
请检查后重新输入!
flag1=0;
}while(!
flag1);
EventInfo(G);
是否显示事件及活动相关信息?
---Yes—>
Y---No—>
anykey---"
cin>
ch;
if(ch=='
Y'
||ch=='
y'
)
OutputGraph(G);
\n工程的最短工期为:
G->
adjlist[G->
n-1].data.vl<
天"
KeyActs(G);
KeyPath(G);
\n\n\n--------是否继续?
-----继续使用—>
Y----退出系统—>
anykey--------"
choose2;
if(choose2=='
||choose2=='
flag2=1;
else
\n-------------------谢谢使用!
欢迎再次使用!
-------------------"
flag2=0;
endl<
elseif(choose1=='
Q'
q'
\n------------------谢谢使用!
------------------"
exit
(1);
else
\n操作有误!
请重新选择:
}while(flag2);
三、系统实现:
1、源代码见报告尾部;
2、调试分析,测试数据及界面如下:
四、设计总结:
由于上学期时间紧张,关键路径这块基本上没有理解,通过这次课程设计,我选了这个课题,一是为了让自己能很好的掌握这个知识点,二是为了在得分的压力下把输出多条关键路径的这个算法写出来。
但是在做的过程中才真正发现这个算法并不是那么简单,我花了几乎一天半的时间就为了把它写出来,但是一直无果,然后又在图书馆查阅大量书籍,虽然还是没有找到相关算法,但是在查阅的过程中我学习到了很多算法思想,这应该是我这次课程设计最大的收获吧。
这个算法的实现其实来的很突然,我在草稿纸上不停地画图分析以及上机实验,就在不知不觉中这个算法就实现了,这我从中明白:
任何事不能只想不做,要善于分析和勤于动手,才有可能达到我们期望的效果。
我从这次课程设计中所得的另外一个很大的收获是:
不能因为问题难就逃避它,只有勇于尝试才可能解决根本问题。
数据结构这门课程对我们学习好这个专业很重要,在以后,我会尽量利用我的空闲时间把以前不熟的和掌握不牢固的知识点再学习一遍,让它成为一门为我所用的课程。
五、附件(完整源代码):
#include<
iostream.h>
stdlib.h>
#defineMAXV50
typedefstruct//顶点类型
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程设计 报告 关键 路径
![提示](https://static.bdocx.com/images/bang_tan.gif)