迪杰斯特拉算法

1.什么是迪杰斯特拉算法?

迪杰斯特拉算法是一种用于在加权图中找到最短路径的算法,由荷兰计算机科学家Edsger W. Dijkstra于1956年提出。这个算法可以解决单源最短路径问题,即从图中的一个顶点到其他所有顶点的最短路径问题。它是一个贪心算法,通过不断选择最小的未处理的顶点来更新其他顶点的最短路径。

  • 迪杰斯特拉算法不适用于包含负权边的图

2.算法步骤

算法的基本步骤:

  1. 初始化:选择源点,并将所有顶点的最短路径估计值初始化为无穷大,除了源点自身初始化为0。

  2. 选择最小的未处理顶点:从未处理的顶点中选择一个距离最小的顶点。

  3. 更新邻接顶点的最短路径:对于刚刚选择的顶点,更新所有邻接顶点的最短路径估计值。

  4. 重复步骤2和3,直到所有顶点都被处理过。

实现思路:

首先设置一个Graph包含7个顶点的有向无权图,设置源点为0,计算从源点到剩余节点的最短路径。

引入两个集合dist和distset。dist的作用是记录已求出最短路径的顶点,而distset则是记录还未求出最短路径的顶点(以及该顶点到起点vs的距离)。

初始时,dist中只有起点vs;distset中是除vs之外的顶点,并且distset中顶点的路径是"起点vs到该顶点的路径"。然后,从distset中找出路径最短的顶点,并将其加入到dist中;接着,更新U中的顶点和顶点对应的路径。 然后,再从distset中找出路径最短的顶点,并将其加入到dist中;接着,更新distset中的顶点和顶点对应的路径。 ... 重复该操作,直到遍历完所有顶点。

3.代码实现

public class DijkstraAlgorithm {
// 定义无穷大,用于初始化距离
public static final int INF = Integer.MAX_VALUE;

// 迪杰斯特拉算法实现
public static void dijkstra(int[][] graph, int src) {
int[] dist = new int[graph.length]; // 存储源点到各点的最短距离
boolean[] sptSet = new boolean[graph.length]; // 标记节点是否处理过

// 初始化所有距离为无穷大,sptSet[]为false
for (int i = 0; i < graph.length; i++) {
dist[i] = INF;
sptSet[i] = false;
}

// 源点到自身的距离始终为0
dist[src] = 0;

// 找到所有顶点的最短路径
for (int count = 0; count < graph.length - 1; count++) {
// 选择一个最小距离的未处理节点
int u = minDistance(dist, sptSet);
// 标记节点为已处理
sptSet[u] = true;

// 更新相邻节点的距离
for (int v = 0; v < graph.length; v++) {
// 更新dist[v]只有在以下情况:
// 1. 节点v未被处理
// 2. 存在从u到v的边
// 3. 从src到v的总权重小于当前dist[v]的值
if (!sptSet[v] && graph[u][v] != 0 &&
dist[u] != INF && dist[u] + graph[u][v] < dist[v]) {
dist[v] = dist[u] + graph[u][v];
}
}
}

// 打印构建的距离数组
printSolution(dist);
}

// 辅助函数,找到最短距离中未处理的节点
public static int minDistance(int[] dist, boolean[] sptSet) {
int min = INF, minIndex = -1;

for (int v = 0; v < dist.length; v++) {
if (!sptSet[v] && dist[v] <= min) {
min = dist[v];
minIndex = v;
}
}

return minIndex;
}

// 打印最短距离数组
public static void printSolution(int[] dist) {
System.out.println("Vertex \t\t Distance from Source");
for (int i = 0; i < dist.length; i++) {
System.out.println(i + " \t\t " + dist[i]);
}
}

public static void main(String[] args) {
// 示例图的邻接矩阵表示
int[][] graph = new int[][]{
{0, 4, 0, 0, 0, 0, 0, 8, 0},
{4, 0, 8, 0, 0, 0, 0, 11, 0},
{0, 8, 0, 7, 0, 4, 0, 0, 2},
{0, 0, 7, 0, 9, 14, 0, 0, 0},
{0, 0, 0, 9, 0, 10, 0, 0, 0},
{0, 0, 4, 14, 10, 0, 2, 0, 0},
{0, 0, 0, 0, 0, 2, 0, 1, 6},
{8, 11, 0, 0, 0, 0, 1, 0, 7},
{0, 0, 2, 0, 0, 0, 6, 7, 0}
};
dijkstra(graph, 0); // 以节点0为源点
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值