實驗題目:校園導遊諮詢
實驗目的
掌握圖的存儲方法和最短路經算法。
實驗內容
設計一個校園導遊程序,爲來訪客人提供各種信息查詢服務。測試數據根據實際情況指定。提示:一般情況下,校園的道路是雙向通行的,可設校園平面圖是一個無向圖。頂點和邊均含有相關信息。
實驗要求
- 設計所在學校的校園平面圖,所含景點不少於10個。以圖中頂點表示校內各景點,存放景點名稱、代號、簡介等信息;以邊表示路徑,存放路徑長度等相關信息。 2. 爲來訪客人提供圖中任意景點相關信息的查詢。
- 爲來訪客人提供圖中任意景點的紋路查詢,即查詢任意兩個景點之間的一條最短的簡單路徑。
實驗內容
需求分析
爲了能夠更好的展現學校的信息,表示學校內部各個景點的信息和路徑信息。我設計了一個校內諮詢網頁,這個網頁內部包括學校的地圖,12個景點的信息,還有每兩個景點之間的最短路徑。
學校地圖
輸入信息
- 景點介紹
當用戶需要了解景點信息時,需要點擊瞭解景點的單選框。 - 最短路徑
當用戶想要訪問兩個頂點的最短路徑時,需要輸入(選擇)起點和終點。
輸出信息
- 景點介紹
用戶選中後,頁面顯示景點的圖片和介紹。 - 最短路徑
用戶選擇了起點和終點之後,在頁面上輸出最短路徑信息。
概要設計
信息存儲
我們的信息存儲主要有兩個部分:景點信息和路徑信息。
- 景點信息
爲了使得網頁上的訪問更加方便,我們不能用一般的數組或結構體來存儲景點的信息。這裏我選擇的XML結構來保存景點信息。裏面有景點的名稱、介紹等等。
- 路徑信息
爲了保存路徑,我將景點和景點之間的邊保存在了一個鄰接矩陣裏面。
最短路徑的算法
由於本次設計需要用戶輸入起點和終點,也是就是說需要求任意兩點之間的最短路徑。所以我們使用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);//後半部
}
調試分析
問題及解決辦法
-
網頁設計遇到的問題和解決辦法
遇到最大的問題就是我本人對於前端設計不算了解,不能實現較爲複雜的頁面。我在調控一些網頁控件時也遇到了對功能不瞭解而出現的錯誤。我的解決辦法就是儘可能簡化網頁設計部分,用最少的控件解決問題。
-
算法遇到的問題和解決辦法
算法遇到的最大的問題就是路徑的輸出。根據Floyd算法,可以很簡單的求出每兩個點之間的最短路徑。但是輸出是個問題。經過一番思考,我在求解最短路徑的時候記錄下節點的信息,然後在求解的時候用遞歸輸出。
算法的時空分析
- 空間複雜度
由於鄰接矩陣的存在,空間複雜度至少是的。在這裏我選擇了12個景點,空間複雜度還可以接受。 - 時間複雜度
由於我使用了floyd算法,時間複雜度就是。但我的景點數是12個,所以這個時間複雜度還是可以接受的。
實驗結果
歡迎界面
景點選擇界面
展示景點
最短路查詢
實驗總結
通過這個實驗我有以下體會
- 我學會使用了多源最短路徑之一的floyd算法,該算法形式簡單,但對於數據規模較大的數據來說,時間複雜度較高。
- 我將數據結構面向對象化,製作網頁很多時候需要用到面嚮對象的技術。我這次實驗將面向對象和數據結構進行了一個結合,感覺使用起來更加的方便了。
- 我將.NET課上學到的ASP.NET 技術和數據結構與算法相結合,實現了技術上的交叉。