校园导航系统之用弗洛伊德算法求加权图的最短路径

   其实这个示例是在大一数据结构课程设计的时候选的题目,只不过在昨天的算法分析与设计实验课上又看到了求加权图的最短路径,忽然想起当初课程设计时为了弄懂Floyd算法而不断抓狂的过程,觉得有必要将它从邮箱的角落里释放出来,来见证自己一步步的成长。也希望能和大家一起成长。

  啰嗦完了,下面进入正题吧!

  1.系统需求分析:

    1、设计你的学校的校园平面图,所选的景点不少于10个。以图中顶点表示校内各景点,存放景点名称、代号、简介等信息;以边表示路径,存放路径长度等相关信息。

    2、为来往客人提供图中任意景点相关信息的查询。

    3、为来往的客人提供图中任意景点的问路查询,即查询任意两个景点间的一条最短的简单路径

  2.系统功能模块设计

        本系统分为三个模块:菜单模块 、路径查询模块、最短路径模块。得到如图所示的系统功能模块图。

    

  3.算法思想描述将结合源码进行分析

  4.源代码:

  

  1 #include<stdio.h>
  2 #include<string.h>
  3 #define Num 13
  4 #define Maxedge 5000
  5 
  6 typedef struct//定义结构型
  7 {
  8     char name[10] ;
  9     int number;   
 10 }vertex;
 11 vertex ver[Num];
 12 int edge[Num][Num];
 13 int shortest[Num][Num];  
 14 int path[Num][Num];
 15     
 16 void show2()//输出各地点名称
 17 {
 18     int i=1;
 19     
 20     for(i=1;i<=Num;i++)
 21     {
 22         printf("%d---%s\t",i,ver[i].name);
 23     }
 24     printf("\n\n");
 25 }
 26 
 27 void init()//初始化地点和长度
 28 {
 29     int i,j;
 30     ver[1].number =1;
 31     strcpy(ver[1].name,"文学院");
 32     ver[2].number =2;
 33     strcpy(ver[2].name,"学校西门");
 34     ver[3].number =3;
 35     strcpy(ver[3].name,"一号餐厅");
 36     ver[4].number =4;
 37     strcpy(ver[4].name,"溜冰场");
 38     ver[5].number =5;
 39     strcpy(ver[5].name,"喷泉广场");
 40     ver[6].number =6;
 41     strcpy(ver[6].name,"山顶操场");
 42     ver[7].number =7;
 43     strcpy(ver[7].name,"图书馆");
 44     ver[8].number =8;
 45     strcpy(ver[8].name,"十号教学楼");
 46     ver[9].number =9;
 47     strcpy(ver[9].name,"服务楼");
 48     ver[10].number =10;
 49     strcpy(ver[10].name,"体育馆");
 50     ver[11].number =11;
 51     strcpy(ver[11].name,"行政楼");
 52     ver[12].number =12;
 53     strcpy(ver[12].name,"学校北门");
 54     ver[13].number =13;
 55     strcpy(ver[13].name,"水房");
 56 
 57     for(i=1;i<=Num;i++)//初始化每天路径为最大值
 58     {
 59        for(j=1;j<=Num;j++)
 60        {
 61           edge[i][j]=Maxedge;
 62        }
 63     }
 64     //自身到达自身为0
 65     for(i=1;i<=Num;i++)
 66     {
 67         edge[i][i]=0;
 68     }
 69     //为顶点间路径赋值
 70     edge[1][2]=edge[2][1]=20;
 71     edge[1][5]=edge[5][1]=240;
 72     edge[2][3]=edge[3][2]=50;
 73     edge[2][4]=edge[4][2]=15;
 74     edge[2][6]=edge[6][2]=20;
 75     edge[3][4]=edge[4][3]=100;
 76     edge[4][6]=edge[6][4]=70;
 77     edge[4][9]=edge[9][4]=50;
 78     edge[5][6]=edge[6][5]=10;
 79     edge[6][10]=edge[10][6]=340;
 80     edge[6][7]=edge[7][6]=40;
 81     edge[7][8]=edge[8][7]=60;
 82     edge[7][10]=edge[10][7]=50;
 83     edge[8][9]=edge[9][8]=20;
 84     edge[8][11]=edge[11][8]=140;
 85     edge[9][11]=edge[11][9]=260;
 86     edge[10][12]=edge[12][10]=110;
 87     edge[10][13]=edge[13][10]=210;
 88 }
 89 
 90 char show3()//功能选项
 91 {
 92     char i;
 93     printf("\t\t\t           功能菜单\n");
 94     printf("--------------------------------------------------------------------------------");
 95     printf("\t\t\t<1> 查看校园各地点代号请输入 1\n");
 96     printf("\t\t\t<2> 最短路径查询请输入       2\n");
 97     printf("\t\t\t<3> 退出系统请输入           3\n");
 98     printf("--------------------------------------------------------------------------------");
 99     printf("          \t\t^.^ 您的选择:");
100     scanf("%s",&i);
101     return i;
102 }
103 
104 void floyd()//弗洛伊德算法求两点最小权值
105 {
106     int i=1,j=1,k=1,l=1;
107     for(i=1;i<=Num;i++)
108     {
109         for(j=1;j<=Num;j++)
110         {
111             shortest[i][j]=edge[i][j];
112             path[i][j]=0;
113         }
114     }
115     for(k=1;k<=Num;k++)
116     {
117         for(i=1;i<=Num;i++)
118         {
119             for(j=1;j<=Num;j++)
120             {
121                 if(shortest[i][j]>(shortest[i][k]+shortest[k][j]))
122                 {
123                     shortest[i][j]=(shortest[i][k]+shortest[k][j]);
124                     path[i][j]=path[j][i]=k;
125                 }
126             }
127         }
128     }
129 }
130 
131 void show4(int i,int j)//显示最短路径及长度。
132 {
133     int k=0,a=i,b=j;
134     if(shortest[i][j]!=Maxedge)
135     {
136         printf("从 %s 到 %s 的最短路径为:\n",ver[i].name,ver[j].name);
137         printf("%s",ver[i].name);
138         while(path[i][j]!=0)
139         {
140             k=path[i][j];
141             while(path[i][k]!=0)
142             {
143                 k=path[i][k];
144             }
145             printf("----%s",ver[k].name);
146             i=k;
147         }
148         printf("----%s;\n",ver[j].name );
149         printf("最短距离为:%d米。\n",shortest[a][b]);
150     }
151     else
152         printf("从 %s 不能到达 %s 。",ver[i].name ,ver[j].name );
153 }
154 
155 void shortestpath()//功能2:接受两地点并调用Floyd算法生成最短路径矩阵
156 {
157     int i=0,j=0;
158     while(1)
159     {    
160     
161         printf("请输入要查询的两点的编号:(以空格间隔)");
162         scanf("%d%d",&i,&j);
163         if(i<=Num&&i>0&&j<=Num&&j>0)
164         {
165             floyd();
166             show4(i,j);
167             return;
168         }
169     }
170 }
171 
172 void main()//主程序
173 {
174     int z;
175     char i;
176     system("color 5f");//更改窗口颜色
177     init();//初始化参数
178     {
179         printf("\t\t\t    ************************\n");
180         printf("\t\t\t    **河南城建学院校园导航**\n");
181         printf("\t\t\t    ************************\n\n\n\n\n");
182         while(true)//用循环使可以多次选择选项    
183         {
184             i=show3();//调用函数显示功能菜单
185             switch(i)//功能菜单选项
186             {
187                 case '1':show2();break;
188                 case '2':shortestpath();break;
189                 case '3':{
190                     system("cls");printf("\n\n\n\n\n\n\n\n\n\t\t\t\t   谢谢您的使用\n\n\n\t\t\tO(∩_∩)O~~\t\tO(∩_∩)O~~\n\n\n\n\n\n\n\n\n");
191                     system("pause");
192                     exit(0);    //退出程序
193                 }                
194                 default :printf("输入错误!\n");break;
195             }
196         }
197     }
198 }

运行结果:

弗洛伊德算法思想:其实很简单,就是求出所有顶点两两之间的最短路径,如果该两点之间存在第三个顶点构成最短路径,则将该顶点的顶点号存入一个path[][]矩阵中,并将长度赋值给shortest[][]数组中!

其实它的核心代码只有这一段:

 1 for(k=1;k<=Num;k++)
 2     {
 3         for(i=1;i<=Num;i++)
 4         {
 5             for(j=1;j<=Num;j++)
 6             {
 7                 if(shortest[i][j]>(shortest[i][k]+shortest[k][j]))
 8                 {
 9                     shortest[i][j]=(shortest[i][k]+shortest[k][j]);
10                     path[i][j]=path[j][i]=k;
11                 }
12             }
13         }
14     }

  事先定义出两个二维数组,shortest[i][j]中存放的是顶点i到顶点j的最短路径长度。path[i][j]的值存放的是顶点i到顶点j之间最短路径经过的顶点的值,即如果顶点i和顶点j之间存在顶点k,使i到k的距离加上k到j的距离,则将这个最短距离存入shortest[i][j]中,并将path[i][j]的值设为k,这样在寻址最短路径的时候只要根据path[i][j]中的值一步步反推出即可。

posted on 2015-11-08 23:09  走心的猪  阅读(1661)  评论(0编辑  收藏  举报

导航