數據結構第四次實驗

實驗題目:校園導遊諮詢

實驗目的

掌握圖的存儲方法和最短路經算法。

實驗內容

設計一個校園導遊程序,爲來訪客人提供各種信息查詢服務。測試數據根據實際情況指定。提示:一般情況下,校園的道路是雙向通行的,可設校園平面圖是一個無向圖。頂點和邊均含有相關信息。

實驗要求

  1. 設計所在學校的校園平面圖,所含景點不少於10個。以圖中頂點表示校內各景點,存放景點名稱、代號、簡介等信息;以邊表示路徑,存放路徑長度等相關信息。 2. 爲來訪客人提供圖中任意景點相關信息的查詢。
  2. 爲來訪客人提供圖中任意景點的紋路查詢,即查詢任意兩個景點之間的一條最短的簡單路徑。

實驗內容

需求分析

爲了能夠更好的展現學校的信息,表示學校內部各個景點的信息和路徑信息。我設計了一個校內諮詢網頁,這個網頁內部包括學校的地圖,12個景點的信息,還有每兩個景點之間的最短路徑。

學校地圖
在這裏插入圖片描述
輸入信息

  1. 景點介紹
    當用戶需要了解景點信息時,需要點擊瞭解景點的單選框。
  2. 最短路徑
    當用戶想要訪問兩個頂點的最短路徑時,需要輸入(選擇)起點和終點。

輸出信息

  1. 景點介紹
    用戶選中後,頁面顯示景點的圖片和介紹。
  2. 最短路徑
    用戶選擇了起點和終點之後,在頁面上輸出最短路徑信息。

概要設計

信息存儲
我們的信息存儲主要有兩個部分:景點信息和路徑信息。

  1. 景點信息
    爲了使得網頁上的訪問更加方便,我們不能用一般的數組或結構體來存儲景點的信息。這裏我選擇的XML結構來保存景點信息。裏面有景點的名稱、介紹等等。
    在這裏插入圖片描述
  2. 路徑信息
    爲了保存路徑,我將景點和景點之間的邊保存在了一個鄰接矩陣裏面。

最短路徑的算法
由於本次設計需要用戶輸入起點和終點,也是就是說需要求任意兩點之間的最短路徑。所以我們使用Floyd算法來求任意兩點之間的最短路徑。

詳細設計

爲了側重重點,我在實驗報告裏不再展示網頁設計相關的代碼,只展示算法的代碼部分。

鄰接矩陣

static int inf = 0x3f3f3f;
        public int[,] Arr = new int[12, 12] {
            { 0, inf,inf,inf,inf,inf, 1,inf,inf,inf,inf,inf },
            { inf, 0, 1 ,inf,inf,inf, 1,inf,inf,inf,inf,inf },
            { inf, 1,0 , 5 ,inf, 3, inf,inf,inf,inf,inf,inf },
            { inf,inf,5,0,inf,inf, inf,inf,inf,inf,12,inf },
            { inf, inf,inf,inf,0,inf, inf,inf,inf,inf,2,2   },
            { inf, inf,3,inf,inf,0, inf,inf,inf,2,inf,inf },
            { 1, 1,inf,inf,inf,inf, 0, 1,inf,inf,inf,inf },
            { inf, inf,inf,inf,inf,inf, 1,0,1,2,inf,inf },
            { inf, inf,inf,inf,inf,inf, inf,1,0,inf,1,2 },
            { inf, inf,inf,inf,inf,2, inf,2,inf,0,2,inf },
            { inf, inf,inf,inf,2,inf, inf,inf,1,2,0,3 },
            { inf, inf,inf,inf,inf,inf, inf,inf,2,inf,3,0 },
        };

路徑保存
我們用一個-1的矩陣來保存路徑

public int[,] path = new int[12, 12] {
            {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 },
            {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 },
            {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 },
            {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 },
            {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 },
            {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 },
            {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 },
            {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 },
            {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 },
            {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 },
            {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 },
            {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 },
        };

最短路算法
採用Floyd算法

public void Shortest()
        {
            for (int k = 0; k < 12; k++)
                for (int i = 0; i < 12; i++)
                    for (int j = 0; j < 12; j++)
                        if(Arr[i, j] >  Arr[i, k] + Arr[k, j])
                        {
                            Arr[i, j] = Arr[i, k] + Arr[k, j];
                            path[i, j] = k;
                        }
            string p = DropDownList1.SelectedValue.ToString();
            string[]p1 = p.Split('-');
            string q = DropDownList2.SelectedValue.ToString();
            string[] q1 = q.Split('-');
            int pp = int.Parse(p1[0]);
            int qq = int.Parse(q1[0]);
            if(Arr[pp,qq]!=inf)
            {
                label1.Text = "";
                label1.Text += p1[0] + p1[1] + "->";
                print(pp, qq);
                label1.Text += q1[0] + q1[1];
            }
            
            label2.Text = DropDownList1.SelectedItem.Text + "->" + DropDownList2.SelectedItem.Text + "的最短路徑是" + Arr[pp, qq];
        }

路徑輸出

public void print(int a, int b)
        {
            if (path[a,b] == -1) return;//因爲開始初始化爲-1,這裏就可以避免相鄰的再次輸出 
            print(a, path[a,b]);//前半部 
            //cout << path[a,b] << "-->";//輸出該點
            XmlDocument doc = new XmlDocument();
            doc.Load(Server.MapPath("~/App_Data/cons.xml"));
            XmlNode xn = doc.SelectSingleNode("Constellation");
            XmlNodeList xnl = xn.ChildNodes;
            // 遍歷子節點
            foreach (XmlNode xnd in xnl)
            {
                // 運用實體類保存信息
                ConsModel cm = new ConsModel();
                XmlElement xe = (XmlElement)xnd;
                XmlNodeList xnl0 = xe.ChildNodes;
                cm.ConsNum = xnl0.Item(0).InnerText;
                cm.ConsName = xnl0.Item(1).InnerText;
                if(path[a,b].ToString()==cm.ConsNum)
                {
                    label1.Text += path[a, b] + cm.ConsName+"->";
                    break;
                }
                    
            }
            print(path[a,b], b);//後半部 
        }

調試分析

問題及解決辦法

  1. 網頁設計遇到的問題和解決辦法
    遇到最大的問題就是我本人對於前端設計不算了解,不能實現較爲複雜的頁面。我在調控一些網頁控件時也遇到了對功能不瞭解而出現的錯誤。

    我的解決辦法就是儘可能簡化網頁設計部分,用最少的控件解決問題。

  2. 算法遇到的問題和解決辦法
    算法遇到的最大的問題就是路徑的輸出。根據Floyd算法,可以很簡單的求出每兩個點之間的最短路徑。但是輸出是個問題。

    經過一番思考,我在求解最短路徑的時候記錄下節點的信息,然後在求解的時候用遞歸輸出。

算法的時空分析

  1. 空間複雜度
    由於鄰接矩陣的存在,空間複雜度至少是N2N^2的。在這裏我選擇了12個景點,空間複雜度還可以接受。
  2. 時間複雜度
    由於我使用了floyd算法,時間複雜度就是O(N3)O(N^3)。但我的景點數是12個,所以這個時間複雜度還是可以接受的。

實驗結果

歡迎界面
在這裏插入圖片描述
景點選擇界面
在這裏插入圖片描述
展示景點
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
最短路查詢
在這裏插入圖片描述

在這裏插入圖片描述

實驗總結

通過這個實驗我有以下體會

  1. 我學會使用了多源最短路徑之一的floyd算法,該算法形式簡單,但對於數據規模較大的數據來說,時間複雜度較高。
  2. 我將數據結構面向對象化,製作網頁很多時候需要用到面嚮對象的技術。我這次實驗將面向對象和數據結構進行了一個結合,感覺使用起來更加的方便了。
  3. 我將.NET課上學到的ASP.NET 技術和數據結構與算法相結合,實現了技術上的交叉。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章