基于Dijkstra的校园导游系统

news2024/12/24 8:51:46

目录

一. 设计目的

二. 设计背景

三. 系统功能

四. 系统算法实现

五. 系统调试与结果分析

六. 完整源代码


一. 设计目的

        通过设计并实现校园导游系统,使学生对数据结构有更深入的了解。该系统综合性非常广,能够极大提高学生的设计,编程及调试等解决实际应用的能力。培养对实际问题的分析,建模等逻辑思维。

二. 设计背景

        随着校园规模的扩大,游客和学生对校园内景点信息的需求日益增加。传统的纸质地图已难以满足其需求,因此开发一款校园导游系统显得尤为重要。本系统以湖南城市学院为例,实现了基于Dijkstra算法的最短路径查询功能,以及景点信息查询和推荐等功能。

三. 系统功能

        1)地图展示功能:首先系统能够展示校园景点的大致分布图,帮助用户直观了解校园布局。知道校园有哪些景点可以前往。

        2)推荐景点模块:在查看了整个校园大致分布图后,如果用户不知道该前往何处,就可以查看推荐景点,前往合适自己前往的景点。

        3)景点信息查询模块:用户若在地图上不熟悉景点的信息以及作用,就可以输入景点编号,查看景点的所有信息简介。

        4)景点间最短路径的查询:当用户已经明确了自己想要前往的景点,就可以输入用户当前所在位置以及想要前往的景点,系统就会给出到达目标景点的最短路径,切实帮助用户快速到达目的地。

        

四. 系统算法实现

        系统在查询景点间最短路径当中,就使用了Dijkstra算法。该算法主要用于计算图中一个顶点到其他所有顶点的最短路径。算法核心是通过不断选取未访问的顶点中距离起点最近的顶点,并更新其相邻顶点的距离,直到所有顶点都被访问过。

        实现该算法主要使用如下四个函数:

        Create函数用来初始化校园景点图,包括设置顶点数、边数、初始化邻接矩阵、输入景点信息及道路信息等。

        inquire函数:根据用户输入的景点编号,输出该景点的详细信息。

        Dijkstra函数:实现Dijkstra算法,计算并输出从起点到终点的最短路径及长度。

        PrintPath函数:辅助函数,用于打印从起点到终点的最短路径。

五. 系统调试与结果分析

         

首先用户会看到这样的一个交互界面,这是文本形式的交互界面,所以这个可以作为我们这个系统的改进,未来可以考虑增加图形用户界面(GUI),提高用户体验。

接着,我们可以查看整个学校的平面图,输入操作1:

只要我们的用户没有执行退出操作,就可以一直使用校园导游系统。

假设我们用户此时在编号为1,也就是学校北门的位置,想要前往学校图书馆,也就是编号为5的景点,想要知道前往图书馆的最短路径,方便她快速到达,就可以执行第4个操作,如下所示:

 

系统就会给出最短路径长度,以及最短路径,也就是从学校北门先经过篮球场,最后到达图书馆,就是最短的路径。

用户如不需要再使用该系统就可以执行第5步操作,退出我们的校园导游系统,如下所示:

 

六. 完整源代码
//基于Dijkstra的校园导游系统。
//这里我们以湖南城市学院大学的部分景点为例
#include<stdio.h>
#include<string.h>
#include<limits.h>;
//首先确定一个景点所包含的内容:景点名称,景点简介
#define MAXSIZE 100		//定义一个数组最大值
typedef struct ElemType {
	int id;				//为了方便管理,设置一个顶点编号
	char name[MAXSIZE];		//景点名称,用一个字符数组存储
	char introduce[MAXSIZE];	//景点的简介,也用字符数组存储起来
}ElemType;

//构建一个图,使用邻接矩阵来存储
typedef struct Graph {
	ElemType vexs[MAXSIZE];		//存放顶点
	int arcs[MAXSIZE][MAXSIZE];	//邻接矩阵
	int vexnum,arcnum ;		//顶点数和边数
}Graph;

//函数声明
void map();
void choice();
void recommend();
Graph Creat(Graph& G);
void inquire(Graph G, int n);
void PrintPath(Graph G, int prev[], int start, int end);
void Dijkstra(Graph& G, int start,int end);

int main()
{
	Graph G=Creat(G);	//创建一个图,并对这个图进行相应的初始化和信息录入
	
	while (1) {
		int num;
		int num1;	//用来接收第二个操作的景点编号
		printf("\n");
		choice();	//菜单界面
		scanf("%d", &num);
		switch (num) {		//使用一个switch语句来处理用户所要进行的操作
		case 1:map(); break;	//break使这个switch语句结束
		case 2:printf("请输入要查询的景点编号(1~10):\n");
			scanf("%d", &num1);
			inquire(G, num1);
			break;
		case 3:recommend(); break;
		case 4:printf("请输入您现在所在景点的编号,以及想要去的景点编号:\n");
			int start, end;
			scanf("%d %d", &start, &end);
		    Dijkstra(G,start,end);
			break;
		case 5:printf("感谢使用本校导游系统,欢迎下次再来");
			return 0;	//整个函数结束
		default:printf("请输入正确的操作指令");
			break;
		}
	}

}


//首先创立一个函数来展示学校平面图
void map() {
	//打印出学校景点的大概方位
	printf("\n");
	printf("--------------------\n");
	printf("·····1·····\n");
	printf("2···· 3·····\n");
	printf("··4·· 5···6  7\n");
	printf("··8········\n");
	printf("9···· 10·····\n");
	printf("---------------------\n");
	printf("地图备注:1--学校北门   2--老食堂   3--篮球场\n");
	printf("4--操场  5--图书馆   6--教学楼1  7--教学楼2\n");
	printf("8--新食堂  9--宿舍楼  10--学校南门\n");
}

//接着创建一个菜单供用户选择
void choice() {
	printf("********欢迎来到湖南城市学院********\n");
	printf("------------------------------------\n");
	printf("****** 1.湖南城市学院整体平面图 ****\n");
	printf("****** 2.查询所有景点信息           ****\n");
	printf("****** 3.查看推荐前往景点       ****\n");
	printf("****** 4.查询到达景点的最短路径 ****\n");
	printf("****** 5.退出                   ****\n");
	printf("------------------------------------\n");
	printf("请输入您想要进行的操作:\n");
}

//构造一个提供推荐景点的函数
void recommend() {
	printf("老食堂推荐指数:*****\n");
	printf("老食堂一楼二楼都有许多特色美食,有些菜品,口感鲜美,让人陶醉;有些佳肴,香气扑鼻,让人无法自拔。\n");
	printf("在品完美食后,还能去一楼蜜雪冰城,益禾堂,瑞幸咖啡等知名品牌店去挑选一杯下午茶,可谓是快活似神仙啊\n");
	printf("吃饱喝足才有力气,热爱美食的朋友们可千万不要错过哦\n");
	printf("\n");
	printf("学校图书馆推荐指数: ****\n");
	printf("学校图书馆收藏着大量图书,各种各样的图书应有尽有。丰富的阅读让思想的翅膀翱翔,让你轻松漫步在知识的丛林,开启智慧的翅膀\n");
	printf("向着本就属于你的高度往上攀登,终能站在巅峰");
	printf("丰富的物质固然重要,但丰富的精神内涵也缺一不可\n");
	
}

//开始录入景点信息
Graph Creat(Graph& G) {
	G.vexnum = 10;	//已知景点总数为10
	G.arcnum = 19;	
	//从1到10给景点编号
	for (int i = 1; i <= G.vexnum; i++) {
		G.vexs[i].id = i;
	}

	//开始初始化道路
	for (int j = 1; j <= G.vexnum; j++) {
		for (int k = 1; k <= G.vexnum; k++) {
			G.arcs[j][k] = INT_MAX;
		}
	}

	//开始根据实际情况输入有道路的两个顶点
	G.arcs[1][2] = G.arcs[2][1] = 300;	//道路是互通,能从一个景点到另外一个景点,也能从另外一个景点到这个景点
	G.arcs[1][3] = G.arcs[3][1] = 100;

	G.arcs[2][3] = G.arcs[3][2] = 150;
	G.arcs[2][4] = G.arcs[4][2] = 160;
	G.arcs[2][8] = G.arcs[8][2] = 310;
	G.arcs[2][9] = G.arcs[9][2] = 350;

	G.arcs[3][5] = G.arcs[5][3] = 110;
	G.arcs[3][6] = G.arcs[6][3] = 250;

	G.arcs[4][8] = G.arcs[8][4] = 170;
	G.arcs[4][9] = G.arcs[9][4] = 260;

	G.arcs[5][6] = G.arcs[6][5] = 180;
	G.arcs[5][10] = G.arcs[10][5] = 270;
	G.arcs[5][8] = G.arcs[8][5] = 280;

	G.arcs[6][10] = G.arcs[10][6] = 320;
	G.arcs[6][7] = G.arcs[7][6] = 120;

	G.arcs[7][10] = G.arcs[10][7] = 330;

	G.arcs[8][9] = G.arcs[9][8] = 190;
	G.arcs[8][10] = G.arcs[10][8] = 200;

	G.arcs[9][10] = G.arcs[10][9] = 210;

	//开始输入景点的名称和简介
	strcpy(G.vexs[1].name, "学校北门");
	strcpy(G.vexs[1].introduce,"一个供学生自由出入的大门,北门外面有着学校周边数量最多的美食摊位。");
	strcpy(G.vexs[2].name,"老食堂");
	strcpy(G.vexs[2].introduce,"窗口众多,饭菜可口,是舌尖上的美味");
	strcpy(G.vexs[3].name,"篮球场");
	strcpy(G.vexs[3].introduce,"强身健体,增进友谊,挥发汗水的宝地");
	strcpy(G.vexs[4].name,"操场");
	strcpy(G.vexs[4].introduce,"每晚都不缺夜跑的人,有许多社团活动也在这个操场举行");
	strcpy(G.vexs[5].name,"图书馆");
	strcpy(G.vexs[5].introduce,"一座充满学习氛围的殿堂,里面的每一位学生都在诠释着努力上进的姿态");
	strcpy(G.vexs[6].name,"教学楼1");
	strcpy(G.vexs[6].introduce,"平日里学生们经常上课的地方,里面布满了桌椅");
	strcpy(G.vexs[7].name,"教学楼2");
	strcpy(G.vexs[7].introduce,"学生们上课的第二场所");
	strcpy(G.vexs[8].name,"新食堂");
	strcpy(G.vexs[8].introduce,"里面大多是新开的窗口,是吃腻了老食堂的第二选择");
	strcpy(G.vexs[9].name,"宿舍楼");
	strcpy(G.vexs[9].introduce,"我们大家都需要一个港湾,而宿舍就是我们在学校的港湾,用来放松休息");
	strcpy(G.vexs[10].name,"学校南门");
	strcpy(G.vexs[10].introduce,"学校与北门遥遥相对的一道门");

	//在完成上述初始化,以及信息录入之后,返回这个图
	return G;
}

//创建一个函数用来输出一个景点的信息
void inquire(Graph G, int n) {
	if (n < 1 || n>10)
		printf("输入的景点编号有误(请输入1~10的景点编号)\n");
	else {
		printf("编号为%d的景点信息如下所示:\n", G.vexs[n].id);
		printf("该景点名称为%s\n", G.vexs[n].name);
		printf("该景点的简介:%s\n", G.vexs[n].introduce);
	}
}

//辅助函数,用来打印从start到end的路径
void PrintPath(Graph G,int prev[], int start, int end) {
	if (end == start) {		
		printf("%s", G.vexs[end].name);
		return;
	}
	PrintPath(G,prev, start, prev[end]);	//递归调用这个算法,直到把所有路径都打印出来
	printf("-> %s", G.vexs[end].name);
}

//创建一个函数来求得任意两个顶点间的最短路径
void Dijkstra(Graph& G, int start, int end) {
	int dist[MAXSIZE];	//用来存放初始顶点到其他所有顶点的距离
	int visited[MAXSIZE];	//用来存放这个顶点是否被访问过
	int prev[MAXSIZE];	//用来存放前驱顶点

	//初始化距离和前驱结点
	for (int i = 1; i <= G.vexnum; i++) {
		dist[i] = INT_MAX;	
		visited[i] = 0;
		prev[i] = -1;
	}

	dist[start] = 0;	//起始顶点到自身距离为0

	//开始遍历所有顶点
	for (int count = 0; count < G.vexnum - 1; count++) {
		int u = -1;

		//找出未访问的顶点中距离最小的顶点
		for (int i = 1; i <= G.vexnum; i++) {
			if (!visited[i] && (u == -1 || dist[i] < dist[u])) {
				u = i;
			}
		}

		visited[u] = 1;		//表示这个顶点已经被访问过

		//更新相邻顶点的距离和前驱结点
		for (int j = 1; j <= G.vexnum; j++) {	//通过判断新加了一个顶点后,能不能通过这个顶点使原来的距离更近,这是算法核心
			if (!visited[j] && G.arcs[u][j] != INT_MAX && dist[u] != INT_MAX && dist[u] + G.arcs[u][j] < dist[j]) {
				dist[j] = dist[u] + G.arcs[u][j];
				prev[j] = u;
			}
		}
	}
	//检查是否存在路径
	if (dist[end] == INT_MAX) {
		printf("从%s 到 %s 不存在路径\n", G.vexs[start].name, G.vexs[end].name);
	}
	else {
		printf("从%s 到 %s 的最短路径长度为%d,路径为:", G.vexs[start].name, G.vexs[end].name, dist[end]);
		PrintPath(G,prev, start, end);
		printf("\n");
	}
}

 

        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1991779.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据库中的约束,聚合函数以及联合查询

目录 数据库中的约束 not null unique default primary key foreign key 表的设计 聚合函数&#xff08;查询&#xff09; 分组 联表查询&#xff08;多表查询&#xff09; 内连接 外连接 左外连接 右外连接 自连接 子查询 合并查询 数据库中的约束 为了保证…

用python获取系统的硬件信息(python实例二十九)

目录 1.认识Python 2.环境与工具 2.1 python环境 2.2 Visual Studio Code编译 3.获取系统信息 3.1 代码构思 3.2 代码示例 3.3 运行部分结果 4.总结 1.认识Python Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设计具有很强的…

计算机组成原理面试-核心概念-问题理解

目录 1.怎么理解计算机组成原理中存储器、控制器、运算器、输入输出设备之间的协作关系和工作流程 2.比、比特等类似几种表示信息存储的单位具体换算 3.介绍计算机的五大功能-数据传送功能、数据存储功能、数据处理功能、操作控制功能、操作判断功能 4.计算机的工作过程/指令…

【Linux基础】Linux基本指令(一)

目录 前言1&#xff0c; ls指令2&#xff0c;pwd指令三&#xff0c;cd指令3.1 当前目录与上级目录3.2 绝对路径和相对路径3.3 tree指令 四&#xff0c;创建一个普通文件或目录4.1 touch指令4.2 mkdir指令 五&#xff0c;删除目录或文件5.1 rmdir指令5.2 rm 指令 六&#xff0c;…

华大基因阿尔茨海默病风险基因检测,助力阿尔茨海默病早预防

中国正面临日益加剧的老龄化挑战。据统计&#xff0c;2020年我国60岁以上的老年人口已达2.6亿&#xff0c;其中轻度认知障碍患者超过3800万&#xff0c;而阿尔茨海默病患者近千万。随着这一趋势的延续&#xff0c;如何早期发现和预防阿尔茨海默病已成为公共卫生领域的重要议题。…

为什么建议从二维向三维GIS开发方向拓展?

GIS开发是地理信息系统领域中一个薪资待遇较高的职业方向&#xff0c;吸引了众多来自测绘、遥感和城市规划等相关专业的学生转型投身于WebGIS开发工作。 那么&#xff0c;今天从技术角度出发&#xff0c;探讨为何鼓励大家超越WebGIS的范畴&#xff0c;继续深入学习三维GIS开发…

el-date-picker 限制开始时间和结束时间

el-date-picker 限制开始时间和结束时间 需求&#xff1a;el-date-picker 月份限制开始时间和结束时间 开始时间&#xff1a;202307 结束时间&#xff1a;202407 代码实现 vue 页面 <el-form-item label"月份" prop"monthList"><el-date-picker …

零基础5分钟上手亚马逊云科技AWS核心云开发/云架构 - 创建高可用数据库集群

简介&#xff1a; 欢迎来到小李哥全新亚马逊云科技AWS云计算知识学习系列&#xff0c;适用于任何无云计算或者亚马逊云科技技术背景的开发者&#xff0c;让大家零基础5分钟通过这篇文章就能完全学会亚马逊云科技一个经典的服务开发架构方案。 我将每天介绍一个基于亚马逊云科…

测试概论之系统测试

系统测试 文章目录 系统测试一、系统测试定义二、系统测试的对象三、系统测试类型1、功能测试2、性能测试3、压力测试4、容量测试5、GUI 测试6、可以性测试7、安装性测试8、配置测试9、异常测试10、备份测试11、健壮性测试12、文档测试13、在线帮助测试14、网络测试 四、系统测…

为什么奥运会采用通义而不是 OpenAI,现在中国的 AI 技术是世界领先了吗?

奥运会作为全球最盛大的体育赛事之一&#xff0c;一直在不断地引入和利用最新的科技来提升赛事的组织效率、观众体验以及运动员的表现。在2024年巴黎奥运会上&#xff0c;人工智能&#xff08;AI&#xff09;技术的应用尤为引人注目。 首先&#xff0c;关于奥运会采用的技术选…

数字噪音计(声级计)【AR814数字噪音计】

系统介绍 声级计&#xff0c;又叫噪音计&#xff0c;是噪声测量中最基本的仪器。声级计一般由电容式传声器、前置放大器、衰减器、放大器、频率计权网络以及有效值指示表头等组成。 声级计的工作原理是&#xff1a;由传声器将声音转换成电信号&#xff0c;再由前置放大器放大…

【json解析】控制台打印json字符串格式正确,但json.loads()解析失败问题解决

问题为控制台打印json字符串格式正确&#xff0c;但json.loads()解析失败。看似简单的问题&#xff0c;却又折腾了好一会&#xff0c;因此记录一下解决方法&#xff01; 出现这个问题的原因&#xff1a;眼见不一定为实&#xff0c;控制台打印的json字符串并不一定是实际的json字…

Typora v1.9.5解锁版下载、安装教程 (轻便简洁的Markdown编辑器)

前言 Typora是一款轻便简洁的Markdown编辑器&#xff0c;支持即时渲染技术&#xff0c;这也是与其他Markdown编辑器最显著的区别。即时渲染使得你写Markdown就想是写Word文档一样流畅自如&#xff0c;不像其他编辑器的有编辑栏和显示栏。 一、下载地址 下载链接&#xff1a;…

软件测试---Fiddler抓包

一、初识Fiddler ①BS架构简介和请求过程理解 ②Fiddler原理 Fiddler是一个代理服务器。代理地址:127.0.0.1&#xff0c;端口:8888。浏览器可以通过设置查看代理服务器&#xff1a;设置->高级->打开您计算机的代理设置->连接->局域网设置->代理服务器->在高级…

Vulnhub靶场-FRISTILEAKS: 1.3

1.环境准备 下载地址&#xff1a;https://www.vulnhub.com/entry/fristileaks-13,133/ 攻击机&#xff1a;kali&#xff08;192.168.26.128&#xff09; 靶机&#xff1a;FRISTILEAKS: 1.3 将靶机和kali的网络连接模式设置为同一种模式&#xff08;Nat模式&#xff09; 注…

【linux】linux中特殊权限管理--FACL详细用法教程与应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全…

MM 14 -采购- 固定资产采购

思维导图 说明 特点&#xff1a; 价值大于2000就算固定资产采购。 不做料号管理 不做库存管理 但是财务做资产卡片管理 流程&#xff1a; 01采购申请意向表---02资产评估表--03财务创建资产卡片AS01--04创建采购申请&#xff08;科目分配类别A&#xff09;--05采购订单--06…

不学函数式设计的3大损失

讲动人的故事&#xff0c;写懂人的代码 可能很多程序员和我一样&#xff0c;一直在一次次地重新入门函数式编程&#xff08;和设计&#xff09;。因为我们总是学了就忘。 鲍叔去年出版了他的大作《函数式设计》&#xff0c;里面有大量Clojure代码示例。如果不懂Clojure&#x…

【工具推荐】四千个厂商默认帐号密码

一、下载地址 WX关注公众号“光剑安全”&#xff0c;发送“20240808厂商”即可获得文档 二、 文档介绍 里面包括多个web产品&#xff0c;多个数据库&#xff1a;mysql、redis、MSSQL (mssql)等 多个服务协议&#xff1a;telnt、ssh、ftp、rdp等 无偿分享技术文章&#xff0c…

Elsevier 旗下又一宝藏SCI!国人发文超五成,8天上线,硕博圈的“易投易中”首选刊!

【SciencePub学术】本期&#xff0c;小编给大家介绍的是1本计算机类的SCI&#xff0c;位于JCR2区中科院4区&#xff0c;影响因子2.6分。 众所周知&#xff0c;顶刊的普遍毛病就是“速度慢&#xff0c;要求严”&#xff0c;这也是让大多数人望而却步的主要原因。虽然此刊影响因子…