C语言数据结构——图的最短路径算法解决实例问题

这篇具有很好参考价值的文章主要介绍了C语言数据结构——图的最短路径算法解决实例问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、问题描述

W公司在某个地区有6个产品销售点,现根据业务需要打算在其中某个销售点上建立一个中心仓库,负责向其他销售点提供产品。由于运输线路不同,运输费用也不同。假定每天需要向每个销售点运输一次产品,那么应将中心仓库建在哪个销售点上,才能使运输费用达到最低。

C语言数据结构——图的最短路径算法解决实例问题

二、算法实现

第一种算法——迪杰斯特拉算法实现

1、算法思路

迪杰斯特拉(Dijkstra)算法是典型最短路径算法, 是用于计算图中一个顶点到其他各顶点的最短路径,该算法的主要特点是以起始点为中心向外层层扩展(广度优先遍历思想),直到扩展到终点为止。

(1)初始化一个起始顶点v0、数组Dist[maxsize]和Visited[maxsize]数组,Dist[maxsize]用于存储从该顶点到图中其他顶点的最短路径长度,Visited[maxsize]用于标记从vo结点到图中其他顶点是否已经找到了最短路径。

(2)算法首先让vo顶点到其所有邻接点的距离赋值给Dist数组,后选择与v0顶点相距最近的邻接点v1。继续从v1顶点出发,找到其所有邻接点,比较v0结点通过v1到v1的邻接点的路径距离是否变短,若变短,则将新的最短路径距离(v0到v1邻接点的距离)在Dist数组中进行更新。若v0到达一个顶点的最短距离已经求出,对其标志数组Visited赋值为1。

(3)重复(2)步骤,直到v0到所有图中顶点的最短路径距离求出,算法结束。

以上是实现迪杰斯特拉(Dijkstra)算法的实现,回到问题上,我们要将中心仓库建在一个销售点上,使得运输费用达到最低,为此们只需要在迪杰斯特拉(Dijkstra)算法外部加一个循环,依次计算图中的每一个销售点到其他销售点最小运输费用的总和。最终我们得出了使得运输费用达到最低的销售点,该销售点就是我们建中心仓库的最佳选择。

2、算法代码如下

#include<stdio.h>
#define maxsize 10
#define inf 10000
typedef char VertexType;
typedef struct {
	VertexType vexs[maxsize];
	int arcs[maxsize][maxsize];
	int n, e;
} Mgraph;
//定位顶点v在顶点数组中的位置
int LocateVexPos(Mgraph* G, char v) {
	int i;
	for (i = 0; i < G->n; i++)
		if (G->vexs[i] == v)
			return i;
	return -1;
}
//根据构造无向图-邻接矩阵存储结构
void CreateMGraph(Mgraph* G)
{
	int i, j, k, posi, posj, temp;
	char vi, vj;
	printf("请输入图的顶点数和边数(输入格式为:顶点数,边数):  ");
	scanf_s("%d,%d", &(G->n), &(G->e));
	printf("请输入顶点信息(连续输入):  ");
	getchar();
	for (i = 0; i < G->n; i++)
		scanf_s("%c", &(G->vexs[i]), sizeof(char));
	for (i = 0; i < G->n; i++)
		for (j = 0; j < G->n; j++)
			G->arcs[i][j] = inf;
	getchar();
	for (k = 0; k < G->e; k++)
	{
		printf("请输入第%d条边(输入格式为:起点,终点,权值): ", k + 1);
		scanf_s("%c,%c,%d", &vi, sizeof(char), &vj, sizeof(char), &temp, sizeof(int));
		getchar();
		posi = LocateVexPos(G, vi);
		posj = LocateVexPos(G, vj);
		G->arcs[posi][posj] = temp;
		G->arcs[posj][posi] = temp;
	}
}
// 求一个顶点到其他顶点的最短路径—迪杰斯特拉算法(Dijsta)
int Dijsta_Path(Mgraph* G, int v0, int Dist[maxsize])
{
	int i, j, k, v, sum = 0;
	int visited[maxsize] = { 0 };
	for (i = 0; i < G->n; i++)
	{
		Dist[i] = G->arcs[v0][i];
	}
	visited[v0] = 1;
	Dist[v0] = 0;
	for (i = 1; i < G->n; i++)
	{
		int min = inf;
		for (j = 0; j < G->n; j++)
		{
			if (!visited[j])
			{
				if (Dist[j] < min)
				{
					v = j;
					min = Dist[j];
				}
			}
		}
		visited[v] = 1;
		for (k = 0; k < G->n; k++)
		{
			if (!visited[k] && (Dist[k] > min + G->arcs[v][k]))
			{
				Dist[k] = min + G->arcs[v][k];
			}
		}
	}
	for (i = 0; i < G->n; i++)
	{
		sum += Dist[i];
	}
	return sum;
}
void Calcu_Cost(Mgraph* G, int Dist[maxsize])
{
	int i, j, k, min_cost = inf;
	int cost[maxsize] = { 0 };
	for (i = 0; i < G->n; i++)
	{
		cost[i] = Dijsta_Path(G, i, Dist);
		if (cost[i] < min_cost)
		{
			min_cost = cost[i];
			k = i;
		}
	}
	printf("\n");
	for (i = 0; i < G->n; i++)
	{
		printf("中心仓库建在销售点%c上到其他销售点的总运输费用为:%d$\n", G->vexs[i], cost[i]);
	}
	printf("\n综上可知,中心仓库建在销售点%c时总运输费用最小,费用最小为:%d\n", G->vexs[k], min_cost);
}
void main()
{
	int Dist[maxsize];
	Mgraph G;
	CreateMGraph(&G);
	Calcu_Cost(&G, Dist);
}

3、代码运行结果:
C语言数据结构——图的最短路径算法解决实例问题
4、代码运行效率分析

迪杰斯特拉 ( Dijkstra) 算法是 一个按路径长度递增的次序产生最短路径的算法,该算法是一种贪心算法,从代码实现上可以看出,运用两个循环结构进行求解,时间复杂度为 O (n2),采用邻接矩阵存储图,空间复杂度为O(n2),n为图中顶点个数,当我们在解决运输费用达到最低这个问题时,需要计算图中的每一个销售点到其他销售点最小运输费用​的总和,因此需要原有算法的基础上再来一次循环,此时的时间复杂度为O (n^3)。

第二种算法—— 弗洛伊德(Floyd)算法实现

1、算法思路

弗洛伊德算法是一种用于求图中任意两顶点间最短路径的算法,该算法运用三重循环暴力求解,弗洛伊德算法中每一个顶点都是出发访问点,需要将每一个顶点看做被访问顶点,求出从每一个顶点到其他顶点的最短路径。该算法设定了两个二维数组,Path[maxsize][maxsize]和Dist[maxsize][maxszie],Path类似一个路径矩阵,记录一个顶点到图中其他顶点经过的路径顶点,Dist[maxsize][maxszie]类似一个最短距离矩阵,记录一个顶点到图中其他顶点的最短路径距离,弗洛伊德算法使用了三重循环,k为中转点,v为起点,w为终点,循环比较Dist[v][w] 和 Dist[v][k] + Dist[k][w] 最小值,如果Dist[v][k] + Dist[k][w] 为更小值,则把Dist[v][k] + Dist[k][w] 覆盖保存在Dist[v][w]中。
经过三重循环后,Dist数组中保存着每个顶点到图中其他顶点的最短距离。根据这个算法,我们计算图中每一个销售点到其他销售点最小运输费用的总和。最终我们可以得出使得运输费用达到最低的销售点,该销售点就是我们建中心仓库的最佳选择。

2、算法代码如下

#include<stdio.h>
#define maxsize 10
#define inf 10000
typedef char VertexType;
typedef struct {
	VertexType vexs[maxsize];
	int arcs[maxsize][maxsize];
	int n, e;
}Mgraph;
//定位顶点v在顶点数组中的位置
int LocateVexPos(Mgraph* G, char v)
{
	int i;
	for (i = 0; i < G->n; i++)
		if (G->vexs[i] == v)
			return i;
	return -1;
}
//根据构造无向图-邻接矩阵存储结构
void CreateMGraph(Mgraph* G)
{
	int i, j, k, posi, posj, temp;
	char vi, vj;
	printf("请输入图的顶点数和边数(输入格式为:顶点数,边数):  ");
	scanf_s("%d,%d", &(G->n), &(G->e));
	printf("请输入顶点信息(连续输入):  ");
	getchar();
	for (i = 0; i < G->n; i++)
		scanf_s("%c", &(G->vexs[i]), sizeof(char));
	for (i = 0; i < G->n; i++)
	{
		for (j = 0; j < G->n; j++)
		{
			if (i == j)
				G->arcs[i][j] = 0;
			else
				G->arcs[i][j] = inf;
		}
	}
	getchar();
	for (k = 0; k < G->e; k++)
	{
		printf("请输入第%d条边(输入格式为:起点,终点,权值):  ", k + 1);
		scanf_s("%c,%c,%d", &vi, sizeof(char), &vj, sizeof(char), &temp, sizeof(int));
		getchar();
		posi = LocateVexPos(G, vi);
		posj = LocateVexPos(G, vj);
		G->arcs[posi][posj] = temp;
		G->arcs[posj][posi] = temp;
	}
}
// 求某个顶点到另一顶点的最短路径,弗洛伊德算法(Floyd算法)
void Floyd_path(Mgraph* G, int D[maxsize][maxsize])
{
	int v, w, u;
	for (v = 0; v < G->n; v++)
	{
		for (w = 0; w < G->n; w++)
		{
			D[v][w] = G->arcs[v][w];
		}
	}
	for (u = 0; u < G->n; u++)
	{
		for (v = 0; v < G->n; v++)
		{
			for (w = 0; w < G->n; w++)
			{
				if (D[v][w] > D[v][u] + D[u][w])
				{
					D[v][w] = D[v][u] + D[u][w];
				}
			}
		}
	}
}
void Calcul_Cost(Mgraph* G, int D[maxsize][maxsize])
{
	int i, j, k, min_cost = inf;
	int cost[maxsize] = { 0 };
	Floyd_path(G, D);
	for (i = 0; i < G->n; i++)
	{
		for (j = 0; j < G->n; j++)
		{
			cost[i] += D[i][j];
		}
		if (cost[i] < min_cost)
		{
			min_cost = cost[i];
			k = i;
		}
	}
	printf("\n");
	for (i = 0; i < G->n; i++)
	{
		printf("中心仓库建在销售点%c上到其他销售点的总运输费用为:%d$\n", G->vexs[i], cost[i]);
	}
	printf("\n综上可知,中心仓库建在销售点%c时总运输费用最小,费用最小为:%d\n", G->vexs[k], min_cost);
}
void main()
{
	int D[maxsize][maxsize];
	Mgraph G;
	CreateMGraph(&G);
	Calcul_Cost(&G, D);
}

3、代码运行结果 :
C语言数据结构——图的最短路径算法解决实例问题
4、代码运行效率分析

Floyd算法是一种动态规划算法,运用三重循环暴力求解最短路径,该算法的时间复杂度为O(n3),运用了邻接矩阵存储图,空间复杂度为O (n2)为顶点数,相比于Dijsta算法,该算法简洁明了,易于实现,Floyd算法可以计算出图中任意两个顶点之间的最短距离,适用于计算多源最短路径,而 Floyd算法适用于计算单源最短路径。文章来源地址https://www.toymoban.com/news/detail-480791.html

到了这里,关于C语言数据结构——图的最短路径算法解决实例问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java高阶数据结构 & 图的最短路径问题

    图的最短路径问题! 图的基础知识博客:传送门 最短路径问题: 从在带权图的某一顶点出发,找出一条通往另一顶点的最短路径, 最短也就是沿路径各边的权值总 和达到最小 。 一共会讲解三种算法 Dijkstra算法【单源最短路径】 Bellman-Ford算法【单源最短路径】 改进:SPF

    2024年02月04日
    浏览(37)
  • 数据结构实验任务六 :基于 Dijsktra 算法的最短路径求解

    本次代码为实验六:基于 Dijsktra 算法的最短路径求解实现。本实验的重点在于对于Dijsktra算法的理解。有关Dijsktra的资料可以参考有关博文: 图论:Dijkstra算法——最详细的分析,图文并茂,一次看懂!-CSDN博客 以下附上实现代码: 以上代码仅供参考,欢迎交流。

    2024年02月04日
    浏览(35)
  • java数据结构与算法刷题-----LeetCode1091. 二进制矩阵中的最短路径

    java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完): https://blog.csdn.net/grd_java/article/details/123063846 双分裂蛇:是求二维表中从起点到终点的经典思路(也是求无权图的最短路径问题的经典解法)。创建两条分裂蛇,分别从起点和

    2024年04月26日
    浏览(30)
  • 算法:关于图的最短路径算法

    本篇总结的是图当中的最短路径算法 单源最短路径问题:给定一个图 G = ( V , E ) G=(V,E)G=(V,E) ,求源结点 s ∈ V s∈Vs∈V 到图中每个结点 v ∈ V v∈Vv∈V 的最短路径。 Dijkstra 算法就适用于解决带权重的有向图上的单源最短路径问题,同时算法要求图中所有边的权重非负。一

    2024年02月19日
    浏览(22)
  • matlab算法模型——图的最短路径和距离

    目录 一、前言 二、最短路径 1.sqarse创建稀疏矩阵 ​​2.有向图的最短路径         使用graphallshortestpaths函数 使用dijkstra.ma函数(直接引用) 3.无向图的最短路径 使用函数graphallshortestpaths(2021的版本不能用了) 使用shortestpath函数 三、未解决的问题 动态规划——求解某类问题

    2024年02月04日
    浏览(24)
  • DS图—图的最短路径(无框架)迪杰斯特拉算法

    目录 题目描述 AC代码 题目描述 给出一个图的邻接矩阵,输入顶点v,用迪杰斯特拉算法求顶点v到其它顶点的最短路径。 输入 第一行输入t,表示有t个测试实例 第二行输入顶点数n和n个顶点信息 第三行起,每行输入邻接矩阵的一行,以此类推输入n行 第i个结点与其它结点如果

    2023年04月08日
    浏览(26)
  • C语言算法与数据结构,旅游景区地图求最短路径

    本次作业要求完成一个编程项目。请虚构一张旅游景区地图,景区地图包括 景点(结点)和道路(边):地图上用字母标注出一些点,表示景点(比如,以点 A、B、C、D、E、F等(至少6个点)多个表示,其中的 两个字母 A 和 B 分别表示景区的入口和出口 );点与点之间的连

    2024年02月04日
    浏览(29)
  • 详解图的最短路径算法(BFS、Dijkstra、Floyd)(附上图解步骤)

    最短路径分为两种: (1)单源路径:从某顶点出发,到其他全部顶点的最短路径 (2)顶点间的最短路径:任意两个顶点之间的最短路径 最短路径的结果主要有两个方面: (1)顶点之间最短路径的长度 (2)从源顶点到目标顶点的路径 只有边权为 1 时才能用BFS求最短路。

    2024年02月05日
    浏览(37)
  • 数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。

    最短路径的算法有两个, Dijkstra算法 和 Floyd算法 。 Dijkstra算法 解决的是 单源 最短路径问题 。 Floyd算法解决的是 多源 最短路径问题,并且可以处理负权图 。 今天要讲的就是Dijkstra算法。 加: feng--Insist (大写的i),进java交流群讨论互联网+技术。可索要PPT等资料。 其他资料

    2024年02月11日
    浏览(33)
  • C语言---数据结构实验---哈夫曼树及哈夫曼编码的算法实现---图的基本操作

    本篇实验代码非本人写,代码源自外部,经调试解决了部分warning和error后在本地vs上可以正常运行,如有运行失败可换至vs 未来会重构实现该两个实验 内容要求: 1、初始化(Init):能够对输入的任意长度的字符串s进行统计,统计每个字符的频度,并建立哈夫曼树 2、建立编码

    2024年02月13日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包