·背景 ios
在大部分數據結構的講義中,圖通常出如今第7章。惋惜當年沒好好學,如今從新拿出來啃一遍。印象中很多老師對於該章節都填鴨式的帶過或者擺在最後開講,也許由於當年LBS並不流行。在其章節後的是一些排序和管理,但就概念複雜度或者封裝流行度而言,圖仍是更難一點。若是僅靠僞代碼,須要更長的時間來消化。圖,也許就像遊戲中的最終BOSS同樣,其恐懼、神祕、優雅、傳說仍是吸引着衆多Fans們趨之若鶩。這兩天邊回憶、邊吃飯、邊吐血、邊洗澡把最經常使用的一些觀點從新筆記下來,但其實也只是冰山一角。 c++
·分解 算法
歷經百年,圖的構成和運用已經遍及生活,其中歐洲人對於這塊的貢獻最大。整個圖衍生出多個發展方向,以下圖所示: 數組
底層的圖是一個大概念,若是沒什麼特別需求,能夠理解就是咱們的地圖,只不過它更原始一點,更蒼白一點,就一些線和點。 網絡
往上一層,分解出了有向、無向。也就是有沒有箭頭的區別,單行道、雙行道的區別。 數據結構
往上一層,分解出了權值。也就是這條路好很差走,要花多大代價走這條路。 ide
往上一層,分解出了基於圖應用算法。有一些基本的算法實際上是通用的,筆者就目前流行的趨勢稍微歸一下類。 this
·基本遍歷:DFS、BFS。一個按前序遍歷,一個按層序遍歷。幫助入門,缺點上:凡是遍歷過的再也不觸碰,容易致使變形數。 spa
·最小生成樹:Prim、Kruskal。常常會聽搞網絡的同窗提及,固然聽到這個詞語的時候,但後面兩個名詞不多聽到,其實就是它們。通常來講,聽到時候,多數是有人插錯網線成環了。 3d
·最短路徑:Dijkstra。名字很難念,不少應用的看家法寶。其餘還有一些算法就不舉例了。缺點上,通常只給告終果,要想知道過程(路由明細),還須要再加工。
·強連通:Tarjen。一個找強連通的份量的算法,兩兩互聯稱爲強連通。但具體能幹什麼用,還沒想通,分類?機學?後續待研究。
·圖匹配:匈牙利算法:二分圖的最大匹配經常使用算法,同上,後續待研究。
·前三項算法的舉例
原理就很少寫了,網上都有,這裏就邊貼代碼邊分析。
·DFS:
1 #include <iostream> 2 #include <sstream> 3 #include <fstream> 4 #include <stdlib.h> 5 #include <string.h> 6 #include <vector> 7 #include <typeinfo> 8 #include <set> 9 #include <stack> 10 11 12 using namespace std; 13 14 typedef string VertexType; //頂點類型應由用戶定義 15 typedef int EdgeType; //邊上的權值類型應由用戶定義 16 typedef int Boolean; 17 18 //最大頂點數,應由用戶定義 19 #define INF -1 //用-1來表明無窮大 20 #define DEBUG 21 #define TRUE 1 22 #define FALSE 0 23 24 25 typedef struct 26 { 27 VertexType vexs[5]; //頂點表 28 EdgeType arc[5][5]; //鄰接矩陣,可看做邊 29 int numVertexes, numEdges; //圖中當前的頂點數和邊數 30 } Graph; 31 32 typedef struct 33 { 34 char d1[2]; 35 char d2[2]; 36 int wv; 37 } Wing; 38 39 typedef struct 40 { 41 vector<string> v1; 42 vector<string> v2; 43 vector<int> v3; 44 } Route; 45 46 Boolean visited[5]; //訪問標誌數組 47 Route *r; //路由表 48 int rp=0; //路由表長度 49 stack<string> minroute; //最短路徑棧 50 51 52 int locates(Graph *g, string sch); 53 void init(Graph *g); 54 void printGraph(Graph g); 55 void CreateGraph(Graph *g,Wing *ww,vector<string> &v); 56 void DFS(Graph g, int i,vector<string> &v); 57 void DFSclear(Graph g,vector<string> &v); 58 void DFSR(Graph g, int i, vector<string> &v,Route *r,stack<string> &stk); 59 60 61 int main() 62 { 63 //放原始圖 64 Wing *w=NULL; 65 w=(Wing*)malloc(sizeof(Wing)*6); 66 67 68 //讀原始圖 69 std::ios::sync_with_stdio(false); 70 string line; 71 string filename="./tu004.cfg"; 72 ifstream ifs; 73 ifs.open(filename.c_str()); 74 int i=0; 75 set<string> v2; 76 vector<string> v1; //遍歷線序 77 while(getline(ifs,line)) 78 { 79 istringstream strstm(line); 80 string str1,str2,str3; 81 strstm>>str1>>str2>>str3; 82 strcpy((w+i)->d1,str1.c_str()); 83 strcpy((w+i)->d2,str2.c_str()); 84 (w+i)->wv=atoi(str3.c_str()); 85 v2.insert(str1); 86 v2.insert(str2); 87 i++; 88 } 89 90 //鄰接矩陣建立圖和頂點數組枚舉建立 91 Graph g; 92 93 set<string>::iterator v2_it; 94 for(v2_it=v2.begin();v2_it!=v2.end();v2_it++) 95 { 96 v1.push_back(*v2_it); 97 } 98 99 //設置頂點和邊上限 100 g.numVertexes=5; 101 g.numEdges=6; 102 103 //開始幹活 104 init(&g); 105 CreateGraph(&g,w,v1); 106 printGraph(g); 107 108 //結束 109 free(w); 110 111 //DFS 深度優先全遍歷 112 /* 113 for(int i=0;i<5;i++) 114 { 115 DFSclear(g,v1); 116 DFS(g,i,v1); 117 for(int j=0;j<5;j++) 118 cout<<v1[j]<<" "; 119 cout<<"---------------------------------------------------------------------"<<endl; 120 121 } 122 */ 123 124 //DFS 深度優先,輸出路由表 125 r=(Route*)malloc(sizeof(Route)*6); 126 DFSclear(g,v1); 127 DFSR(g,2,v1,r,minroute); 128 for(int j=0;j<5;j++) 129 cout<<v1[j]<<" "; 130 cout<<"\n---------------------------------------------------------------------"<<endl; 131 132 //打印路由表 133 for(int j=0;j<rp;j++) 134 cout<<r->v1[j]<<":"<<r->v2[j]<<":"<<r->v3[j]<<endl; 135 136 cout<<"\n---------------------------------------------------------------------"<<endl; 137 138 //打印最短路徑 139 while(minroute.size()>0) 140 { 141 cout<<minroute.top()<<endl; 142 minroute.pop(); 143 } 144 } 145 146 147 void DFSR(Graph g, int i, vector<string> &v,Route *r, stack<string> &stk) 148 { 149 cout<<"進入遍歷中"<<i<<":"; 150 stk.push(g.vexs[i]); 151 v.push_back(g.vexs[i]); 152 int j; 153 visited[i] = TRUE; 154 cout<<" 頂點:"<<g.vexs[i]<<endl; 155 for(j = 0; j < g.numVertexes; j++) 156 { 157 cout<<"\t遍歷點:"<<j<<"的狀態"<<visited[j]<<" "<<"g.arc的值"<<g.arc[i][j]<<endl; 158 if(g.arc[i][j] == 1 && !visited[j]) 159 { 160 cout<<"\t\t\t\t 準備進入下一點:"<<j<<endl; 161 cout<<"\t\t\t\t\t\t "<<i<<":"<<j<<":"<<g.arc[i][j]<<endl; 162 r->v1.push_back(g.vexs[i]); 163 r->v2.push_back(g.vexs[j]); 164 r->v3.push_back(g.arc[i][j]); 165 rp++; 166 DFSR(g,j,v,r,stk); //對爲訪問的鄰接頂點遞歸調用 167 } 168 } 169 if(stk.top()=="3") 170 { 171 cout<<"完成最短路徑"<<endl; 172 } 173 else 174 { 175 stk.pop(); 176 } 177 cout<<"結束本次"<<i<<"遍歷"<<endl; 178 } 179 180 181 182 void DFS(Graph g, int i, vector<string> &v) 183 { 184 cout<<"進入遍歷中"<<i<<":"; 185 v.push_back(g.vexs[i]); 186 int j; 187 visited[i] = TRUE; 188 cout<<" 頂點:"<<g.vexs[i]<<endl; 189 //printf("%s ", g.vexs[i].c_str()); //打印頂點,也能夠其餘操做 190 for(j = 0; j < g.numVertexes; j++) 191 { 192 cout<<"\t遍歷點:"<<j<<"的狀態"<<visited[j]<<" "<<"g.arc的值"<<g.arc[i][j]<<endl; 193 if(g.arc[i][j] == 1 && !visited[j]) 194 { 195 cout<<"\t\t\t\t 準備進入下一點:"<<j<<endl; 196 cout<<"\t\t\t\t\t\t "<<i<<":"<<j<<":"<<g.arc[i][j]<<endl; 197 DFS(g,j,v); //對爲訪問的鄰接頂點遞歸調用 198 } 199 } 200 cout<<"結束本次"<<i<<"遍歷"<<endl; 201 } 202 203 204 205 206 207 void DFSclear(Graph g,vector<string> &v) 208 { 209 int i; 210 cout<<endl; 211 cout<<"初始化全部頂點狀態都是未訪問過狀態"<<endl; 212 for(i = 0; i < g.numVertexes; i++) 213 { 214 visited[i] = FALSE; //初始化全部頂點狀態都是未訪問過狀態 215 } 216 v.clear(); 217 } 218 219 220 221 222 void CreateGraph(Graph *g,Wing *ww,vector<string> &v) 223 { 224 printf("剛纔輸入頂點數和邊數爲:%d %d\n", g->numVertexes, g->numEdges); 225 //設置頂點數組 226 for(int i=0;i<g->numVertexes;i++) 227 { 228 g->vexs[i]=v[i]; 229 cout<<g->vexs[i]<<" "; 230 //printf("%s ",g->vexs[i].c_str()); 231 } 232 cout<<endl; 233 234 235 //矩陣賦值 236 for(int k=0;k<6;k++) 237 { 238 int m=-1; 239 int n=-1; 240 m = locates(g,(ww+k)->d1); 241 n = locates(g,(ww+k)->d2); 242 243 if(n == -1 || m == -1) 244 { 245 fprintf(stderr, "there is no this vertex.\n"); 246 return; 247 } 248 //printf("m=%d,n=%d\n",m,n); 249 g->arc[m][n] = (ww+k)->wv; 250 g->arc[n][m] = g->arc[m][n]; 251 } 252 253 } 254 255 void init(Graph *g) 256 { 257 for(int i=0;i<g->numVertexes;i++) 258 for(int j=0;j<g->numVertexes;j++) 259 { 260 g->arc[i][j]=0; 261 } 262 } 263 264 265 266 int locates(Graph *g,string sch) 267 { 268 int i = 0; 269 for(i = 0; i < g->numVertexes; i++) 270 { 271 if(g->vexs[i] == sch) 272 { 273 break; 274 } 275 } 276 if(i >= g->numVertexes) 277 { 278 return -1; 279 } 280 return i; 281 } 282 283 void printGraph(Graph g) 284 { 285 printf("開始打印\n"); 286 int i, j; 287 for(i = 0; i < g.numVertexes; i++) 288 { 289 for(j = 0; j < g.numVertexes; j++) 290 { 291 printf("%d ", g.arc[i][j]); 292 } 293 printf("\n"); 294 } 295 }
結果:
=================================================================================
·Prim:
原Prim算法中用的For遍歷,我稍微改了一下,走嵌套,每一個次只選擇兩個分支最爲待選拓撲分支。
1 #include <iostream> 2 #include <sstream> 3 #include <fstream> 4 #include <stdlib.h> 5 #include <string.h> 6 #include <vector> 7 #include <typeinfo> 8 #include <set> 9 #include <stack> 10 #include <map> 11 12 13 14 using namespace std; 15 16 typedef string VertexType; //頂點類型應由用戶定義 17 typedef int EdgeType; //邊上的權值類型應由用戶定義 18 typedef int Boolean; 19 20 #define DM 6 //頂點數 21 #define WM 8 //邊數 22 #define INF -1 //用-1來表明無窮大 23 #define DEBUG 24 #define TRUE 1 25 #define FALSE 0 26 27 28 typedef struct 29 { 30 VertexType vexs[DM]; //頂點表 31 EdgeType arc[DM][DM]; //鄰接矩陣,可看做邊 32 int numVertexes, numEdges; //圖中當前的頂點數和邊數 33 } Graph; 34 35 typedef struct 36 { 37 char d1[2]; 38 char d2[2]; 39 int wv; 40 } Wing; 41 42 typedef struct 43 { 44 vector<string> v1; 45 vector<string> v2; 46 vector<int> v3; 47 } Route; 48 49 Boolean visited[DM]; //訪問標誌數組 50 Route *r; //路由表 51 int rp=0; //路由表長度 52 stack<string> mrs; //最短路徑棧 53 54 55 int locates(Graph *g, string sch); 56 void init(Graph *g); 57 void printGraph(Graph g); 58 void CreateGraph(Graph *g,Wing *ww,vector<string> &v); 59 void DFS(Graph g, int i,vector<string> &v); 60 void DFSclear(Graph g,vector<string> &v); 61 void DFSR(Graph g, int i, vector<string> &v,Route *r,stack<string> &stk); 62 void Prim(Graph g,int i); 63 64 65 int main() 66 { 67 //放原始圖 68 Wing *w=NULL; 69 w=(Wing*)malloc(sizeof(Wing)*8); 70 71 72 //讀原始圖 73 std::ios::sync_with_stdio(false); 74 string line; 75 string filename="./tu007.cfg"; 76 ifstream ifs; 77 ifs.open(filename.c_str()); 78 int i=0; 79 set<string> v2; 80 vector<string> v1; //遍歷線序 81 while(getline(ifs,line)) 82 { 83 istringstream strstm(line); 84 string str1,str2,str3; 85 strstm>>str1>>str2>>str3; 86 strcpy((w+i)->d1,str1.c_str()); 87 strcpy((w+i)->d2,str2.c_str()); 88 (w+i)->wv=atoi(str3.c_str()); 89 v2.insert(str1); 90 v2.insert(str2); 91 i++; 92 } 93 94 //鄰接矩陣建立圖和頂點數組枚舉建立 95 Graph g; 96 97 set<string>::iterator v2_it; 98 for(v2_it=v2.begin();v2_it!=v2.end();v2_it++) 99 { 100 v1.push_back(*v2_it); 101 } 102 103 //設置頂點和邊上限 104 g.numVertexes=DM; 105 g.numEdges=WM; 106 107 //開始幹活 108 init(&g); 109 CreateGraph(&g,w,v1); 110 printGraph(g); 111 112 //結束 113 free(w); 114 115 //開始Prim算法 116 DFSclear(g,v1); 117 Prim(g,2); 118 } 119 120 121 void Prim(Graph g,int i) 122 { 123 cout<<"進入遍歷中"<<i<<":"<<endl; 124 visited[i] = TRUE; 125 int mn=999; 126 map<int,int> a; 127 for(int j = 0; j < g.numVertexes; j++) 128 { 129 cout<<visited[j]<<" "; 130 if(g.arc[i][j]>0 && !visited[j]) 131 { 132 a[g.arc[i][j]]=j; 133 } 134 } 135 map<int,int>::iterator a_it=a.begin(); 136 137 cout<<endl; 138 for(a_it;a_it!=a.end();a_it++) 139 { 140 cout<<"*權值列表="<<a_it->first<<" NEXT:"<<a_it->second<<endl; 141 } 142 143 a_it=a.begin(); 144 145 cout<<"\t權值="<<a_it->first<<" NEXT:"<<a_it->second<<" MAP SIZE:"<<a.size()<<endl; 146 147 if(a.size()>0) 148 { 149 if(a_it->first>0 && !visited[a_it->second]) 150 { 151 cout<<"\t進入下一步:"<<a_it->second<<endl; 152 Prim(g,a_it->second); 153 } 154 a_it++; 155 if(a_it->first>0 && !visited[a_it->second]) 156 { 157 cout<<"\t進入下一步:"<<a_it->second<<endl; 158 Prim(g,a_it->second); 159 } 160 } 161 162 cout<<"開始返回:"<<i<<endl; 163 } 164 165 166 void DFSR(Graph g, int i, vector<string> &v,Route *r, stack<string> &stk) 167 { 168 cout<<"進入遍歷中"<<i<<":"; 169 stk.push(g.vexs[i]); 170 v.push_back(g.vexs[i]); 171 int j; 172 visited[i] = TRUE; 173 cout<<" 頂點:"<<g.vexs[i]<<endl; 174 for(j = 0; j < g.numVertexes; j++) 175 { 176 cout<<"\t遍歷點:"<<j<<"的狀態"<<visited[j]<<" "<<"g.arc的值"<<g.arc[i][j]<<endl; 177 if(g.arc[i][j] == 1 && !visited[j]) 178 //if(g.arc[i][j] == 1 ) 179 { 180 cout<<"\t\t\t\t 準備進入下一點:"<<j<<endl; 181 cout<<"\t\t\t\t\t\t "<<i<<":"<<j<<":"<<g.arc[i][j]<<endl; 182 r->v1.push_back(g.vexs[i]); 183 r->v2.push_back(g.vexs[j]); 184 r->v3.push_back(g.arc[i][j]); 185 rp++; 186 DFSR(g,j,v,r,stk); //對爲訪問的鄰接頂點遞歸調用 187 } 188 } 189 190 if(stk.top()=="5") 191 { 192 cout<<"完成最短路徑"<<endl; 193 } 194 else 195 { 196 stk.pop(); 197 } 198 cout<<"結束本次"<<i<<"遍歷"<<endl; 199 200 } 201 202 203 204 void DFS(Graph g, int i, vector<string> &v) 205 { 206 cout<<"進入遍歷中"<<i<<":"; 207 v.push_back(g.vexs[i]); 208 int j; 209 visited[i] = TRUE; 210 cout<<" 頂點:"<<g.vexs[i]<<endl; 211 //printf("%s ", g.vexs[i].c_str()); //打印頂點,也能夠其餘操做 212 for(j = 0; j < g.numVertexes; j++) 213 { 214 cout<<"\t遍歷點:"<<j<<"的狀態"<<visited[j]<<" "<<"g.arc的值"<<g.arc[i][j]<<endl; 215 if(g.arc[i][j] == 1 && !visited[j]) 216 { 217 cout<<"\t\t\t\t 準備進入下一點:"<<j<<endl; 218 cout<<"\t\t\t\t\t\t "<<i<<":"<<j<<":"<<g.arc[i][j]<<endl; 219 DFS(g,j,v); //對爲訪問的鄰接頂點遞歸調用 220 } 221 } 222 cout<<"結束本次"<<i<<"遍歷"<<endl; 223 } 224 225 226 227 228 229 void DFSclear(Graph g,vector<string> &v) 230 { 231 int i; 232 cout<<endl; 233 cout<<"初始化全部頂點狀態都是未訪問過狀態...."<<endl; 234 for(i = 0; i < g.numVertexes; i++) 235 { 236 visited[i] = FALSE; //初始化全部頂點狀態都是未訪問過狀態 237 } 238 v.clear(); 239 } 240 241 242 243 244 void CreateGraph(Graph *g,Wing *ww,vector<string> &v) 245 { 246 #ifdef DEBUG 247 printf("剛纔輸入頂點數和邊數爲:%d %d\n", g->numVertexes, g->numEdges); 248 #endif 249 //設置頂點數組 250 for(int i=0;i<g->numVertexes;i++) 251 { 252 g->vexs[i]=v[i]; 253 cout<<g->vexs[i]<<" "; 254 //printf("%s ",g->vexs[i].c_str()); 255 } 256 cout<<endl; 257 258 259 //矩陣賦值 260 for(int k=0;k<WM;k++) 261 { 262 int m=-1; 263 int n=-1; 264 m = locates(g,(ww+k)->d1); 265 n = locates(g,(ww+k)->d2); 266 267 if(n == -1 || m == -1) 268 { 269 fprintf(stderr, "there is no this vertex.\n"); 270 return; 271 } 272 //printf("m=%d,n=%d\n",m,n); 273 g->arc[m][n] = (ww+k)->wv; 274 g->arc[n][m] = g->arc[m][n]; 275 } 276 277 } 278 279 void init(Graph *g) 280 { 281 for(int i=0;i<g->numVertexes;i++) 282 for(int j=0;j<g->numVertexes;j++) 283 { 284 g->arc[i][j]=0; 285 } 286 } 287 288 289 290 int locates(Graph *g,string sch) 291 { 292 int i = 0; 293 for(i = 0; i < g->numVertexes; i++) 294 { 295 if(g->vexs[i] == sch) 296 { 297 break; 298 } 299 } 300 if(i >= g->numVertexes) 301 { 302 return -1; 303 } 304 return i; 305 } 306 307 void printGraph(Graph g) 308 { 309 printf("開始打印\n"); 310 int i, j; 311 for(i = 0; i < g.numVertexes; i++) 312 { 313 for(j = 0; j < g.numVertexes; j++) 314 { 315 printf("%d ", g.arc[i][j]); 316 } 317 printf("\n"); 318 } 319 }
結果:
=================================================================================
·Dijkstra:
原Dijkstra算法實現,只打印了最短路徑結果,但我的以爲中間過程明細更重要,稍微改了一下。
1 #include <iostream> 2 #include <sstream> 3 #include <fstream> 4 #include <stdlib.h> 5 #include <string.h> 6 #include <vector> 7 #include <typeinfo> 8 #include <set> 9 10 11 using namespace std; 12 13 typedef string VertexType; //頂點類型應由用戶定義 14 typedef int EdgeType; //邊上的權值類型應由用戶定義 15 16 #define DM 6 //頂點數 17 #define BM 8 //邊數 18 #define INF 9999999 //用9999999來表明無窮大 19 #define DEBUG 20 21 22 typedef struct 23 { 24 VertexType vexs[DM]; //頂點表 25 EdgeType arc[DM][DM]; //鄰接矩陣,可看做邊 26 int numVertexes, numEdges; //圖中當前的頂點數和邊數 27 } Graph; 28 29 typedef struct 30 { 31 char d1[2]; 32 char d2[2]; 33 int wv; 34 } Wing; 35 36 typedef struct 37 { 38 int r_id; 39 int src; 40 int des; 41 double ww; 42 } Rd; 43 44 int locates(Graph *g, string sch); 45 void init(Graph *g); 46 void printGraph(Graph g); 47 void CreateGraph(Graph *g,Wing *ww,vector<string> &v); 48 void DIJ(Graph g,int src,Rd rtt[]); 49 50 int main() 51 { 52 //放原始圖 53 Wing *w=NULL; 54 w=(Wing*)malloc(sizeof(Wing)*BM); 55 56 57 //讀原始圖 58 std::ios::sync_with_stdio(false); 59 string line; 60 string filename="./tu008.cfg"; 61 ifstream ifs; 62 ifs.open(filename.c_str()); 63 int i=0; 64 set<string> v2; 65 while(getline(ifs,line)) 66 { 67 istringstream strstm(line); 68 string str1,str2,str3; 69 strstm>>str1>>str2>>str3; 70 strcpy((w+i)->d1,str1.c_str()); 71 strcpy((w+i)->d2,str2.c_str()); 72 (w+i)->wv=atoi(str3.c_str()); 73 v2.insert(str1); 74 v2.insert(str2); 75 i++; 76 } 77 78 //鄰接矩陣建立圖和頂點數組枚舉建立 79 Graph g; 80 vector<string> v1; 81 82 set<string>::iterator v2_it; 83 for(v2_it=v2.begin();v2_it!=v2.end();v2_it++) 84 { 85 v1.push_back(*v2_it); 86 } 87 88 //設置頂點和邊上限 89 g.numVertexes=DM; 90 g.numEdges=BM; 91 92 //開始幹活 93 init(&g); 94 CreateGraph(&g,w,v1); 95 printGraph(g); 96 97 //結束 98 free(w); 99 100 //拓撲最短路徑 101 Rd route[10]; 102 DIJ(g,0,route); 103 104 } 105 106 107 void DIJ(Graph g, int src,Rd rtt[]) 108 { 109 int idMin = 0; 110 double dMin = 0; 111 double dTempMin = 0; 112 int rtc=0; //路由表計數 113 114 //距離定義,訪問標記 115 double dDist[DM] = {0}; 116 bool bFinalSet[DM] = {false}; 117 118 for (int i=0;i<DM;i++) 119 { 120 bFinalSet[i] = false; 121 dDist[i] = g.arc[src][i]; 122 //cout<<i<<":"<<bFinalSet[i]<<":"<<dDist[i]<<endl; 123 cout<<"Route Detail:"<<src<<"-->"<<i<<","<<dDist[i]<<endl; 124 //初始化路由表 125 126 rtt[i].r_id=i; 127 rtt[i].src=src; 128 rtt[i].des=i; 129 rtt[i].ww=dDist[i]; 130 rtc=i; 131 132 } 133 134 cout<<endl; 135 136 //起點定義 137 dDist[src]= 0; 138 bFinalSet[src] = true; 139 140 for (int j=1;j<DM;j++) 141 { 142 //打印路由表 143 cout<<"打印路由表共"<<rtc+1<<"條:"<<endl; 144 for(int z=0;z<=rtc;z++) 145 { 146 cout<<rtt[z].r_id<<":"<<rtt[z].src<<":"<<rtt[z].des<<":"<<rtt[z].ww<<endl; 147 } 148 149 //開始遍歷 150 dMin = INF; 151 cout<<"--------------------------------"<<endl; 152 for (int k=0; k<DM;k++) 153 { 154 if ((!bFinalSet[k]) && (dDist[k] <= dMin)) 155 { 156 cout<<"Round:"<<j<<"|k="<<k<<" dDist["<<k<<"]="<<dDist[k]<<endl; 157 idMin = k; 158 dMin = dDist[k]; 159 } 160 } 161 bFinalSet[idMin] = true; 162 cout<<"Round:"<<j<<"|最短路徑 "<<src<<" and idMin="<<idMin<<" is:dMin="<<dMin<<endl; 163 164 for (int l=0;l<DM;l++) 165 { 166 dTempMin = dMin + g.arc[idMin][l]; 167 // cout<<"Round:"<<j<<"|g.arc["<<idMin<<"]["<<l<<"]:"<<g.arc[idMin][l]<<"|dTempMin:"<<dTempMin<<"|dDist["<<l<<"]:"<<dDist[l]<<endl; 168 if ((!bFinalSet[l]) && (dTempMin < dDist[l])) 169 { 170 rtc++; 171 rtt[rtc]=rtt[idMin]; 172 rtt[rtc].r_id=rtc; 173 rtt[rtc].src=idMin; 174 rtt[rtc].des=l; 175 rtt[rtc].ww=dTempMin; 176 cout<<"Round:"<<j<<"|Update dDist["<<l<<"],Route Detail "<<idMin<<"--->"<<l<<endl; 177 dDist[l] = dTempMin; 178 } 179 //cout<<"Round:"<<j<<"|Update ShortPath dDist["<<l<<"]:"<<dDist[l]<<endl; 180 } 181 182 183 } 184 } 185 186 void CreateGraph(Graph *g,Wing *ww,vector<string> &v) 187 { 188 #ifdef DEBUG 189 printf("剛纔輸入頂點數和邊數爲:%d %d\n", g->numVertexes, g->numEdges); 190 #endif 191 //設置頂點數組 192 for(int i=0;i<g->numVertexes;i++) 193 { 194 g->vexs[i]=v[i]; 195 cout<<g->vexs[i]<<" "; 196 } 197 cout<<endl; 198 199 200 //矩陣賦值 201 for(int k=0;k<BM;k++) 202 { 203 int m=-1; 204 int n=-1; 205 m = locates(g,(ww+k)->d1); 206 n = locates(g,(ww+k)->d2); 207 208 if(n == -1 || m == -1) 209 { 210 fprintf(stderr, "there is no this vertex.\n"); 211 return; 212 } 213 //printf("m=%d,n=%d\n",m,n); 214 g->arc[m][n] = (ww+k)->wv; 215 // g->arc[n][m] = g->arc[m][n]; 216 } 217 218 } 219 220 void init(Graph *g) 221 { 222 for(int i=0;i<g->numVertexes;i++) 223 for(int j=0;j<g->numVertexes;j++) 224 { 225 if(i==j) 226 { 227 g->arc[i][j]=0; 228 } 229 else 230 { 231 g->arc[i][j]=INF; 232 } 233 } 234 } 235 236 237 238 int locates(Graph *g,string sch) 239 { 240 int i = 0; 241 for(i = 0; i < g->numVertexes; i++) 242 { 243 if(g->vexs[i] == sch) 244 { 245 break; 246 } 247 } 248 if(i >= g->numVertexes) 249 { 250 return -1; 251 } 252 return i; 253 } 254 255 void printGraph(Graph g) 256 { 257 printf("開始打印\n"); 258 int i, j; 259 for(i = 0; i < g.numVertexes; i++) 260 { 261 for(j = 0; j < g.numVertexes; j++) 262 { 263 printf("%8d ", g.arc[i][j]); 264 } 265 printf("\n"); 266 } 267 }
結果:
·小結
上述這些只是近期無聊研究的結果,你們夥輕拍磚~,^_^ ,午睡去了