实验题目:校园导游咨询
实验目的
掌握图的存储方法和最短路经算法。
实验内容
设计一个校园导游程序,为来访客人提供各种信息查询服务。测试数据根据实际情况指定。提示:一般情况下,校园的道路是双向通行的,可设校园平面图是一个无向图。顶点和边均含有相关信息。
实验要求
- 设计所在学校的校园平面图,所含景点不少于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 技术和数据结构与算法相结合,实现了技术上的交叉。