zoukankan      html  css  js  c++  java
  • 实现教科书图7.33的程序(另加孤立顶点台北)(两城市之间的最短路径模拟)

    // algo7-9.cpp 实现教科书图7.33的程序(另加孤立顶点台北)
    #define MAX_NAME 9 // 顶点字符串的最大长度+1
    #define MAX_INFO 20 // 相关信息字符串的最大长度+1
    typedef int VRType;
    typedef char VertexType[MAX_NAME];
    typedef char InfoType;
    #include"c1.h"
    #include"c7-1.h" // 邻接矩阵存储结构
    #include"bo7-1.cpp" // 邻接矩阵存储结构的基本操作
    typedef int PathMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 3维数组
    typedef int DistancMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 2维数组
    #include"func7-2.cpp" // 求有向网中各对顶点之间最短距离的Floyd算法
    void path(MGraph G,PathMatrix P,int i,int j)
    { // 求由序号为i的起点城市到序号为j的终点城市最短路径沿途所经过的城市
    	int k;
    	int m=i; // 起点城市序号赋给m
    	printf("依次经过的城市:
    ");
    	while(m!=j) // 没到终点城市
    	{
    		G.arcs[m][m].adj=INFINITY; // 对角元素赋值无穷大
    		for(k=0;k<G.vexnum;k++)
    			if(G.arcs[m][k].adj<INFINITY&&P[m][j][k]) // m到k有直接通路,且k在m到j的最短路径上
    			{
    				printf("%s ",G.vexs[m]);
    				G.arcs[m][k].adj=G.arcs[k][m].adj=INFINITY; // 将直接通路设为不通
    				m=k; // 经过的城市序号赋给m,继续查找
    				break;
    			}
    	}
    	printf("%s
    ",G.vexs[j]); // 输出终点城市
    }
    void main()
    {
    	MGraph g;
    	int i,j,k,q=1;
    	PathMatrix p; // 3维数组
    	DistancMatrix d; // 2维数组
    	printf("数据文件名为map.txt
    ");
    	CreateFUDN(g); // 通过文件构造无向网g
    	for(i=0;i<g.vexnum;i++)
    		g.arcs[i][i].adj=0; // ShortestPath_FLOYD()要求对角元素值为0,因为两点相同,其距离为0
    	ShortestPath_FLOYD(g,p,d); // 求每对顶点间的最短路径,在func7-2.cpp中
    	while(q)
    	{
    		printf("请选择:1 查询0 结束
    ");
    		scanf("%d",&q);
    		if(q)
    		{
    			for(i=0;i<g.vexnum;i++)
    			{
    				printf("%2d %-9s",i+1,g.vexs[i]);
    				if(i%6==5) // 输出6个数据就换行
    					printf("
    ");
    			}
    			printf("
    请输入要查询的起点城市代码终点城市代码: ");
    			scanf("%d%d",&i,&j);
    			if(d[i-1][j-1]<INFINITY) // 有通路
    			{
    				printf("%s到%s的最短距离为%d
    ",g.vexs[i-1],g.vexs[j-1],d[i-1][j-1]);
    				path(g,p,i-1,j-1); // 求最短路径上由起点城市到终点城市沿途所经过的城市
    			}
    			else
    				printf("%s到%s没有路径可通
    ",g.vexs[i-1],g.vexs[j-1]);
    			printf("与%s到%s有关的p矩阵:
    ",g.vexs[i-1],g.vexs[j-1]);
    			for(k=0;k<g.vexnum;k++)
    				printf("%2d",p[i-1][j-1][k]);
    			printf("
    ");
    		}
    	}
    }

    代码的运行结果:

    数据文件名为map.txt
    请输入数据文件名:map.txt
    请选择:1 查询0 结束
    1
    1 乌鲁木齐2 呼和浩特3 哈尔滨4 西宁5 兰州6 成都
    7 昆明8 贵阳9 南宁10 柳州11 株州12 广州
    13 深圳14 南昌15 福州16 上海17 武汉18 西安
    19 郑州20 徐州21 北京22 天津23 沈阳24 大连
    25 长春26 台北
    请输入要查询的起点城市代码终点城市代码: 1 10
    乌鲁木齐到柳州的最短距离为4694
    依次经过的城市:
    乌鲁木齐兰州西安郑州武汉株州柳州
    与乌鲁木齐到柳州有关的p矩阵:
    1 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0
    请选择:1 查询0 结束
    1
    1 乌鲁木齐2 呼和浩特3 哈尔滨4 西宁5 兰州6 成都
    7 昆明8 贵阳9 南宁10 柳州11 株州12 广州
    13 深圳14 南昌15 福州16 上海17 武汉18 西安
    19 郑州20 徐州21 北京22 天津23 沈阳24 大连
    25 长春26 台北
    请输入要查询的起点城市代码终点城市代码: 21 26
    北京到台北没有路径可通
    与北京到台北有关的p矩阵:
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    请选择:1 查询0 结束
    0

    和algo7-6.cpp 中的ShortestPath_DIJ()类似,algo7-9.cpp 中的ShortestPath_FLOYD()
    也有存放最短路径通过的顶点的数组P。在这里,数组P 是三维的。一维数组P[v][w][]
    中的信息是从顶点v 到顶点w 最短距离所通过的顶点。如P[v][w][u]=1,说明从顶点v
    到顶点w 最短距离通过顶点u。而P[v][w][t]=0,说明从顶点v 到顶点w 最短距离不通
    过顶点t。以上面的程序运行结果为例,D[0][9]是乌鲁木齐到柳州的最短距离,
    P[0][9][]={ 1 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0},对照序号可知,乌鲁木齐到
    柳州的最短距离经过乌鲁木齐、兰州、柳州、株州、武汉、西安和郑州7 个城市。
    为了求得依次经过的城市,调用path()。path()的算法是:对于从顶点v 到顶点w 最
    短距离路径的起点v,它的下一点u 是满足G.arcs[v][u].adj 不是无穷(v 到u 有直接通路)
    同时P[v][w][u]=1(u 在v 到w 的最短路径上)条件的惟一顶点。将G.arcs[v][u].adj 改
    为无穷(避免又回头找v),再从u 找满足G.arcs[u][x].adj 不是无穷(u 到x 有直接通路)
    同时P[v][w][x]=1(x 在v 到w 的最短路径上)条件的惟一顶点x。循环这个过程,直至到
    达终点w。以上程序运行结果验证了path()的作用。

    孤立顶点台北和北京不在同一个连通分量中,故它们之间没有路径可通。对应的一维
    数组P[20][25][]是全0。
    algo7-9.cpp 虽然能够求得任意两城市间的最短路径,但它的DOS 界面总让我们感到
    不方便。我们也可以在可视化的界面下实现algo7-9.cpp 的功能。
    光盘VCshortest 子目录中的软件实现了algo7-9.cpp 的可视化。在Visual C++6.0 环
    境下打开文件VCshortestshortest.dsw,按F7 编译后,按Ctrl+F5 运行,就会出现图
    771 所示界面。


    移动鼠标光标到待查询的起点城市圆圈中并单击鼠标左键,即选定了起点城市。该城
    市的圆圈变成虚线。再移动鼠标光标到待查询的终点城市圆圈中并再次单击鼠标左键,即
    选定了终点城市。这时,从起点城市到终点城市最短距离的沿途城市圆圈及沿线均变成虚
    线,显示出求得的最短路径。同时,在图的右部中间还用文字说明两城市间的最短距离及
    依次经过的城市。
    图772 是运行VCshortest 子目录中的程序并依次用鼠标左键单击南昌和天津的结
    果。这个过程可以反复进行,直到按下“退出”按钮。
    如果没有Visual C++6.0 软件,可将文件VCshortestDebugshortest.exe 和文件
    VCshortestmapvc.txt 拷到硬盘的同一个子目录下,直接运行shortest.exe 即可。
    algo7-9.cpp 的许多函数都嵌到VCshortest 软件中了。有一些根据具体情况做了修
    改。如mapvc.txt 的内容如下:


    26
    30
    乌鲁木齐31 26
    呼和浩特277 86
    哈尔滨607 26
    西宁109 142
    兰州175 154
    成都169 214
    昆明103 282
    贵阳187 274
    南宁187 318
    柳州247 298
    株州307 262
    广州295 322
    深圳355 334
    南昌379 262
    福州445 274
    上海463 218
    武汉349 222
    西安253 170
    郑州337 170
    徐州415 170
    北京385 98
    天津445 114
    沈阳523 90
    大连493 150
    长春565 58

    台北475 318
    乌鲁木齐兰州1892
    呼和浩特兰州1145
    ⋯⋯(以下同数据文件map.txt,故略)

    和algo7-9.cpp 调用的数据文件map.txt 相比,mapvc.txt 中的顶点信息不仅有城市名
    称,还有城市在图中的x、y 坐标。因此,顶点信息用结构体bb 来表示:
    struct bb
    {
    VertexType a;
    int x;
    int y;
    };
    其中,VertexType 仍然是字符串类型,存放城市名称。同时,由文件构造无向网的函
    数CreateFUDN() 也做了相应的修改。求有向网中各对顶点之间最短路径的函数
    ShortestPath_FLOYD()直接用在了程序中。求由起点城市到终点城市最短路径沿途所经过
    城市的函数path()做了修改。
    这个软件主要目的在于说明:在视窗时代,算法和数据结构并没有过时,仍然是软件
    的灵魂。视窗手段能使界面变漂亮,但要想实现众多的复杂功能,还必须依靠算法和数据
    结构。

  • 相关阅读:
    Excel标题与索引的对应关系
    拼接LINQ动态表达式
    根据输入的模型属性表达式获取名称
    如何将页面的<br/>在Excel中正确换行
    针对VM从挂机-启动后,docker相关服务的无法使用问题!
    NIO(三):Selector选择器
    NIO(二):Channel通道
    Netty(一):netty的入门使用。
    设计模式(五):原型模式
    NIO(一):Buffer缓冲区
  • 原文地址:https://www.cnblogs.com/KongkOngL/p/4074446.html
Copyright © 2011-2022 走看看