天天看點

校園導航系統

校園導航系統

【問題描述】

當對校園參觀時,會遇到這樣的問題:如果從校園的某個位置出發,參觀到校園中的所有景點,怎樣設計路線,使參觀者既能參觀所有景點又使走的路程最少。

【資料描述】

定義一個鄰接矩陣存儲結構,用來存儲點和邊的資訊。

定義一個輔助數組closedge,該數組包含兩個分量,lowcost記錄從U到V-U具有最小代價的邊,adjvex記錄改邊依附于U中的頂點。

typedef char ElemType;

typedef struct {

ElemType vexs[max];
int arcs[max][max];
int vexnum,arcnum;           

}MGraph;

struct {

ElemType adjvex;
int lowcost;           

}closedge[max];

【算法思想】

(1)已知校園中各景點和路徑的權重,使參觀者既能參觀所有景點又使走的路程最少。即求最小生成樹,使得路徑保持連通且經過所有邊權值之和最小。

(2)用到Prim算法求最小生成樹,算法思想大體為:

設N=(V,E)是一個連通網,T=(U,TE)是N的最小生成樹,TE是N中最小生成樹中邊的集合。

①初始化:令U={u0|u0∈V},TE={}。其中u0是頂點集合V中的某個頂點。

②選擇:在所有u∈U,v∈V-U的邊(u,v)∈E中,選擇一條代價最小的邊(ui,vj),将(ui,vj)并入集合TE,同時vj并入U。

③反複執行步驟②,直至U=V為止。

TE必有n-1條邊,則T為N的最小生成樹。

【C源程式】

#include<stdio.h>
#include<stdlib.h>
#include<time.h> 
#define max 20
#define INFINITY 1000
typedef char ElemType;
typedef struct {
    ElemType vexs[max];
    int arcs[max][max];
    int vexnum,arcnum;
}MGraph; 
struct {
    ElemType adjvex;
    int lowcost;
}closedge[max];

//傳回頂點下标 
int LocateVex(MGraph G,ElemType v)
{
    for(int i=0;i<G.vexnum;i++)
    {
        if(v==G.vexs[i])
            return i;
    }
    return -1;
}
//建立無向圖鄰接矩陣 
void CreatGraph(MGraph &G)
{
    int  i, j, k,m,n;
       char v1, v2;
       srand(time(0));
   printf("輸入校園中景點數及弧數:\n");
   scanf( "%d%d", &G.vexnum, &G.arcnum );
   getchar(); 
   printf("輸入校園中所有景點:\n" );
   for( i=0; i<G.vexnum; i++ )
   {   
           G.vexs[i]=getchar(); 
           getchar();   }
   for( i=0; i<G.vexnum; i++ )          //初始化鄰接矩陣
      for( j=0; j<G.vexnum; j++ )
          G.arcs[i][j]=INFINITY;
   for( k=0; k<G.arcnum; k++ )
   {
           int w;
           printf("輸入校園中的兩個景點确定邊:\n" );
       v1=getchar(); getchar();
       v2=getchar(); getchar();
       m= LocateVex(G,v1);  n= LocateVex(G,v2);
       printf("請輸入邊的權重:\n"); 
       scanf("%d",&w);
       getchar();
       G.arcs[m][n]=w;G.arcs[n][m]=w;
   }
   printf("鄰接矩陣為:\n"); 
   for( i=0; i<G.vexnum; i++ ) 
   {      
      for( j=0; j<G.vexnum; j++ )
          printf("%d\t",G.arcs[i][j]);
    printf("\n"); 
}
}
//Prim(适用于邊稠密的網) 
int MiniSpanTree_Prim(MGraph G,ElemType u)
{
    int k=LocateVex(G,u);
    for(int j=0;j<G.vexnum;j++)
    {
            if(j!=k)
            {
                closedge[j].adjvex=u;
                closedge[j].lowcost=G.arcs[k][j];
            }
    }
    closedge[k].lowcost=0;
    int minsum=0;
    for(int i=1;i<G.vexnum;i++)
    {
        int minCost=INFINITY;
        for(int j=0;j<G.vexnum;j++)//找最小值 
        {
            if(closedge[j].lowcost!=0&&closedge[j].lowcost<minCost){
                minCost = closedge[j].lowcost;
                k=j;
            }
        }
        printf("%c----%c %d\n",closedge[k].adjvex,G.vexs[k],closedge[k].lowcost);
        minsum+=closedge[k].lowcost;
        closedge[k].lowcost=0;
        for(int j=0;j<G.vexnum;j++)
        {
            if(closedge[j].lowcost!=0&&G.arcs[k][j]<closedge[j].lowcost)
            {
                closedge[j].adjvex = G.vexs[k];
                closedge[j].lowcost = G.arcs[k][j];
            }
        }
    }
    return minsum;
}
int main()
{
     MGraph G;
    CreatGraph(G);                                                           //建立無向圖的鄰接矩陣 
    printf("請輸入從哪個景點出發:\n");
    char u;
    scanf("%c",&u);
    printf("\n 最短路徑權重之和為;%d.\n", MiniSpanTree_Prim(G,u));//輸出路徑與權值
    return 0;
 }            

【小結】

校園導航問題:

不足之處:将問題過于簡單化,就簡單實作建立賦權圖的鄰接矩陣存儲結構,和用Prim算法求最短生成樹,跟校園導航沒有太多關系,不實用。

通過進行資料結構課程設計,對資料結構和算法有了進一步深刻的認識。也發現了自己很多問題。對許多重要的算法不能熟練的運用。仍需對代碼進一步完善。

【參考文獻】

[1] 趙永升,宋麗華,資料結構.北京:電子工業出版社,2019.
[2] 嚴蔚敏,資料結構(C語言版).北京:清華大學出版社,2007.
           

繼續閱讀