最短路徑


實驗六 最短路徑
----因特網最短路徑優先(OSPF)路由算法的實現
[請參考教材189頁算法7.15]


一、實驗目的
因特網中,路由器中路由表的生成是非常關鍵的技術問題。目前,在因特網中的路由器中,都支持開放最短路徑優先(OSPF)路由生成算法。OSPF算法生成速度快,而且收斂快、性能穩定,是目前已知的因特網中路由表生成的最好算法之一。
OSPF最重要的內容是路由器如何根據已接收到的本路由器所在的自治系統(AS)的路由器拓撲結構以及各路由器之間的傳輸費用(代價、權),生成一條從本路由器到AS中各路由器的最短路徑,進而生成路由表。
本實驗的目的是根據一個給定的網絡拓撲結構及路由器之間的傳輸費用,生成指定路由器到其它路由器的最短路徑的實現方法,並且根據求得的最短路徑,生成路由表。
最短路徑算法是因特網(Internet)路由算法中最重要的算法,關係到因特網的網絡交換性能以及網絡的穩定性,因此,解決最短路徑算法的實現問題,具有非常重要的應用價值。本設計型實驗,緊密結合最短路徑在因特網中的實際應用,通過最短路徑算法的程序實現過程和路由表的生成過程,更深地領會最短路徑在因特網中實現快速路由以及路由表生成的原理,培養學生解決實際問題的能力。
二、實驗要求
  熟悉C語言編程, 熟練使用C語言實現圖形結構的說明、創建以及圖的存儲表示;要求學生熟練應用圖形數據結構編程實現最短路徑的算法;瞭解AS中路由器與網絡、網絡與路由器代價計算方法;瞭解根據OSPF生成路由表的原理。
三、實驗內容
根據給定的網絡拓撲圖求某路由器到其它路由器的最短路徑,並生成路由表
下圖爲因特網中某自治系統(AS)路由器及網絡連接拓撲圖。


R1
R4
R2
R5
N3
N1
N5
R6
N2
R3
8
4
2
3
9
5
5
7
2
5
N4
2


按照因特網的規定,從網絡到路由器的費用爲0,因此上圖(無向圖)可表示爲下圖(有向圖)形式。


8
R1
R4
R2
R5
N3
N1
N5
R6
N2
R3
4
2
3
9
5
5
7
2
5
N4
2
8
4


求從某路由器(如R1)至其它路由器的最短路徑。即從始點(如R1)開始,逐步求始點(如R1)到其它可達的各路由器的最短路徑,直到所有路由器計算完成爲止。
根據最短路徑的求解結果,可以生成路由表。
路由表主要由兩個表項組成,即目的網絡(目的路由器所在網絡)及下一路由器(或下一跳,即所求路由器相鄰的某一路由器),如N5,R4,表示到達N5的最短路徑通過R4,N3,R6,因此相對於路由器R1而言,到達目的網絡N5的下一跳爲R4。
下表是R1到其它網絡的最短路徑:
開始
路由器
目的路由器
或目的網絡
最短路徑經過的路由器或網絡序列
最短路徑值
R1
R2
R1-N1-R2
5
R1
R3
R1-N1-R3
5
R1
R4
R1-R4
8
R1
R5
R1-N1-R2-R5
9
R1
R6
R1-R4-N3-R6
10
R1
N1
R1-N1
5
R1
N2
R1-N1-R3-N2
7
R1
N3
R1-R4-N3
10
R1
N4
R1-N1-R2-R5-N4
11
R1
N5
R1-R4-N3-R6-N5
15
根據R1到其它網絡的最短路徑,很容易得到R1的路由表(下一跳是R1到達網絡所經過的第一個路由器),詳見下表:
目的網絡
下一跳(路由器)
N1
--
N2
R3
N3
R4
N4
R2
N5
R4
四、實驗步驟
以下是最短路徑算法的具體實現步驟。但是由於本實驗爲設計型實驗,且爲解決實驗問題而做,因此,以下的最短路徑算法只能作參考,還有若干步驟需要學生們自己獨立完成,如生成路由表;而且除求R1路由器到其它路由器的最短路徑外,還可以求其它路由器(如R2,R3,…)最短路徑和生成路由表[只需做一個路由器的最短路徑和路由表]。
1.輸入e條弧,生成AOE-網的存儲結構
2.初始化: S ← { v0 };
        dist[i] ← Edge[0][i],   i = 1, 2, …, n;         // n爲圖中頂點個數
        if (dist[i] != ∝) { P[i] = {0, i};}               // 頂點0到頂點i的路徑
3.求出最短路徑的長度:
        dist[j] ← min { dist[i] }, i屬於V- S ;
        S ← S U { j };
4.修改從v0到V-S集合中各頂點的最短路徑:
       if (dist[i] > dist[j] + Edge[j][i]) {
dist[i] = dist[j] + Edge[j][i];
P[i] = P[j] U {i};     }                        // 頂點0到頂點i的新路徑
每一個 i 屬於V-S;
5.判斷:若 S == V, 則算法結束,否則轉 3。
源程序

#include <stdio.h>
#include <math.h>
#include <string.h>
#define FALSE     0
#define TRUE      1
#define MAX       11
#define INFINITY  50
typedef struct{
   int vexnum;
   int arcs[MAX][MAX];
   int arcnum;
}mgrath;
int mode[MAX][MAX]={
   {0,50,50,8,50,50,5,50,50,50,50},
   {50,0,50,50,4,50,7,50,50,50,50},
   {50,50,0,50,50,50,3,2,50,50,50},
   {8,50,50,0,50,50,50,50,2,50,50},
   {50,4,50,50,0,50,50,50,5,2,50},
   {50,50,50,50,50,0,50,50,9,50,5},
   {0,0,0,50,50,50,50,50,50,50,50},
   {50,50,0,50,50,50,50,50,50,50,50},
   {50,50,50,0,0,0,50,50,50,50,50},
   {50,50,50,50,0,50,50,50,50,50,50},
   {50,50,50,50,50,0,50,50,50,50,50}
};

typedef int pathmatrix[MAX][MAX];
typedef int shortpath[MAX];
typedef char ch[MAX][MAX];
char emax[][3]={"r1","r2","r3","r4","r5","r6","n1","n2","n3","n4","n5"};
int createmgrath(mgrath &G,ch &H)
{

   int i,j,k=0,l=0;

   G.vexnum=G.arcnum=11;
   puts("input G.vexnum G.arcnum");

   printf("%d,%d \n",G.vexnum,G.arcnum);
   for(i=0;i<11;i++)
   {
       strcpy(H[i],emax[i]);
   }
   for(i=0;i<G.vexnum;i++)
       for(j=0;j<G.vexnum;j++)
           G.arcs[i][j]=mode[i][j];
      return 1;
}
void shortestpath_DIJ(mgrath G,int v0,pathmatrix &p,shortpath &D)
{
   int v,w,i,min,j;
   shortpath final;
   for(v=0;v<G.vexnum;++v)
   {
       final[v]=FALSE;
       D[v]=G.arcs[v0][v];
       for(w=0;w<G.vexnum;++w)  p[v][w]=FALSE;  // 設空路徑
       if(D[v]<INFINITY)
       {
           p[v][v0]=TRUE;
           p[v][v]=TRUE;
       }
   }

   D[v0]=0;  final[v0]=TRUE;     // 初始化,v0頂點屬於S集
//--- 開始主循環,每次求得v0到某個v頂點的最短路徑,並加v到S集 ---
for(i=0;i<G.vexnum;++i)     // 其餘G.vexnum-1個頂點
   {
       min=INFINITY;
       for(w=0;w<G.vexnum;++w)
       {
           if(!final[w])
               if(D[w]<min)
               {
                   v=w;
                   min=D[w];
               }
       }
       final[v]=TRUE;
       for(w=0;w<G.vexnum;++w)
       {
           if(!final[w]&&(min+G.arcs[v][w]<D[w]))
           {
               D[w]=min+G.arcs[v][w];

               for(j=0;j<G.vexnum;j++)
                   p[w][j]=p[v][j];
               p[w][w]=TRUE;
           }
       }
   }        
}
void main()
{

   int k,i,j,q,l,h,n;
   int f,m;

   mgrath A;
   ch B,C;    

   pathmatrix N,D;
   shortpath M;
   createmgrath(A,B);
for( unsigned int w=0; w<MAX; ++w )
{
 for( unsigned int j=0; j<MAX; ++j )
 C[w][j] = 0;
}
   puts("begin from which node : ");
   printf("if you want input r1 please input 0 \n");
   printf("if you want input r2 please input 1 \n");
   printf("if you want input r3 please input 2 \n");
   printf("if you want input r4 please input 3 \n");
   printf("if you want input r5 please input 4 \n");
   printf("if you want input r6 please input 5 \n");
   printf("if you want input n1 please input 7 \n");
   printf("if you want input n2 please input 8 \n");
   printf("if you want input n3 please input 9 \n");
   printf("if you want input n4 please input 10 \n");

   scanf("%d",&k);

   shortestpath_DIJ(A,k,N,M);
   for(i=0;i<A.vexnum;i++)    
   {
       for(j=0;j<A.vexnum;j++)
  D[i][j]=N[i][j];
   }    
  printf("\n");

   printf(" 起點    目的網絡    最短路徑經過的路由器或網絡序列    最短路徑值 \n");
   for(l=0,f=0;l<11;l++,f=0)
   {
       if(B[l][0]=='n'){
           q=k;
           printf(" %s        %s      ",B[k],B[l]);

           for(n=13,h=0;h<11;h++)
           {
               for(j=0;j<11;j++)
                   if(D[l][j]==TRUE && A.arcs[q][j]<50)
                   {
                       D[l][j]=FALSE;
                       printf("%s-",B[j]);
                       n--;
                       q=j;
                       if(f==0 && B[j][0]=='r' && B[j]!=B[k])
                       {
                           for(m=0;m<11;m++)
                               C[l][m]=B[j][m];
                           f=1;
                       }break;
                   }
           }
           for(;n>0;n--)
               printf("   ");

           printf("%d \n",M[l]);
       }
   }
   printf(" \n \n目的網絡       起點%s的路由表的下一跳\n",B[k],B[k]);
   for(l=0;l<11;l++)
   {
       if(B[l][0]=='n')
 {
           if(B[l][0]==NULL)
   printf("NULL");
  else{
               printf("  %s       ",B[l]);
   printf("    %s \n",C[l]);
  }
       }
    }
}  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章