Floyd算法應用-醫院選址問題

1)問題描述

n個村莊之間的交通圖可以用有向網圖來表示,圖中邊<vi, vj>上的權值表示從村莊i到村莊j的道路長度。現在要從這n個村莊中選擇一個村莊新建一所醫院,問這所醫院應建在哪個村莊,才能使所有的村莊離醫院都比較近?

2) 基本要求

(1) 建立模型,設計存儲結構;

(2) 設計算法完成問題求解;

(3) 分析算法的時間復雜度。

3) 設計思想

醫院選址問題實際是求有向圖中心點的問題。首先定義頂點的偏心度。

設圖G=(VE),對任一頂點k,稱E(k)=max{d(i, k)}(iV)為頂點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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/375985.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/375985.shtml
英文地址,請注明出處:http://en.pswp.cn/news/375985.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

linux ls 命令排序,如何在Linux中使用ls命令按大小對所有文件進行排序

ls命令是列出目錄內容的最流行且非常有用的命令。 在本文中&#xff0c;我們將解釋如何使用ls sort選項按大小列出目錄內容。1)按大小列出目錄中的文件(排序)要列出具有大小排序的特定目錄的內容&#xff0c;我們將使用-lS選項和ls命令。 它將在頂部顯示最大的文件。[linuxidcl…

C?#?獲?取?當?前?時?間?的?各?種?格?式

C#獲取當前時間的各種格式 DateTime.Now.ToShortTimeString() DateTime dt DateTime.Now; dt.ToString();//2005-11-5 13:21:25 dt.ToFileTime().ToString();//127756416859912816 dt.ToFileTimeUtc().ToString();//127756704859912816 dt.ToLocalTime().ToString(…

基于tcp connect的端口掃描程序

原理&#xff1a;connect()函數用于對于每一個感興趣的目標計算機的端口進行連接&#xff0c;如果該端口處于偵聽狀態&#xff0c;那么connect()就會成功&#xff0c;即沒有提供服務。如果對于每一個目標端口以串行的方式使用單獨的connect()調用&#xff0c;需要較長的時間&am…

UIScrollView

一、UIScrollView 1.常見屬性 property(nonatomic) CGPoint contentOffset; // 記錄UIScrollView滾動的位置 property(nonatomic) CGSize contentSize; // 內容尺寸&#xff08;能滾動的范圍&#xff09; property(nonatomic) UIEdgeInsets contentInset; // 額外增加的滾動區域…

linux如何運行多個硬盤,一個硬盤如何裝兩個Linux

1個硬盤已安裝Fedora 8 Linux系統&#xff0c;并安裝grub引導管理程序&#xff0c;現要在這個硬盤的空閑分區中安裝Fedora 9&#xff0c;操作如下&#xff1a;1.將Fedora-9-i386-DVD.iso文件放到一個Windows Fat32分區((hd0,4))的根目錄&#xff0c;將這個iso文件中的isolinux目…

APIO2015 醬油記

Day 0 昨天CTSC才比完&#xff0c;當然是要浪啦&#xff01; 于是浪了一天。。。午飯都沒吃。。。 晚飯。。。貌似也沒吃。。。 晚上的時候覺得這樣子浪不太好&#xff0c;還是要認真一下&#xff0c;打開bzoj&#xff0c;棄療了。。。還是浪吧。。。 Day 1 今天要講課&#xf…

宏定義 #define 和常量 const 的區別

學習筆記&#xff01;參考鏈接 一、類型和安全檢查不同宏定義是字符替換&#xff0c;沒有數據類型的區別&#xff0c;同時這種替換沒有類型安全檢查&#xff0c;可能產生邊際效應等錯誤&#xff1b;const常量是常量的聲明&#xff0c;有類型區別&#xff0c;需要在編譯階段進行…

【ibus】設置ibus輸入法(pinyin sunpinyin)

設置ibus-pinyin 在終端中運行 /usr/lib/ibus-pinyin/ibus-setup-pinyin命令可以調出ibus的完整設置對話框 設置ibus-sunpinyin 可以執行ibus-sunpinyin自帶的python設置腳本ibus-setup-sunpinyin來全面設置它 : $ /usr/lib/ibus-sunpinyin/ibus-setup-sunpinyin 如果執行此腳…

linux 進程 釋放內存,Linux 釋放內存方法和原理

今天驚愕地發現&#xff0c;主節點上8G內存被不知道什么進程吃掉了整整6G有余&#xff0c;正常的計算快要維持不下去了&#xff0c;遂處理之。先看看內存使用狀況[rootnode1 ~]# free -mtotal used free shared buffers cachedMem: 8004 6557 1446 0 163 5630-/ buffers/cache:…

玩轉Win32開發(2):完整的開發流程

上一篇中我給各位說了一般人認為C中較為難的東西——指針。其實對于C&#xff0c;難點當然不局限在指針這玩意兒上&#xff0c;還有一些有趣的概念&#xff0c;如模板類、虛基類、純虛函數等&#xff0c;這些都是概念性的東西&#xff0c;幾乎每一本C書上都會介紹&#xff0c;而…

c++函數傳參:值傳遞、指針傳遞、引用傳遞

1、將變量名作為實參和形參&#xff1a; 這時傳給形參的是變量的值&#xff0c;傳遞是單向的。如果在執行函數期間形參的值發生變化&#xff0c;并不傳回實參。應為在調用函數時&#xff0c;形參和實參不是同一個存儲單元。 2、傳遞變量的指針&#xff1a; 形參是指針變量&a…

贊!帶進度條的 jQuery 文件拖放上傳插件

jQuery File Uploader 是一個 jQuery 文件拖放上傳插件&#xff0c;包括 Ajax 上傳和進度條效果。作者編寫這個插件的想法是要保持它非常簡單&#xff0c;不像其他的插件&#xff0c;很多的標記&#xff0c;并提供一些 Hack 的方式使之兼容那些古老的瀏覽器。jQuery File Uploa…

linux系統有幾個系統盤,linux操作系統的分區有哪些種類?各分區主要作用是什么?...

滿意答案Linux下一切都是文件&#xff0c;不存在分區的概念&#xff0c;在Linux下說的分區只是磁盤管理和數據組織的需要。Linux使用標準的目錄結構&#xff0c;在安裝的時候&#xff0c;安裝程序就已經為用戶創建了文件系統和完整而固定的目錄組成形式&#xff0c;并指定了每個…

::范圍解析運算符

學習筆記&#xff1a;參考鏈接 ::是范圍解析運算符&#xff0c;或者稱為域區分符&#xff0c;用來指明一個函數或一個數據屬于哪一個類。 ::也可以不跟類名&#xff0c;表示全局函數或者全局數據 eg: #include<iostream> using namespace std;int month;//全局變量 i…

渴望

有些時候 還是會覺得很孤獨 因為自己總是一個人 一個人吃飯 一個人學習 一個人生活 心情難免會低落 很想有一個人 可以一直陪伴在自己身邊 一起吃飯 一起學習 一起看潮起潮落 以為自己足夠堅強 可以耐得住很多孤獨 卻總還是會 感覺lonely 很多時候很羨慕 那些大學里的小情侶 雖…

linux中可以安裝不同版本的gcc么,在linux下安裝多個版本的GCC

文章鏈接&#xff1a;http://blog.csdn.net/chid/article/details/6251781很是有用&#xff0c;轉載學習1.查看當前linux版本內核版本&#xff1a;cat /proc/version或者&#xff1a;uname -a2.查看gcc的版本gcc -v或者&#xff1a;gcc --version或者&#xff1a;查看當前安裝的…

Python中如何讀取xml的數據

<?xml version"1.0" encoding"utf-8" ?> - <catalog><maxid>4</maxid> - <login username"pytest" passwd"123456"><caption>Python</caption> - <item id"4"><ca…

C++中private成員變量和protect成員變量的區別

保護成員和私有成員很相似&#xff0c;但是就是在子類中&#xff0c;保護成員可以訪問&#xff0c;而私有成員不能被訪問&#xff0c;也就是說子類中的函數&#xff0c;可以訪問父類中的保護成員變量&#xff0c;而不能訪問私有成員變量&#xff0c;要想訪問父類中的私有成員變…

Linux下C語言串口應用編程,Linux下串口C語言編程

Linux下串口C語言編程 (5頁)本資源提供全文預覽&#xff0c;點擊全文預覽即可全文預覽,如果喜歡文檔就下載吧&#xff0c;查找使用更方便哦&#xff01;9.9 積分串口操作代碼#include #include #include #include #include #include #include #include #include #define BUFFER…

順序查找 折半查找

順序查找 算法描述 順序比較即可。 平均查找長度 (n1)/2, 其中n為表長。 時間復雜度 O(n) #include "stdio.h" typedef struct student{int id; /*學生編號*/char name[10]; /*…