Floyd算法应用-医院选址问题
1)问题描述
n个村庄之间的交通图可以用有向网图来表示,图中边<vi, vj>上的权值表示从村庄i到村庄j的道路长度。现在要从这n个村庄中选择一个村庄新建一所医院,问这所医院应建在哪个村庄,才能使所有的村庄离医院都比较近?
2) 基本要求
(1) 建立模型,设计存储结构;
(2) 设计算法完成问题求解;
(3) 分析算法的时间复杂度。
3) 设计思想
医院选址问题实际是求有向图中心点的问题。首先定义顶点的偏心度。
设图G=(V,E),对任一顶点k,称E(k)=max{d(i, k)}(i∈V)为顶点k的偏心度。显然,偏心度最小的顶点即为图G的中心点。
如图3(a)所示是一个带权有向图,其各顶点的偏心度如图(b)所示。
4)医院选址问题的算法用伪代码描述如下:
1.对加权有向图,调用Floyd算法,求每对顶点间最短路径长度的矩阵;
2.对最短路径长度矩阵的每列求大值,即得到各顶点的偏心度;
3.具有最小偏心度的顶点即为所求。
5)代码附录
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #define INFINITY 1000000 5 #define MAX_VERTEX_NUM 20 6 7 //定义弧的权值信息 8 typedef struct Arccell 9 { 10 int adj; //权值 11 } Arccell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //图的邻接矩阵 12 //定义结点信息 13 typedef struct VertexInfo 14 { 15 char name[20];//结点[村庄]名称 16 int position;//定点编号 17 } VertexInfo; 18 //图的结构 19 typedef struct Mgraph 20 { 21 VertexInfo vexs[MAX_VERTEX_NUM];//顶点数组 22 AdjMatrix arcs;//邻接矩阵 23 int vernum,arcnum;//分别指定顶点数和边数 24 } Mgraph; 25 26 27 //对图的初始化 28 Mgraph initgraph() 29 { 30 Mgraph c; 31 printf("请输入该图的顶点个数和弧的个数:\n"); 32 printf("顶点个数:"); 33 scanf("%d",&c.vernum); 34 printf("弧的个数:"); 35 scanf("%d",&c.arcnum); 36 //依次设置顶点编号 37 for(int i=0; i<c.vernum; i++) 38 { 39 c.vexs[i].position=i; 40 } 41 //依次输入各顶点信息 42 /* 43 strcpy(c.vexs[0].name,"a"); 44 strcpy(c.vexs[1].name,"b"); 45 strcpy(c.vexs[2].name,"c"); 46 strcpy(c.vexs[3].name,"d"); 47 strcpy(c.vexs[4].name,"e"); 48 49 */ 50 printf("\n请依次输入各个村庄的名称:\n"); 51 for(int i=0;i<c.vernum;i++) 52 { 53 printf("村庄%d:",i); 54 scanf("%s",&c.vexs[i].name); 55 56 } 57 58 //依次设置各弧的信息 59 for(int i=0; i<c.vernum; i++) 60 { 61 //先初始化邻接矩阵,相同点设置为0,其他全部设置为INFINITY(无穷大) 62 for(int j=0; j<c.vernum; j++) 63 { 64 c.arcs[i][j].adj=INFINITY; 65 if(i==j) 66 { 67 c.arcs[i][j].adj=0; 68 } 69 } 70 } 71 //再依次输入需要设置的权值 72 int i,j,k; 73 printf("请输入需要设置的弧长及其两端顶点[输入3个0结束]:\n"); 74 while(scanf("%d%d%d",&i,&j,&k)) 75 { 76 if(i==0&&j==0&k==0) 77 break; 78 c.arcs[i][j].adj=k; 79 } 80 /* 81 c.arcs[0][1].adj=1; 82 c.arcs[1][2].adj=2; 83 c.arcs[2][3].adj=2; 84 c.arcs[2][4].adj=4; 85 c.arcs[3][1].adj=1; 86 c.arcs[3][2].adj=3; 87 c.arcs[4][3].adj=5; 88 */ 89 return c; 90 } 91 92 //输出邻接矩阵 93 void printMatrix(Mgraph c) 94 { 95 printf("该图的邻接矩阵如下所示:\n"); 96 int count=0;//用于计数 97 for(int i=0; i<c.vernum; i++) 98 for(int j=0; j<c.vernum; j++) 99 { 100 if(c.arcs[i][j].adj==INFINITY) 101 printf(" #"); 102 else 103 printf("%4d",c.arcs[i][j].adj); 104 count++; 105 if(count%c.vernum==0) 106 printf("\n"); 107 } 108 } 109 110 void ShortestPath_Floyd(Mgraph G,int dis[][MAX_VERTEX_NUM]) 111 { 112 //用floyd算法求有向网G中各对定点v和w之间的最短路径及其带权长度dis[v][w] 113 for(int v=0; v<G.vernum; v++) 114 for(int w=0; w<G.vernum; w++) 115 { 116 //对各结点之间初始化已知距离 117 dis[v][w]=G.arcs[v][w].adj; 118 } 119 120 for(int u=0; u<G.vernum; u++) 121 for(int v=0; v<G.vernum; v++) 122 for(int w=0; w<G.vernum; w++) 123 { 124 if(dis[v][u]+dis[u][w]<dis[v][w]) 125 { 126 //从v经u到w的路径更短 127 dis[v][w]=dis[v][u]+dis[u][w]; 128 } 129 } 130 131 } 132 //输出距离矩阵 133 void printDis(Mgraph G,int dis[MAX_VERTEX_NUM][MAX_VERTEX_NUM]) 134 { 135 printf("\n经过Flyod算法之后各顶点之间的距离如下:\n"); 136 for(int i=0; i<G.vernum; i++) 137 { 138 for(int j=0; j<G.vernum; j++) 139 { 140 if(dis[i][j]>=1000000) 141 printf(" #"); 142 else 143 printf("%4d",dis[i][j]); 144 145 } 146 printf("\n"); 147 } 148 } 149 150 //得到偏心度degree[]数组 151 void getDegree(Mgraph G,int dis[MAX_VERTEX_NUM][MAX_VERTEX_NUM],int degree[]) 152 { 153 for(int i=0;i<G.vernum;i++) 154 { 155 int max=dis[0][i]; 156 for(int j=0;j<G.vernum;j++) 157 { 158 if(dis[j][i]>max) 159 max=dis[j][i]; 160 } 161 degree[i]=max; 162 } 163 } 164 165 166 167 int main() 168 { 169 printf("**********欢迎使用医院选址系统*********\n"); 170 Mgraph c=initgraph(); 171 system("cls"); 172 173 //输出邻接矩阵 174 getchar(); 175 printMatrix(c); 176 177 //定义距离数组,调用Floyd算法得到结果 178 int dis[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; 179 ShortestPath_Floyd(c,dis); 180 181 //输出各个顶点之间的距离矩阵 182 getchar(); 183 printDis(c,dis); 184 185 //存放偏心度数 186 int degree[c.vernum]; 187 getDegree(c,dis,degree); 188 189 //显示各顶点的偏心度 190 getchar(); 191 printf("\n各顶点的偏心度如下所示:\n"); 192 for(int i=0;i<c.vernum;i++) 193 { 194 if(degree[i]>=1000000) 195 printf(" #\n"); 196 else 197 printf("%4d\n",degree[i]); 198 } 199 200 //得到最小村庄的编号和名称 201 int num; 202 int min=degree[0]; 203 for(int i=0;i<c.vernum;i++) 204 { 205 if(min>degree[i]) 206 min=degree[i]; 207 } 208 209 for(int i=0;i<c.vernum;i++) 210 { 211 if(min==degree[i]) 212 { 213 num=i; 214 break; 215 } 216 } 217 getchar(); 218 printf("\n偏心度最小的村庄编号:%4d\n",num);//输出偏心度最小的村庄编号 219 printf("医院应该建立在村庄: %4s \n",c.vexs[num].name); 220 return 0; 221 222 }
6)测试结果
1.首先运行程序,出现如图6.1所示。
图6.1 程序运行开始界面
2.输入顶点个数和边的个数之后,会提示输入村庄名称,如图6.2所示。
图6.2 提示输入村庄名称界面
3.村庄名称输入结束之后,提示输入边的起始点和权值,如图6.3所示。
图6.3 提示输入边相关信息的界面
4.输入边的信息,以输入0 0 0结束,如图6.4所示。
图6.4 输入边相关信息界面
5.边的信息输入完成之后,回车得到邻接矩阵,如图6.5所示。
图6.5 邻接矩阵表
6.继续回车,得到距离矩阵,如图6.6所示。
图6.6 距离矩阵表
7.回车,得到偏心度表,如图6.7所示。
图6.7 各顶点偏心度
8.最后程序输出医院选址结果,如图6.8所示。
图6.8 最终结果
转载于:https://www.cnblogs.com/wujiyang/p/4491750.html
Floyd算法应用-医院选址问题相关推荐
- FLoyd算法与社区医院选址问题
问题: n个社区之间的交通图用无向加权图表示,现在要从这n个社区中选择一个社区建一所医院,问这所医院应建在哪个社区,能使所有的社区离医院都比较近(能使离医院最远的社区到医院最近) 或能使所有的社区到达 ...
- 用Floyd算法解决选址问题(附完整matlab代码)
以2021年五一建模比赛中的消防站选址为例,此问题为重心性加权最优选址问题.可考虑各区域的出警次数和人口密度,并对其进行加权分析处理. 首先用Floyd算法求出距离矩阵,在考虑出警次数和人口密度的前提 ...
- 基于最短路径的物流中心选址(含Dijksra和Floyd算法)
题目:基于最短路径算法的物流中心选址 要求:包含迪杰斯特拉(Dijkstra)算法和弗洛德(Floyd)算法 最短路算法包含Dijkstra算法和Flody算法,也就是顶点对间的最短路的算法和全部顶点 ...
- 【数据结构】 医院选址
问题描述 在某个镇中包含n个村庄,现要从这n个村庄中选择一个村庄建立一所医院,这所医院应建在哪个村庄,才能使离医院最远的村庄到医院最近?(Floyd算法) 一堆废话 很久没有更新博客了,小白刚刚历经考 ...
- 数据结构案例经验分享--医院选址问题(C语言实现)
数据结构实验案例分享--医院选址问题 问题描述 问题罗列 VexName初始化出现问题 AM_Graph参数传递不成功的问题 最终代码与运行结果展示 问题描述 医院选址问题: n个村庄之间的交通图可以 ...
- 怎么使用计算机算法,浅谈如何在用计算机来更好的实现Floyd算法
[摘 要]本文主要介绍了数学建模中的一个常用的方法(Floyd算法).我们首先介绍了邻接矩阵的定义.其次,阐述了Floyd算法的具体内容以及Floyd算法的改进.最后,给出了Floyd算法的广泛应用, ...
- 数据结构与算法(7-4)最短路径(迪杰斯特拉(Dijkstra)算法、弗洛伊德(Floyd)算法)
目录 一.最短路径概念 二.迪杰斯特拉(Dijkstra)算法(单源最短路径) 1.原理 2.过程 3.代码 三.弗洛伊德(Floyd)算法(多源最短路径) 1.原理 2.存储 3.遍历 4.代码 参 ...
- 【POJ/算法】 3259 Wormholes(Bellman-Ford算法, SPFA ,FLoyd算法)
Bellman-Ford算法 Bellman-Ford算法的优点是可以发现负圈,缺点是时间复杂度比Dijkstra算法高.而SPFA算法是使用队列优化的Bellman-Ford版本,其在时间复杂度和编 ...
- 最小环算法求解(Dijkstra算法+Floyd算法)
方法一: #include<iostream> #include<algorithm> #include<cmath> #include<cstdio> ...
最新文章
- opencv打开raw格式图像
- python在哪下载-python在哪里下载
- java中hashMap的排序
- Java注释@interface的用法【转】
- Shell编程 ——for循环、if语句、sleep睡眠。——每秒钟生成一个文件,一共生成60个文件
- java 数据库查询Date类型字段 没有了时分秒 全为 00 的解决办法
- 信息论霍夫曼编码c语言,Huffman 信息论与编码 - 下载 - 搜珍网
- nsq php,NSQ 最佳实践
- 转-squid介绍及其简单配置
- ch8 ProviderDemo
- 计算机网络管理员考试真题,2020年计算机软考网络管理员测试题及答案(20200810164142)...
- 是否开启谷歌Ad广告中的搜索网络合作伙伴?
- linux中vim编译器中复制粘贴,编辑器 - 如何从(并复制到)系统剪贴板进行vim粘贴?...
- CSS 网格 Gird 布局
- Lipschitz连续,一致连续
- Intel 英特尔CPU带字母
- 2022年ABC123公众号年刊下载(PDF电子书)
- C# 构造器-实例构造器,类型构造器
- 网上购车平台上私户,不一样的上私户购车体验
- Java快速开发之代码生成器
热门文章
- [收藏] Opera鼠标手势命令
- Why you have so few friends?
- 使用Hamcrest增强JUnit的测试能力
- Android应用中Back键的监听及处理
- 公用机房计算机主板选购,才知道,IDC机房运维工作居然可以如此简单!
- mexw32与mexw64
- C++判断文件夹是否存在
- 91.91p10.space v.php,luogu P1091 合唱队形
- Python应用实战-Pandas 计算连续行为天数的几种思路
- 趣话题:git三部曲(二)-拆分历史提交记录reset