距離向量選路算法

1.代碼

#include<stdio.h>
#include<ctype.h>
#include<malloc.h>
#include<limits.h>
#include<string.h>
#include<stdlib.h>
#include<io.h>
#include<math.h>
#include<sys/timeb.h>
#include<stdarg.h>
#include<time.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define MAX_NAME 9//頂點名稱字符串最大長度+1
#define INFINITY 1000//用1000代替∞
#define MAX_VERTEX_NUM 26 //最大頂點個數
typedef int Status;
typedef int Boolean;
typedef int VRType;//定義頂點關係類型爲整型,與INFINITY的類型一致
typedef char PathMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM][MAX_VERTEX_NUM];//三維數組
typedef VRType DistancMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//二維數組 
typedef struct //邊(弧)信息結構
{
    VRType adj;//頂點關係類型,對帶權圖,表示權值 
} ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//二維數組 
enum GraphKind{DG,DN,UDG,UDN} ;//{有向圖、無向網、無向圖、無向網}
struct VertexType//最簡單的頂點信息類型(只有頂點名稱)
{
    char name[MAX_NAME];//頂點名稱 
    char routers[MAX_VERTEX_NUM][MAX_NAME];//定義最短路徑中到目的節點的上一跳 
} ;
struct MGraph//圖的結構
{
    VertexType vexs[MAX_VERTEX_NUM];//頂點向量
    AdjMatrix arcs;//鄰接矩陣(二維數組)
    int vexnum,arcnum;//圖的當前頂點數和弧數
    GraphKind kind; //圖的種類標誌 
} ;

int stable=0;//到達穩定前路由表交換次數 

void visit(VertexType ver)//訪問頂點的函數
{
    printf("%s",ver.name);
}
void input(VertexType &ver) //輸入頂點信息的函數 
{
scanf("%s",ver.name);   
}

int LocateVex(MGraph G,VertexType u)
{
    //查找頂點u,並返回其位置
    int i;
    for(i=0;i<G.vexnum;++i)
        if(strcmp(u.name,G.vexs[i].name)==0)
        return i;
}
void CreateDN(MGraph &G)//構造有向網G 
{
int i,j,k;
VRType w;//頂點關係類型 
 VertexType v1,v2;
 printf("               請輸入網絡拓撲結構中的節點數、弧數");
 scanf("%d %d",&G.vexnum,&G.arcnum);
 printf("               請輸入%d個頂點的值(名稱小於%d個字符):",G.vexnum,MAX_NAME);
 for(i=0;i<G.vexnum;i++)//構造頂點向量
  input(G.vexs[i]);    //輸入節點名稱
  for(i=0;i<G.vexnum;i++)//初始化二維鄰接矩陣
  for(j=0;j<G.vexnum;j++)
  {
    G.arcs[i][j].adj=INFINITY;
  } 
  printf("               請輸入%d條弧的弧尾  弧頭  權值:\n",G.arcnum);
  for(k=0;k<G.arcnum;k++)
  {
    scanf("%s %s %d",v1.name,v2.name,&w);
    i=LocateVex(G,v1);
    j=LocateVex(G,v2);
    G.arcs[i][j].adj=w;
    G.arcs[j][i].adj=w;
  } 
}
VertexType GetVex(MGraph G,int v)
{
    if(v>=G.vexnum||v<0)
    exit(OVERFLOW);
    return G.vexs[v];
}
void Display(MGraph G)
{
    int i,j,k;
    printf("              %d個頂點%d條弧的無向網。頂點依次是:",G.vexnum,G.arcnum);
    for(i=0;i<G.vexnum;i++)
    visit(GetVex(G,i));
    printf("\n                         初 始 路 由 表 如 下(1000表示無窮遠):\n");
    printf("                       ");
        for(i=0;i<G.vexnum;i++)
        printf("%-8s",G.vexs[i].name);
        printf("\n");
         for(j=0;j<G.vexnum;j++)
     {   printf("%20s",G.vexs[j].name);
        for(k=0;k<G.vexnum;k++)
        printf("   %-5d",G.arcs[j][k].adj);
        printf("\n");
     }
} 

void ShortestPath_Floyd(MGraph G,PathMatrix P,DistancMatrix D)
{
    //用Floyd算法隨機更新兩頂點間最短路徑、頂點路由表,若P[v][w][u]爲true,則u是從v到w當前求得最短路徑上的頂點
    int u,v,w,i,j,k;
    int change=1;//路由表有無交換 
    int bad=1;//不好的交換 
    for(v=0;v<G.vexnum;v++)
    for(w=0;w<G.vexnum;w++)
    {
        D[v][w]=G.arcs[v][w].adj;//頂點v到w的直接距離
        for(u=0;u<G.vexnum;u++)
        P[v][w][u]=FALSE;
        if(D[v][w]<INFINITY)//從V到W有直接路徑 
        {
        strcpy(G.vexs[v].routers[w],G.vexs[v].name);
        P[v][w][v]=P[v][w][w]=TRUE; //由v到w的路徑經過v和w兩點
         }
         else 
         strcpy(G.vexs[v].routers[w],"-");
    } 
    srand((unsigned)time(NULL));//產生隨機數種子,防止僞隨機數 
    while(change==1)
    {
    for(;bad<20;)//連續20次隨機交換無更新,爲壞的交換,則停止隨機交換 
    {
    v=rand()%G.vexnum;
    w=rand()%G.vexnum;
    if(D[v][w]<INFINITY&&v!=w)
    {
    printf("%s節點向%s節點發送距離向量,",G.vexs[w].name,G.vexs[v].name);
     change=0;
     for(u=0;u<G.vexnum;u++)
     {
     if(D[w][u]<INFINITY&&D[v][w]+D[w][u]<D[v][u])//從v經u到w的一條路徑更短
      {
     D[v][u]=D[v][w]+D[w][u];//更新最短距離
     change=1;
     bad=0;   //一有更新,則不是壞的交換 
     if(w!=u)
     strcpy(G.vexs[v].routers[u],G.vexs[w].name);//記錄上一跳節點名稱 
     for(i=0;i<G.vexnum;i++)
     P[v][w][i]=P[v][u][i]||P[u][w][i];//從v到w的路徑經過從v到u和從u到w的所有路徑 

      }//if 
    }//for u
    if(change==1)
    {  
     stable++;  
    printf("                         %s 的 路 由 表 如 下:\n",G.vexs[v].name);
    printf("                       目的節點 最短路徑  上一跳\n");
    for(j=0;j<G.vexnum;j++)
    printf("                    %8s  %8d %8s\n",G.vexs[j].name,D[v][j],G.vexs[v].routers[j]);
    }// if change 
    else 
    {
    printf(" %s 的 路 由 表 無更新:\n\n",G.vexs[v].name); 
    bad++;
    }
    }//if
    }//for
    }//while
     printf("\n********************************************************************************\n");    
     printf("                    所以經過%d次交換,路由表達到穩定,最短路徑矩陣爲:\n",stable);
     printf("                       ");
    for(i=0;i<G.vexnum;i++)
        printf("%-8s",G.vexs[i].name);
        printf("\n");
         for(j=0;j<G.vexnum;j++)
     {   printf("%20s",G.vexs[j].name);
        for(k=0;k<G.vexnum;k++)
        printf("   %-5d",D[j][k]);
        printf("\n");
     }
     for(i=0;i<G.vexnum;i++)
    {
       printf("                         %s 的 路 由 表 如 下:\n",G.vexs[i].name);
    printf("                       目的節點 最短路徑  上一跳\n");
    for(j=0;j<G.vexnum;j++)
    printf("                    %8s  %8d %8s\n",G.vexs[j].name,D[i][j],G.vexs[i].routers[j]);
    }
} 
 main()
 {
    MGraph g;
    int i,j,k;
    PathMatrix p;
    DistancMatrix d;
    printf("***********************本程序完成距離向量路由算法的模擬*************************\n"); 
    CreateDN(g);//構造有向網g
     for(i=0;i<g.vexnum;i++)
     g.arcs[i][i].adj=0;//頂點到自身距離爲0
     Display(g);//輸出有向網g 
     ShortestPath_Floyd(g,p,d);//求每對頂點的最短路徑 

     return 1;
 } 

2.運行結果
這裏寫圖片描述

這裏寫圖片描述

3.結果說明
首先通過輸入得出各個路由頂點以及頂點之間的距離。然後打印出來。然後程序通過距離向量選路算法得出最小路徑。最後打印出各個路由器之間的最短路徑,“上一跳”表示在初始路由器和終點路由器之間,且和終點路由器直接相連的一個路由器節點。如果沒有路徑,上一跳由“-”表示。在運行結果中,我省略了一部分截圖,裏面表示“ 路 由 表 無更新“;

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