圖-指尖上的舞蹈

·背景 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 }
無向圖-Prim

 

結果:

=================================================================================

·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 }
有向圖-最短路徑

 

結果:

 

·小結

  上述這些只是近期無聊研究的結果,你們夥輕拍磚~,^_^ ,午睡去了

相關文章
相關標籤/搜索