通信网基础及应用课程设计模板.docx
《通信网基础及应用课程设计模板.docx》由会员分享,可在线阅读,更多相关《通信网基础及应用课程设计模板.docx(15页珍藏版)》请在冰豆网上搜索。
![通信网基础及应用课程设计模板.docx](https://file1.bdocx.com/fileroot1/2023-2/2/1eabd336-315b-48bd-9e5b-6d25fc7b7d90/1eabd336-315b-48bd-9e5b-6d25fc7b7d901.gif)
通信网基础及应用课程设计模板
课程设计说明书NO.1
基于Vc++最短路径Dijkstra算法的实现
1.课程设计的目的
为了巩固“通信网基础及应用”课程学到的相关知识,通过对本课程所学知识的综合运用,使学生融会贯通课程中所学的理论知识,初步掌握通信网络的体系结构和扩频通信系统等相关知识;加深对通信网络的基本理论、基本知识和常用技术的理解;提高学生分析问题的能力和实践能力,培养科学研究的独立工作能力。
2.设计方案论证
2.1问题描述
给定一个带权无向图G=(V,E),其中每条边的权是一个非负实数。
另外,还给定V中的一个项点,称为源。
现在我们要计算从源到所有其他各项点的最短路径长度。
这里的长度是指路上各边权之和。
这个问题通常称为单源最短路径问题。
2.2算法介绍
Dijkstra算法是由荷兰计算机科学家艾兹格•迪科斯彻发现的。
算法解决的是有向图中最短路径问题。
例如,如果图中的顶点表示城市,而边上的权重表示著城市间开车路经的距离。
Dijkstra算法可以用来找到两个城市之间的最短路径。
Dijkstra算法的输入包含了一个有权重的有向图G,以及G中的一个来源顶点S。
我们以V表示G中所有顶点的集合。
每一个图中的边,都是两个顶点所形成的有序元素对。
(u,v)表示从顶点u到v有路径相连。
我们以E所有边的集合,而边的权重则由权重函数w:
E→[0,∞]定义。
因此,w(u,v)就是从顶点u到顶点v的非负花费值(cost)。
边的花费可以想像成两个顶点之间的距离。
任两点间路径的花费值,就是该路径上所有边的花费值总和。
已知有V中有顶点s及t,Dijkstra算法可以找到s到t的最低花费路径(i.e.最短路径)。
这个算法也可以在一个图中,找到从一个顶点s到任何其他顶点的最短路径。
2.3算法描述
这个算法是通过为每个顶点v保留目前为止所找到的从s到v的最短路径来工作的。
初始时,源点s的路径长度值被赋为0(d[s]=0),同时把所有其他顶点的路径长度设为无穷大,即表示我们不知道任何通向这些顶点的路径(对于V中所有顶点v除s外d[v]=∞)。
当算法结束时,d[v]中储存的便是从s到v的最短路径,或者如果路径不存在的话是无穷大。
Dijstra算法的基础操作是边的拓展:
如果存在一条从u到v的边,那么从s到u的最短路径可以通过将边(u,v)添加到尾部来拓展一条从s到v的路径。
这条路径的长度是d[u]+w(u,v)。
如果这个值比目前已知的d[v]的值要小,我们可以用新值来替代当前d[v]中的值。
拓展边的操作一直执行到所有的d[v]都代表从s到v最短路径的花费。
这个算法经过组织因而当d[u]达到它最终的值的时候没条边(u,v)都只被拓展一次。
算法维护两个顶点集S和Q。
集合S保留了我们已知的所有d[v]的值已经是最短路径的值顶点,而集合Q则保留其他所有顶点。
集合S初始状态为空,而后每一步都有一个顶点从Q移动到S。
这个被选择的顶点是Q中拥有最小的d[u]值的顶点。
当一个顶点u从Q中转移到了S中,算法对每条外接边(u,v)进行拓展。
2.4Dijkstra算法计算过程
Dijkstra算法是一种最短路径算法,用于计算一个节点到其它所有节点的最短路。
算法本身并不是按照我们的正常思维习惯,我们一般会,从原点遍历所有与之相连的节点,找到最短路径,再从最短路径上的那个点遍历与之相连的所有其它点(原点除外),然后依次类推。
这样做虽然可以算出一个树形,但是在大多数情况下,这种算法会产生很多次优路径,也就是说非最短路径。
Dijkstra算法的大概过程:
假设两个表,表A和表B
表A表示生成路径,表B表示最后确定的路径
1.从原点出发,遍历检查所有与之相连的节点,将原点和这些节点存放到表A中,并记录下两节点之间的代价。
2.将代价最小的代价值和这两节点移动到表B中(其中一个是原点)。
3.把这个节点所连接的子节点找出,放入到表A中,算出子节点到原点的代价
4.重复第二步和第三步直到表A为空。
然后根据表B中的数据算出最优树。
Dijstra算法的基础操作是边的拓展:
如果存在一条从u到v的边,那么从s到u的最短路径可以通过将边(u,v)添加到尾部来拓展一条从s到v的路径。
这条路径长度d[u]+w(u,v)。
如果这个值比目前已知的d[v]的值要小,我们可以用新值来替代当前d[v]中的值。
拓展边的操作一直执行到所有的d[v]都代表从s到v最短路径的花费。
这个算法经过组织因而当d[u]达到它最终的值的时候没条边(u,v)都只被拓展一次.
Dijkstra算法是解单源最短路径问题的一个算法。
2.5相关问题和算法
在Dijkstra算法的基础上作一些改动,可以扩展其功能。
OSPF(openshortestpathfirst,开放最短路径优先)算法是Dijkstra算法在网络路由中的一个具体实现。
与Dijkstra算法不同,Bellman-Ford算法可用于具有负花费边的图,只要图中不存在总花费为负值且从源点s可达的环路(如果有这样的环路,则最短路径不存在,因为沿环路循环多次即可无限制的降低总花费)。
与最短路径问题有关的一个问题是旅行商问题(travelingsalesmanproblem),它要求找出通过所有顶点恰好一次且最终回到源点的最短路径。
该问题是NP难的;换言之,与最短路径问题不同,旅行商问题不太可能具有多项式时间算法。
如果有已知信息可用来估计某一点到目标点的距离,则可改用A*算法,以减小最短路径的搜索范围。
另外,用于解决最短路径问题的算法被称做“最短路径算法”,有时被简称作“路径算法”。
最常用的路径算法有:
Dijkstra算法
SPFA算法
Bellman-Ford算法
Floyd-Warshall算法
Johnson算法
所谓单源最短路径问题是指:
已知图G=(V,E),我们希望找出从某给定的源结点S∈V到V中的每个结点的最短路径。
3.设计的过程与分析
#include
//定义状态代码及数据类型
#defineNULL0
#defineOK1
#defineERROR0
#defineINFINITY255
#defineMAX_VERTEX_NUM20
typedefintStatus;
typedefintElemType;
//-----------------------队列结构-------------------------
//节点存储结构
typedefstructQNode{
ElemTypedata;
structQNode*next;
}QNode,*QueuePtr;
//队列
typedefstruct{
QueuePtrfront;
QueuePtrrear;
}LinkQueue;
//初始化队列
StatusInitQueue(LinkQueue&Q){
Q.front=Q.rear=newQNode;
if(!
Q.front)
returnERROR;
Q.front->next=NULL;
returnOK;
}
//入队
StatusEnQueue(LinkQueue&Q,ElemTypee){
QueuePtrp=NULL;
p=newQNode;
if(!
p)
returnERROR;
p->data=e;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
returnOK;
}
//出队
StatusDeQueue(LinkQueue&Q,ElemType&e){
QueuePtrp=NULL;
if(Q.front==Q.rear)
returnERROR;
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(Q.rear==p)//注意当出队后为空队的情况
Q.rear=Q.front;
deletep;
returnOK;
}
//判断是否为空队列
StatusEmptyQueue(LinkQueue&Q){
returnQ.front==Q.rear?
true:
false;
}
//复制队列(copyQ1toQ2)
StatusCopyQueue(LinkQueue&Q1,LinkQueue&Q2){
inte;
QueuePtrp;
while(!
EmptyQueue(Q2)){//cleanQ2
DeQueue(Q2,e);
}//copyonebyone
p=Q1.front->next;
while(p){
e=p->data;
p=p->next;
EnQueue(Q2,e);
}
returnOK;
}
//----------------------图的结构:
邻接矩阵(有向网)--------------------------//
//邻接矩阵元素
typedefstructArcCell{
intadj;//arcvalue:
>0,INFINITY:
nolink
char*info;
}AcrCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
//图的结构
typedefstruct{
charvexs[MAX_VERTEX_NUM][5];//顶点数组
AdjMatrixarcs;//邻接矩阵
intvexnum;//图当前的顶点数
intarcnum;//图当前边的个数
}MGraph;
//建立邻接图(key=1为有向网,key=0为无向网)
StatusCreateUDN(MGraph&G,intvexnum,intedgenum,char*names,char*edges,intkey){
inti,j,k,value;
//输入当前图的顶点数,边个数
G.vexnum=vexnum;
G.arcnum=edgenum;
//各个顶点数据
for(i=0;ifor(j=0;j<4;j++){
G.vexs[i][j]=*names;
names++;
}
G.vexs[i][4]='\0';
}
//初始化邻接矩阵(全为INFINITY)
for(i=0;ifor(j=0;jG.arcs[i][j].adj=INFINITY;
G.arcs[i][j].info=NULL;
}
}
//建立邻接矩阵每条边的数值
for(k=0;ki=int(*edges)-48;
edges++;
j=int(*edges)-48;
edges++;
value=(int(*edges)-48)*10;
edges++;
value+=int(*edges)-48;
edges++;
G.arcs[i][j].adj=value;
if(!
key){
G.arcs[j][i].adj=value;
}
}
returnOK;
}
//打印出邻接矩阵
voidPrintGraph(MGraph&G){
inti,j;
cout<<"\n//---------------PrintMatrix-----------------//\n\n";
for(i=0;icout<}
cout<for(i=0;icout<<"\n\n"<for(j=0;jif(G.arcs[i][j].adj==INFINITY)
cout<<"/";
else
cout<<""<}
}
cout<<"\n\n//---------------PrintMatrix-----------------//\n";
}
//----------------------求源点v0到各点的最短路径--------------------------//
voidShortestPath(MGraph&G,intv0){
intD[MAX_VERTEX_NUM],final[MAX_VERTEX_NUM],i,w,v=0,min;
//建立队列数组,用以依次储存最短的路径
LinkQueueQ[MAX_VERTEX_NUM];
//初始化数组
for(i=0;iInitQueue(Q[i]);
D[i]=G.arcs[v0][i].adj;
final[i]=false;
}
final[v0]=true;
//一个一个循环找出最短距离(共vexnum-1个)
for(i=1;imin=INFINITY;
//扫描找出非final集中最小的D[]
for(w=0;wif(!
final[w]&&D[w]v=w;
min=D[w];
}
}
final[v]=true;
//更新各D[]数据
for(w=0;wif(!
final[w]&&G.arcs[v][w].adj+minD[w]=G.arcs[v][w].adj+min;
CopyQueue(Q[v],Q[w]);
EnQueue(Q[w],v);
}
}
}
//打印出结果
cout<<"//---------------ShortestPath-----------------//\n\n";
cout<<"出发地->目的地\t最短距离\t详细路径\n\n";
for(i=0;iif(D[i]!
=INFINITY){
cout<<""<"<cout<while(!
EmptyQueue(Q[i])){
DeQueue(Q[i],v);
cout<<"->"<}
cout<<"->"<}else{
cout<<""<"<\n";
}
}
cout<<"\n//---------------ShortestPath-----------------//\n";
}
voidPrintCity(char*names,intvexnum){
inti,j;
cout<<"列表:
\n\n";
for(i=0;icout<<""<
for(j=0;j<4;j++){
cout<<*names;
names++;
}
cout<<"";
}
cout<<"\n请选择出发地点>";
}
voidmain(){
MGraphG;
//图的结构数据
char*edges,*names;
intvexnum,arcnum,city,kind;
vexnum=6;
arcnum=10;
names="A1A2A3A4A5A6";
edges="0103030505071205150623082403430152085407";
do{
PrintCity(names,vexnum);
cin>>city;
cout<<"\n\n操作:
\n0-无向图列表1-有向图列表\n2-无向图矩阵3-有向图矩阵\n4-选择地点5-退出\n\n请选择操作>";
do{
cin>>kind;
if(kind>=0&&kind<=3){
CreateUDN(G,vexnum,arcnum,names,edges,kind%2);
switch(kind/2){
case0:
ShortestPath(G,city);
break;
case1:
PrintGraph(G);
break;
}
}
cout<<"\n\n操作:
\n0-无向图列表1-有向图列表\n2-无向图矩阵3-有向图矩阵\n4-选择地点5-退出\n\n请选择操作>";
}
while(kind<4);
}
while(kind<5);
}
3.2运行结果
4.设计体会
5.参考文献
沈阳大学
课程设计说明书NO2
沈阳大学
课程设计说明书NO.3
沈阳大学
课程设计说明书NO.4
沈阳大学
课程设计说明书NO.5
沈阳大学
课程设计说明书NO.6
沈阳大学
课程设计说明书NO.7
沈阳大学
课程设计说明书NO.8
沈阳大学
课程设计说明书NO.9
沈阳大学
课程设计说明书NO.10
沈阳大学
课程设计说明书NO.11
沈阳大学
课程设计说明书NO.12
沈阳大学
课程设计说明书NO.13
沈阳大学
课程设计说明书NO.14
沈阳大学
课程设计说明书NO.15
沈阳大学
参考文献要列出3篇以上,格式如下:
[1]谢宋和,甘勇.单片机模糊控制系统设计与应用实例[M].北京:
电子工业出版社,1999.5:
20-25
(参考书或专著格式为:
著者.书名[M].版本(第1版不注).出版地:
出版者,出版年月:
引文所在页码)
[2]潘新民,王燕芳.微型计算机控制技术[M],第2版.北京:
电子工业出版社,2003.4:
305-350
(1本书只能作为1篇参考文献,不能将1本书列为多个参考文献)
[3]范立南,谢子殿.单片机原理及应用教程[M].北京:
北京大学出版社,2006.1:
123-130
[4]NewmanWM,SbroullRF.PrinciplesofInteractiveComputerGraphics[M].NewYork:
McGrawHill,1979.10:
10-25
[5]卜小明,龙全求.一种薄板弯曲问题的四边形位移单元[J].力学学报,1991,23
(1):
53-60
(参考期刊杂志格式为:
作者.论文题目[J].期刊名,出版年,卷号(期号):
页码)(期刊名前不写出版地)
[6]MastriAR.Neuropathyofdiabeticneurogenicbladder[J].AnnInternMed,1980,92
(2):
316-318
[7]范立南,韩晓微,王忠石等.基于多结构元的噪声污染灰度图像边缘检测研究[J].武汉大学学报(工学版),2003,49(3):
45-49
[8]index.asp
(一般情况下不要用网址作为参考文献,如果用,最多1个)
注:
[M]表示参考的是书籍;[J]表示参考的是学术期刊的论文;如果参考会议论文集中的论文用[C]。
要求:
全部打印在A4纸(二本),各级标题四号宋体加粗,正文文字小四号宋体,程序五号timesnewroman,字数3000字以上,15页以上。
严禁抄袭,如有雷同者,均按不及格论处
注:
本页不用打印