校园导游咨询预习报告

问题定义

本次课程设计要求协助中国大学生计算机设计大赛江苏省组委会,设计一款赛事管理系统,实现赛务相关的数据管理及信息服务,该系统能够为省级赛事管理解决以下问题:

(1)能够管理各参赛队的基本信息(包含参赛队编号,参赛作品名称,参赛学校,赛事类别,参赛者,指导老师),赛事类别共11项(参见大赛官网jsjds.blcu.edu.cn);包括增加、删除、修改参赛队伍的信息。

(2)从team.txt中读取参赛队伍的基本信息,实现基于二叉排序树的查找。根据提示输入参赛队编号,若查找成功,输出该赛事类别对应的基本信息(参赛作品名称、参赛学校、赛事类别、参赛者和指导老师信息),同时,输出查找成功时的平均查找长度ASL;否则,输出“查找失败!”。
(3)能够提供按参赛学校查询参赛团队(或根据赛事类别查询参赛团队),即,根据提示输入参赛学校名称(赛事类别),若查找成功,输出该学校参赛的(该赛事类别的)所有团队的基本信息,输出的参赛团队按赛事类别有序输出。(排序算法可从选择排序、插入排序、希尔排序、归并排序、堆排序中任意选择,并为选择算法的原因做出说明。)

(4)为省赛现场设计一个决赛叫号系统。所有参赛队按赛事组织文件中的赛事类别分到9个决赛室,决赛室按顺序叫号,被叫号参赛队进场,比赛结束后,下一参赛队才能进赛场。请模拟决赛叫号系统,演示省赛现场各决赛室的参赛队进场情况。(模拟时,要能直观展示叫号顺序与进场秩序一致)

(5)赛事系统为参赛者提供赛地的校园导游程序,为参赛者提供各种路径导航的查询服务。以我校长山校区提供比赛场地为例,(请为参赛者提供不少于10个目标地的导航。可为参赛者提供校园地图中任意目标地(建筑物)相关信息的查询;提供任意两个目标地(建筑物)的导航查询,即查询任意两个目的地(建筑物)之间的一条最短路径。

问题分析

赛事管理系统的实现需要涉及到多个方面,包括数据结构设计、搜索和排序算法的应用、用户交互和可视化等方面的问题。

在学习过程中,需要熟练掌握二叉排序树的基本原理和实现,选择合适的排序算法对查询结果进行排序,同时需要使用JavaFX等工具对系统界面进行设计。

这显然是一个图论问题,而且校园内道路一般是双向通行的,所以这是一个无向图。对 于图的存储结构而言,图中各个景点的存储结构有邻接表和邻接矩阵两种存储结构,考虑到 顶点个数少于 50 个,所以邻接表和邻接矩阵的复杂度相同。本题中选择使用邻接矩阵来表 示图。

任务中要求求解出图中景点的问路查询,即为给定两个源点,求解出两个顶点之间的最 短路径。根据数据结构课程所学知识,有多种经典算法可以解决最短路径问题,包括 Dijkstra 算法,Floyd-Warshell 算法,Bellman-Ford 算法和深度优先遍历。不同是算法有不同的算法复 杂度,考虑到校园中道路没有负权边,即算法均可解决最短路径问题。

其中 Dijkstra 算法求的是单源最短路径:即从一个结点出发到其它所有结点的最短路径, 算法的时间复杂度为 O(n 2 ),但题目要求任意两个结点的最短路径,所以还是要在外层增加 一个循环,以求得多源最短路径。

而 Floyd 算法求的是多源最短路径:即从任意结点出发到其它所有结点的最短路径,算 法的时间复杂度为 O(n 3 ),它可以一次性求得所有结点间的最短路径,且算法思想简单,便 于理解。所以我们这一项目采用 Floyd 算法来求解最短路径

系统主要包括以下几个组成部分:

  • 数据结构设计:采用二叉排序树进行参赛队伍的基本信息存储,使用链式前向星存储导航图信息和路径信息;

  • 界面设计:使用JavaFX等工具进行设计,包括各种输入框、下拉框,以及部分交互式地图展示等

  • 二叉排序树实现参赛队伍的查找:使用二叉排序树实现快速查找,同时计算ASL;

  • 排序算法实现学校(或赛事类别)查询:采用高效的排序算法对查询结果进行排序;

  • 决赛叫号系统:采用队列模拟决赛叫号程序,实现按赛事类别叫号和模拟参赛队进场;

  • 赛地校园导游:将校园地图导入系统,同时实现不少于10个目标地的导航。采用Floyd算法求解最短路径,同时提供地点信息和路径导航查询。

概要设计

#define MAXVEX 13     //最大顶点个数 
#define INFINITY 3276//图的矩阵中A(i,i)记为0,若没有通路,记为INFINITY = 32762
int PathMatirx[MAXVEX][MAXVEX];
int ShortPath[MAXVEX][MAXVEX];

//结点的结构体--代表实际中的景点
typedef struct {
    int Num;//景点的编号
    string name;       //校园景点名
    string info;    //校园景点的描述信息
}VextexType;

//邻接矩阵的数据类型 
typedef struct {
    int AdjMatrix[MAXVEX][MAXVEX]; //用二维数组来存放邻接矩阵 
    VextexType vex[MAXVEX];    //存放顶点信息
    int vexnum;        //顶点数 
    int arcnum;     //边数 
}MGraph;

void InitGraph();//初始化无向图
void Menu();//向用户显示菜单
void PrintAllInfo();//打印所有景点的信息
void MapDisplay();//显示地图函数
void ShortestPathOfAnyTwo(MGraph G);//查询任意两景点之间最短路径
void Floyd();//弗洛伊德算法求最短路径函数
void AddArc(MGraph G);//增加边<v,w>
DelVertex(MGraph G);//删去顶点v和所有与之关联的边
DelArc(MGraph G);//删去边<v,w>
UpdateIifo();//更新景点信息

void InitGraph(MGraph& G) {
    int i = 0, j = 0;
    G.vexnum = 13;
    G.arcnum = 19;
    for (int i = 0; i < 13; i++) {
        G.vex[i].Num = i + 1;//第1号景点到第13号景点
    }

void MapDisplay() {
    system("mspaint Cloud_Picture.jpg");//使用Windows自带的画板打开校园云图
    system("mspaint Plane_Figure.png");//使用Windows自带的画板打开校园平面图
}

Floyd算法(弗洛伊德算法)求最短路径:
两个准备的二维数组:
int PathMatirx[MAXVEX][MAXVEX];//记录对应点的最小路径的前驱点
int ShortPath[MAXVEX][MAXVEX];//记录顶点间的最小路径值

void Floyd(MGraph& G) {
    //对Floyd的两个数组进行初始化
    for (int i = 0; i < G.vexnum; i++) {
        for (int j = 0; j < G.vexnum; j++) {
            PathMatirx[i][j] = j;
            ShortPath[i][j] = G.AdjMatrix[i][j];
        }
    }
    for (int k = 0; k < G.vexnum; k++) {
        for (int v = 0; v < G.vexnum; v++) {
            for (int w = 0; w < G.vexnum; w++) {
                if (ShortPath[v][w] > ShortPath[v][k] + ShortPath[k][w]) {
                    //更新最短路径
                    ShortPath[v][w] = ShortPath[v][k] + ShortPath[k][w];
                    //更新路径中间经过的节点
                    PathMatirx[v][w] = PathMatirx[v][k];
                }
            }
        }
    }
}

void UpdateIifo(MGraph& G) {
    //更新景点信息
    int number;
    string info;
    string name;
    cout << "请输入您想更新的景点的编号" << endl;
    cin >> number;
    if (number<1 || number>G.vexnum) {
        cout << "您的输入有误,请重新输入" << endl;
        return;
    }
    cout << "请输入景点新的信息" << endl;
    cin >> info;
    cout << info << endl;
    G.vex[number - 1].info = info;
    cin >> name;
    cout << name << endl;
    G.vex[number - 1].name = name;
    cout << "修改成功" << endl;
    PrintAllInfo(G);
}

任意节点i到j的最短路径两种可能:

直接从i到j;
从i经过若干个节点k到j。
map(i,j)表示节点i到j最短路径的距离,对于每一个节点k,检查map(i,k)+map(k,j)小于map(i,j),如果成立,map(i,j) = map(i,k)+map(k,j);遍历每个k,每次更新的是除第k行和第k列的数。

prim算法求最小生成树

void Prim(MGraph& G) {
    cout << "请输入您想从几号景点" << endl;
    int choice;
    cin >> choice;
    struct {
        int adjvex;
        int lowcost;
    }closedge[MAXVEX];
    int i, e, k, m, min;
    closedge[choice].lowcost = 0;
    for (i = 0; i < G.vexnum; i++)
        if (i != choice - 1)
        {
            closedge[i].adjvex = choice - 1;
            closedge[i].lowcost = G.AdjMatrix[choice - 1][i];
        }
    for (e = 0; e < G.vexnum - 1; e++) {
        min = INFINITY;
        for (k = 0; k < G.vexnum; k++) {
            if (closedge[k].lowcost != 0 && closedge[k].lowcost < min) {
                m = k;
                min = closedge[k].lowcost;
            }
        }
        printf("从%s<------>%s:%dm\n", G.vex[closedge[m].adjvex].name, G.vex[m].name, closedge[m].lowcost);
        closedge[m].lowcost = 0;
        //当m加入后,更新closedge数组信息
        for (i = 0; i < G.vexnum; i++) {
            if (i != m && G.AdjMatrix[m][i] < closedge[i].lowcost) {
                closedge[i].lowcost = G.AdjMatrix[m][i];
                closedge[i].adjvex = m;
            }
        }
    }
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值