网站首页 > 技术教程 正文
Dijkstra最短路径算法
给定一个图和图中的一个源顶点A,找到从源顶点A到给定图中所有顶点的最短路径,边的数值为顶点之间的距离。
Dijkstra算法与Prim算法的MST(最小生成树)一样,生成以给定源为根的SPT(最短路径树)。维护两组集合,一组包含包含在SPT中的顶点,另一组包含尚未包含在SPT中的顶点。在算法的每一步,找到尚未包含在SPT集合中其与源顶点距离最小的顶点,并加入到SPT中。
步骤:
- 创建SPT空集合和一个包含N的顶点的dist距离数组,源顶点的距离初始化为0,其它顶点为无限大。
- 从dist数组选择一个距离最小并且不在SPT集合中的顶点v。
- 把顶点v加入SPT集合。
- 更新与顶点v相邻顶点的dist距离值,重复2~4步,直到SPT包含所有的顶点。
- dist数组即为从源顶点到所有顶点的最短距离。
算法结果演示
sptSet: A
dist: [0, inf, inf, inf, inf, inf, inf, inf, inf]
----------------------------------------
sptSet: A C
dist: [0, 3, 2, inf, inf, inf, inf, inf, inf]
----------------------------------------
sptSet: A C B
dist: [0, 3, 2, 9, 8, inf, inf, 10, inf]
----------------------------------------
sptSet: A C B F
dist: [0, 3, 2, 8, 8, 7, inf, 10, inf]
----------------------------------------
sptSet: A C B F D
dist: [0, 3, 2, 8, 8, 7, 12, 10, 12]
----------------------------------------
sptSet: A C B F D E
dist: [0, 3, 2, 8, 8, 7, 12, 10, 12]
----------------------------------------
sptSet: A C B F D E H
dist: [0, 3, 2, 8, 8, 7, 12, 10, 12]
----------------------------------------
sptSet: A C B F D E H G
dist: [0, 3, 2, 8, 8, 7, 12, 10, 12]
----------------------------------------
sptSet: A C B F D E H G I
dist: [0, 3, 2, 8, 8, 7, 12, 10, 12]
----------------------------------------
顶点 | 从源到所有顶点的距离 |
A | 0 |
B | 3 |
C | 2 |
D | 8 |
E | 8 |
F | 7 |
G | 12 |
H | 10 |
I | 12 |
代码实现(python, C)
# python
import sys
class Graph():
def __init__(self, vertices):
self.vertices = vertices
self.graph = [[0 for column in range(vertices)]
for row in range(vertices)]
def show(self, dist):
print("Vertex \t\tDistance from Source")
for v in range(self.vertices):
print(chr(v+65), "\t\t", dist[v])
def minDistance(self, dist, sptSet):
min = sys.maxsize
for v in range(self.vertices):
if dist[v] < min and v not in sptSet:
min = dist[v]
min_index = v
return min_index
def dijkstra(self, src):
dist = [sys.maxsize] * self.vertices # 记录从原点出发,到每个节点的距离,初始为无限远
dist[src] = 0
sptSet = []
for cout in range(self.vertices):
x = self.minDistance(dist, sptSet)
sptSet.append(x)
for y in range(self.vertices):
# 与x顶点相邻且不在setSet中,x到相邻顶点的距离小于目前dist记录的距离,
# 则更新相应顶点在dist中距离
if self.graph[x][y] > 0 and y not in sptSet and \
dist[y] > dist[x] + self.graph[x][y]:
dist[y] = dist[x] + self.graph[x][y]
self.show(dist)
g = Graph(9)
# graph表示每个顶点和其它顶点的距离,0表示没有相连
# 0, 1, 2, 3, 4, 5, 6, 7, 8
g.graph = [[0, 3, 2, 0, 0, 0, 0, 0, 0], #0
[3, 0, 0, 5, 0, 4, 0, 0, 0], #1
[2, 0, 0, 7, 6, 0, 0, 8, 0], #2
[0, 5, 7, 0, 4, 0, 0, 0, 0], #3
[0, 0, 6, 4, 0, 8, 0, 0, 9], #4
[0, 4, 0, 0, 8, 0, 5, 0, 5], #5
[0, 0, 0, 0, 0, 5, 0, 0, 3], #6
[0, 0, 8, 0, 0, 0, 0, 0, 4], #7
[0, 0, 0, 0, 9, 5, 3, 4, 0]];#8
g.dijkstra(0);
// C
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#define VERTICES 9
void show(uint32_t dist[])
{
printf("Vertex \t\tDistance from Source\n");
for(int v = 0; v < VERTICES; v++)
printf("%c\t\t%u\n", 'A' + v, dist[v]);
}
uint32_t minDistance(uint32_t dist[], uint32_t sptSet[])
{
uint32_t min = ~(0);
uint32_t min_index = 0;
for(int v = 0; v < VERTICES; v++) {
if (dist[v] < min && sptSet[v] == 0) {
min = dist[v];
min_index = v;
}
}
return min_index;
}
void dijkstra(uint32_t graph[][VERTICES], int src_vertice)
{
uint32_t dist[VERTICES] = {~0}; // 记录从原点出发,到每个节点的距离,初始为无限远
uint32_t sptSet[VERTICES] = {0};
memset(dist, ~0, sizeof(dist));
memset(sptSet, 0, sizeof(sptSet));
dist[src_vertice] = 0;
for (int i = 0; i < VERTICES; i++) {
int x = minDistance(dist, sptSet);
sptSet[x] = 1;
for (int y = 0; y < VERTICES; y++) {
/* 与x顶点相邻且不在setSet中,x到相邻顶点的距离小于目前dist记录的距离,
则更新相应顶点在dist中距离*/
if (graph[x][y] > 0 && sptSet[y] == 0 &&
dist[y] > dist[x] + graph[x][y]) {
dist[y] = dist[x] + graph[x][y];
}
}
}
show(dist);
}
void main(void)
{
// graph表示每个顶点和其它顶点的距离,0表示没有相连
uint32_t graph[][VERTICES] =
// 0, 1, 2, 3, 4, 5, 6, 7, 8
{{0, 3, 2, 0, 0, 0, 0, 0, 0}, // 0
{3, 0, 0, 5, 0, 4, 0, 0, 0}, // 1
{2, 0, 0, 7, 6, 0, 0, 8, 0}, // 2
{0, 5, 7, 0, 4, 0, 0, 0, 0}, // 3
{0, 0, 6, 4, 0, 8, 0, 0, 9}, // 4
{0, 4, 0, 0, 8, 0, 5, 0, 5}, // 5
{0, 0, 0, 0, 0, 5, 0, 0, 3}, // 6
{0, 0, 8, 0, 0, 0, 0, 0, 4}, // 7
{0, 0, 0, 0, 9, 5, 3, 4, 0}}; // 8
dijkstra(graph, 0);
}
猜你喜欢
- 2024-10-25 AMEYA360报道:智能扫地机器人 SLAM技术与A算法
- 2024-10-25 基于LFOA算法的相关向量机核参数优化
- 2024-10-25 定积分的换元法与分部积分法 定积分的换元和分部
- 2024-10-25 Apriori算法是什么?适用于什么情境?
- 2024-10-25 用Python写一个A*搜索算法含注释说明
- 2024-10-25 浅谈什么是分治算法 浅谈什么是分治算法是什么
- 2024-10-25 技术分享 | Prometheus避障—A_star算法代码阅读
- 2024-10-25 浅析机器人学位置与姿态之坐标系绕任意轴线旋转算法
- 2024-10-25 一文简介常见的机器学习算法 常见机器学习算法
- 2024-10-25 欧几里得算法 最大公约数欧几里得算法
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- sd分区 (65)
- raid5数据恢复 (81)
- 地址转换 (73)
- 手机存储卡根目录 (55)
- tcp端口 (74)
- project server (59)
- 双击ctrl (55)
- 鼠标 单击变双击 (67)
- debugview (59)
- 字符动画 (65)
- flushdns (57)
- ps复制快捷键 (57)
- 清除系统垃圾代码 (58)
- web服务器的架设 (67)
- 16进制转换 (69)
- xclient (55)
- ps源文件 (67)
- filezilla server (59)
- 句柄无效 (56)
- word页眉页脚设置 (59)
- ansys实例 (56)
- 6 1 3固件 (59)
- sqlserver2000挂起 (59)
- vm虚拟主机 (55)
- config (61)
本文暂时没有评论,来添加一个吧(●'◡'●)