栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

终于搞懂Dijkstra算法了

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

终于搞懂Dijkstra算法了

文章目录
  • 示例1
  • 示例2
  • 参考资料

Dijkstra算法用来解决单源最短路径问题,思路如下

将图中顶点分为2部分
S:已经找到最短路径的顶点
U:剩下的顶点
假设初始顶点为v0, 那么S:{v0}, U:{剩下的顶点}
从U中找到一个距离v0最近的一个顶点,假设为x,将x从U中移动到S。
对于U中的任意顶点y,如果d[v0][x] + d[x][y] < d[v0][y], 则d[v0][y] = d[v0][x] + d[x][y]。
如此循环,直到处理完U中所有顶点。

Dijkstra是按照路径长度递增的顺序,来求解v0到其他顶点的所有最短路径。
是一个贪心算法。

示例1

代码

// g[i][j]:顶点i、顶点j之间的距离
// 如果i、j直连,就是边ij的长度,
// 否则对应math.MaxInt32【i == j 时,也是math.MaxInt32】

// 返回 顶点 start 到 其他顶点 的最短距离
func shortestPath(g [][]int, start int) []int {
	// 顶点个数
	n := len(g)
	// 存储 顶点 start 到 其他顶点 的最短距离
	distance := make([]int, n)
	// start -> start的距离为0
	distance[start] = 0
	// 标记顶点的访问状态
	visited := make([]bool, n)
	// 顶点 start 加入到 S
	visited[start] = true
	// 确定剩下 n-1 个 顶点 的最短距离
	for i := 1; i < n; i++ {
		// 在 U 中找到最短路径对应的顶点
		// 需要比边的最大值要大
		min := math.MaxInt32 + 1
		var k int
		for j := 0; j < n; j++ {
			if !visited[j] && g[start][j] < min {
				min = g[start][j]
				k = j
			}
		}
		// 顶点 k 加入到 S
		visited[k] = true
		distance[k] = min
		// 更新 U 中的路径
		for j := 0; j < n; j++ {
			if !visited[j] && min+g[k][j] < g[start][j] {
				g[start][j] = min + g[k][j]
			}
		}
	}
	return distance
}

1个示例

输入

func Test_xx(t *testing.T) {
	g := [][]int{
		{math.MaxInt32, 4, math.MaxInt32, 2, math.MaxInt32},
		{4, math.MaxInt32, 4, 1, math.MaxInt32},
		{math.MaxInt32, 4, math.MaxInt32, 1, 3},
		{2, 1, 1, math.MaxInt32, 7},
		{math.MaxInt32, math.MaxInt32, 3, 7, math.MaxInt32},
	}
	fmt.Println(shortestPath(g, 0))
}

输出

[0 3 3 2 6]

再给一个示例

输入

func Test_xx(t *testing.T) {
	g := [][]int{
		{math.MaxInt32, math.MaxInt32, 10, math.MaxInt32, 30, 100},
		{math.MaxInt32, math.MaxInt32, 5, math.MaxInt32, math.MaxInt32, math.MaxInt32},
		{math.MaxInt32, math.MaxInt32, math.MaxInt32, 50, math.MaxInt32, math.MaxInt32},
		{math.MaxInt32, math.MaxInt32, math.MaxInt32, math.MaxInt32, math.MaxInt32, 10},
		{math.MaxInt32, math.MaxInt32, math.MaxInt32, 20, math.MaxInt32, 60},
		{math.MaxInt32, math.MaxInt32, math.MaxInt32, math.MaxInt32, math.MaxInt32, math.MaxInt32},
	}
	fmt.Println(shortestPath(g, 0))
}

输出

[0 2147483647 10 50 30 60]

上述代码会修改输入g,下面给一个不修改g的版本

示例2
func shortestPath2(g [][]int, start int) []int {
	n := len(g)
	distance := make([]int, n)
	for i := 0; i < n; i++ {
		distance[i] = g[start][i]
	}
	distance[start] = 0
	visited := make([]bool, n)
	visited[start] = true
	for i := 1; i < n; i++ {
		min := math.MaxInt32 + 1
		var k int
		for j := 0; j < n; j++ {
			if !visited[j] && distance[j] < min {
				min = distance[j]
				k = j
			}
		}
		visited[k] = true
		for j := 0; j < n; j++ {
			if !visited[j] && min+g[k][j] < distance[j] {
				distance[j] = min + g[k][j]
			}
		}
	}
	return distance
}
参考资料

https://houbb.github.io/2020/01/23/data-struct-learn-03-graph-dijkstra

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/857105.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号