课程设计

来源:互联网 发布:上海淘宝公司 编辑:程序博客网 时间:2024/06/01 09:08

一、课程设计目的和要求

(1)目的

1. 了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力;

2. 初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能; 

3. 提高综合运用所学的理论知识和方法独立分析和解决问题的能力; 

4. 训练用系统的观点和软件开发一般规范进行软件开发,培养软件工作者所具备的科学工作方法和作风。

(2)要求

现请根据学校的平面图,找出一些重要的场所,画出学校的平面图(场所可以根据其重要性适当减少),根据实际画出不同点间的路径,并估算每两个场所间的路径长。请设计数据结构并编程,当给出一个出发点和要到达另外一个场所的信息时,请给出最佳路径,并输出路径相关信息。

 

二、系统开发相关情况

(一)开发背景

GDOU是真是一个好地方,校园如一座大花园,美丽而宽广。校园有许多建筑如教学楼、饭堂、宿舍楼、图书馆、体育馆、运动场、商业街、医院等,还有一些著名的风景点。现请根据学校的平面图,找出一些重要的场所,画出学校的平面图(场所可以根据其重要性适当减少),根据实际画出不同点间的路径,并估算每两个场所间的路径长。请设计数据结构并编程,当给出一个出发点和要到达另外一个场所的信息时,请给出最佳路径,并输出路径相关信息。

三、系统及需求分析

(一)需求分析

1、问题描述  图的最短路径问题是指从指定的某一点v开始,求得从该地点到图中其它各地点的最短路径,并且给出求得的最短路径的长度及途径的地点。除了完成最短路径的求解外,还能对该图进行修改,如顶点以及边的增删、边上权值的修改等。 

校园最短路径问题中的数据元素有:

 a)     顶点数

b)     边数

c)     边的长度

四 .逻辑结构设计

1.      抽象数据类型图的定义如下:

ADT Graph{  数据对象V:V是具有相同特性数据元素的集合,称为顶点集。

数据关系R: 

R={VR} 

VR={(v,w)| v , w∈V, (v , w)表示v和w之间存在路径}

基本操作P: 

CreatGraph(&G, V, VR) 

初始条件: V是图的顶点集,VR是图中边的集合。

操作结果: 按定义(V, VR) 构造图G。 

DestroyGraph(&G) 

初始条件: 图G已存在。

操作结果: 销毁图。  LocateVex(G, u)   

初始条件: 图G存在,u和G中顶点具有相同特征。 

操作结果: 若G中存在顶点u,则返回该顶点在图中“位置” ;

否则返回  其它信息。  GetVex(G, v)  

初始条件: 图G存在,v是G中某个顶点。

操作结果: 返回v的信息。  InsertVex(&G, v)  

初始条件: 图G存在,v和G中顶点具有相同特征。

操作结果: 在图G中增添新顶点v。 DeleteVex(&G, v) 

初始条件: 图G存在,v和G中顶点具有相同特征。

操作结果: 删除G中顶点v及其相关的边。 InsertArc(&G, v, w)  

初始条件: 图G存在,v和w是G中两个顶点。 

操作结果: 在G中增添弧<v,w>,若G是无向的,则还增添对称弧<w,v>。 DeleteArc(&G, v, w) 

初始条件: 图G存在,v和w是G中两个顶点。 

操作结果: 在G中删除弧<v,w>,若G是无向的,则还删除对称弧<w,v>。  } ADT Graph 2. 主程序 void main()  {    

初始化;     while(“命令”!=“退出”) {      Switch语句         接受命令(输入选择项序号);        处理命令;    } }

 

 

 

 

 

五.模块设计

 (1)带权无向图


(2)运算方法以及思想

Dijkstra算法:

从起始点 (即源点 )到其它每个顶点 的长度。

例如,D[3] = 2表示从起始点到顶点3的路径相对最小长度为2。这里强调相对就是说在算法执行过程中D的值是在不断逼近最终结果但在过程中不一定就等于长度。

2、D的初始状态为:若从 到 有弧(即从 到 存在连接边),则D 为弧上的权值(即为从 到 的边的权值);否则置D 为∞。

显然,长度为 D =Min{ D | ∈V } 的路径就是从 出发到顶点 的长度最短的一条路径,此路径为()。

3、那么,下一条长度次短的是哪一条呢?也就是找到从源点到下一个顶点的最短路径长度所对应的顶点,且这条最短路径长度仅次于从源点 到顶点 的最短路径长度。

假设该次短路径的终点是 ,则可想而知,这条路径要么是( ),或者是( )。它的长度或者是从 到 的弧上的权值,或者是D 加上从 到 的弧上的权值。

4、一般情况下,假设S为已求得的从源点 出发的最短路径长度的顶点的集合,则可证明:下一条次最短路径(设其终点为 )要么是弧( ),或者是从源点 出发的中间只经过S中的顶点而最后到达顶点 的路径。

因此,下一条长度次短的的最短路径长度必是D = Min{ D | ∈V-S },其中D 要么是弧( )上的权值,或者是D ( ∈S)和弧( , )上的权值之和。

算法描述如下:

1)令arcs表示弧上的权值。若弧不存在,则置arcs为∞(在本程序中为MAXCOST)。S为已找到的从出发的的终点的集合,初始状态为空集。那么,从 出发到图上其余各顶点可能达到的长度的初值为D=arcs[Locate Vex(G, )], ∈V;

2)选择,使得D=Min{ D | ∈V-S } ;

3)修改从出发的到集合V-S中任一顶点的最短路径长度

运算思想:

按路径长度递增次序产生算法:

把顶点集合V分成两组:

(1)S:已求出的顶点的集合(初始时只含有源点V0)

(2)V-S=T:尚未确定的顶点集合

将T中顶点按递增的次序加入到S中,保证:

(1)从源点V0到S中其他各顶点的长度都不大于从V0到T中任何顶点的最短路径长度

(2)每个顶点对应一个距离值

S中顶点:从V0到此顶点的长度

T中顶点:从V0到此顶点的只包括S中顶点作中间顶点的最短路径长度

依据:可以证明V0到T中顶点Vk的,或是从V0到Vk的直接路径的权值;或是从V0经S中顶点到Vk的路径权值之和

(反证法可证)

求最短路径步骤

算法步骤如下:

G={V,E}

1. 初始时令 S={V0},T=V-S={其余顶点},T中顶点对应的距离值

若存在<V0,Vi>,d(V0,Vi)为<V0,Vi>弧上的权值

若不存在<V0,Vi>,d(V0,Vi)为∞

2. 从T中选取一个与S中顶点有关联边且权值最小的顶点W,加入到S中

3. 对其余T中顶点的距离值进行修改:若加进W作中间顶点,从V0到Vi的距离值缩短,则修改此距离值

重复上述步骤2、3,直到S中包含所有顶点,即W=Vi为止

六.运行调试

 

 

七.源代码

#include<stdio.h>

#include <string.h>

#include <stdlib.h>

#define Max 10000

#define NUM 11

 

typedef struct ArcCell{

int adj;

char *info;

}ArcCell;

 

typedef struct VertexType{

int number;

char *sight;

}VertexType;

 

typedef struct{

VertexType vex[NUM]; 

ArcCell arcs[NUM][NUM];

int vexnum,arcnum; 

}MGraph;

 

MGraph G;

int P[NUM][NUM];

long int D[NUM];

int x[13]={0};

void CreateUDN(int v,int a);

void pingmu();

 

void ShortestPath(int num);

void output(int sight1,int sight2);

char Menu();

 

void NextValue(int);

 

void main() // 主函数

{ int v0,v1;

char ck;

 

CreateUDN(NUM,11);

do

{

ck=Menu();

switch(ck)

{

case '1':

pingmu();

printf("\n\n\t\t\t请选择出发地序号(1~10):");

scanf("%d",&v0);

printf("\t\t\t请选择目的地序号(1~10):");

scanf("%d",&v1);

ShortestPath(v0);

output(v0,v1);

printf("/n\n\t\t\t\t请按回车键继续.../n");

getchar();

getchar();

break;

case'2':

 printf("此系统有些简陋,因没太深究/n");

 printf("地点之间的距离非真实,有待探究/n");

 getchar();

getchar();

 break;

};

}while(ck!='e');

}

 

char Menu() // 主菜单

{

char c;

int flag;

do{

flag=1;

pingmu();

printf("\n\t\t****************************************\n");

printf("\t\t欢迎来到广东海洋大学系统\n");

printf("\t\t 1.查询地点路径 \n");

printf("\t\t 2.系统简介\n");

printf("\t\t e.退出\n");

printf("/t/t****************************************/n");

printf("/t/t/t请输入您的选择:");

scanf("%c",&c);

if(c=='1'||c=='2'||c=='e')

flag=0;

}while(flag);

return c;

}

 

void CreateUDN(int v,int a) // 创建图的函数

{

int i,j;

G.vexnum=v;

G.arcnum=a;

for(i=1;i<G.vexnum;++i)G.vex[i].number=i; 

G.vex[0].sight="各个地点名字";

G.vex[1].sight="学校大门";

G.vex[2].sight="东区宿舍 ";

G.vex[3].sight="足球场";

G.vex[4].sight="教学楼";

G.vex[5].sight="体育馆";

G.vex[6].sight="中心广场";

G.vex[7].sight="图书馆";

G.vex[8].sight="物理实验楼";

G.vex[9].sight="西区宿舍";

G.vex[10].sight="西湖";

for(i=1;i<G.vexnum;++i)

{

for(j=1;j<G.vexnum;++j)

{

G.arcs[i][j].adj=Max;

G.arcs[i][j].info=NULL;

}

}

 

 

G.arcs[1][4].adj=G.arcs[4][1].adj=300;

G.arcs[1][2].adj=G.arcs[2][1].adj=300;

G.arcs[1][10].adj=G.arcs[10][1].adj=800;

G.arcs[4][6].adj=G.arcs[6][4].adj=200;

G.arcs[2][5].adj=G.arcs[5][2].adj=300;

G.arcs[5][7].adj=G.arcs[7][5].adj=100;

G.arcs[7][8].adj=G.arcs[8][7].adj=400;

G.arcs[6][9].adj=G.arcs[9][6].adj=800;

G.arcs[6][8].adj=G.arcs[8][6].adj=300;

G.arcs[2][3].adj=G.arcs[3][2].adj=200;

G.arcs[6][7].adj=G.arcs[7][6].adj=100;

G.arcs[6][10].adj=G.arcs[10][6].adj=800;

G.arcs[9][10].adj=G.arcs[10][9].adj=600;

 

}

 

void pingmu() // 输出函数

{

int i;

printf("                           广东海洋大学地点概况\n");

for(i=1;i<NUM;i++)

{

printf("/t/t/t/t(%2d)%-20s/t/t/t",i,G.vex[i].sight);

}

}

 

void ShortestPath(int num) // 迪杰斯特拉算法最短路径

{

int v,w,i,t;

int final[NUM];

int min;

for(v=1;v<NUM;v++)

{

final[v]=0; 

D[v]=G.arcs[num][v].adj;

for(w=1;w<NUM;w++) 

P[v][w]=0;

if(D[v]<32767)

{

P[v][num]=1;

P[v][v]=1; 

}

}

D[num]=0;

final[num]=1;

for(i=1;i<NUM;++i)

{

min=Max; 

for(w=1;w<NUM;++w)

if(!final[w])

if(D[w]<min)

{

v=w;

min=D[w];

}

final[v]=1; 

for(w=1;w<NUM;++w)

if(!final[w]&&((min+G.arcs[v][w].adj)<D[w]))

{

D[w]=min+G.arcs[v][w].adj;

for(t=0;t<NUM;t++)

P[w][t]=P[v][t];

P[w][w]=1;

}

}

}

 

void output(int sight1,int sight2) // 输出函数

{

int a,b,c,d,q=0;

a=sight2; 

if(a!=sight1)

{

printf("\n\t从%s到%s的最短路径是",G.vex[sight1].sight,G.vex[sight2].sight);

printf("\t(最短距离为 %dm.)\n\n\t",D[a]); 

printf("/t%s",G.vex[sight1].sight); 

d=sight1;

for(c=0;c<NUM;++c)

{

gate:;

P[a][sight1]=0;

for(b=0;b<NUM;b++)

{

if(G.arcs[d][b].adj<32767&&P[a][b])

{

printf("-->%s",G.vex[b].sight); 

q=q+1;

P[a][b]=0;

d=b; 

if(q%8==0) printf("/n");

goto gate;

}

}

}

}

}

八.心得总结

  我通过这次课程设计,能把自己所学的知识所表达出来,让我学到的知识记得更加深刻,这样不但训练了我的动手能力,还考验了我的分析能力,虽然做这个设计题目算是简单的了,但是对我来说还是比较吃力,让我深刻的体会到没有认真去学而导致的麻烦,要不停的查书,百度,最后就连个界面都没排版好,想改动一下就调试失败,所以我还是没把界面弄好看,请多多包涵。

0 0