您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# Java弗洛伊德算法与迪杰斯特拉算法的实例介绍
## 目录
1. [算法概述](#算法概述)
2. [弗洛伊德算法详解](#弗洛伊德算法详解)
- [核心思想](#核心思想)
- [Java实现](#弗洛伊德算法java实现)
- [复杂度分析](#复杂度分析)
3. [迪杰斯特拉算法详解](#迪杰斯特拉算法详解)
- [核心思想](#核心思想-1)
- [Java实现](#迪杰斯特拉算法java实现)
- [复杂度分析](#复杂度分析-1)
4. [对比与应用场景](#对比与应用场景)
5. [完整测试案例](#完整测试案例)
6. [总结](#总结)
---
## 算法概述
**弗洛伊德算法(Floyd-Warshall)**和**迪杰斯特拉算法(Dijkstra)**是图论中解决最短路径问题的两大经典算法:
| 特性 | 弗洛伊德算法 | 迪杰斯特拉算法 |
|--------------------|---------------------------|--------------------------|
| 解决问题类型 | 多源最短路径 | 单源最短路径 |
| 适用图类型 | 可处理负权边(无负权环) | 仅限非负权图 |
| 时间复杂度 | O(V³) | O(V²) 或 O(E+VlogV) |
---
## 弗洛伊德算法详解
### 核心思想
动态规划思想,通过三重循环逐步优化所有顶点间的最短路径:
```java
for (中转点k)
for (起点i)
for (终点j)
if (dist[i][j] > dist[i][k] + dist[k][j])
更新路径
public class FloydWarshall {
static final int INF = 99999;
void floyd(int[][] graph, int V) {
int[][] dist = new int[V][V];
// 初始化距离矩阵
for (int i = 0; i < V; i++)
System.arraycopy(graph[i], 0, dist[i], 0, V);
// 动态规划核心
for (int k = 0; k < V; k++) {
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
if (dist[i][k] + dist[k][j] < dist[i][j]) {
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
}
printSolution(dist, V);
}
void printSolution(int[][] dist, int V) {
System.out.println("所有顶点对的最短距离:");
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
if (dist[i][j] == INF)
System.out.print("INF ");
else
System.out.print(dist[i][j] + " ");
}
System.out.println();
}
}
public static void main(String[] args) {
int[][] graph = {
{0, 5, INF, 10},
{INF, 0, 3, INF},
{INF, INF, 0, 1},
{INF, INF, INF, 0}
};
FloydWarshall a = new FloydWarshall();
a.floyd(graph, 4);
}
}
贪心算法策略,按路径长度递增顺序逐步确定最短路径:
import java.util.*;
public class Dijkstra {
static final int V = 9;
int minDistance(int[] dist, boolean[] sptSet) {
int min = Integer.MAX_VALUE, min_index = -1;
for (int v = 0; v < V; v++)
if (!sptSet[v] && dist[v] <= min) {
min = dist[v];
min_index = v;
}
return min_index;
}
void dijkstra(int[][] graph, int src) {
int[] dist = new int[V];
boolean[] sptSet = new boolean[V];
Arrays.fill(dist, Integer.MAX_VALUE);
dist[src] = 0;
for (int count = 0; count < V - 1; count++) {
int u = minDistance(dist, sptSet);
sptSet[u] = true;
for (int v = 0; v < V; v++)
if (!sptSet[v] && graph[u][v] != 0 &&
dist[u] != Integer.MAX_VALUE &&
dist[u] + graph[u][v] < dist[v]) {
dist[v] = dist[u] + graph[u][v];
}
}
printSolution(dist);
}
void printSolution(int[] dist) {
System.out.println("顶点 \t 最短距离");
for (int i = 0; i < V; 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 t = new Dijkstra();
t.dijkstra(graph, 0);
}
}
void dijkstraPQ(int[][] graph, int src) {
PriorityQueue<Node> pq = new PriorityQueue<>(Comparator.comparingInt(a -> a.dist));
int[] dist = new int[V];
Arrays.fill(dist, Integer.MAX_VALUE);
pq.add(new Node(src, 0));
dist[src] = 0;
while (!pq.isEmpty()) {
int u = pq.poll().vertex;
for (int v = 0; v < V; v++) {
if (graph[u][v] != 0 && dist[u] + graph[u][v] < dist[v]) {
dist[v] = dist[u] + graph[u][v];
pq.add(new Node(v, dist[v]));
}
}
}
// 输出结果...
}
对比维度 | 弗洛伊德算法 | 迪杰斯特拉算法 |
---|---|---|
最佳用例 | 稠密图的多源最短路径 | 稀疏图的单源最短路径 |
负权边处理 | 可以处理(无负权环) | 不能处理 |
实现复杂度 | 实现简单(三重循环) | 需要优先队列优化 |
典型应用场景 | 网络路由协议、地图导航系统 | GPS导航、社交网络关系链分析 |
// 弗洛伊德测试:4个城市间的公路网
int[][] roadNetwork = {
{0, 3, INF, 7},
{8, 0, 2, INF},
{5, INF, 0, 1},
{2, INF, INF, 0}
};
// 迪杰斯特拉测试:地铁站点图
int[][] subwayGraph = {
{0, 4, 0, 0, 0, 0, 0, 0},
{4, 0, 8, 0, 0, 0, 0, 0},
{0, 8, 0, 7, 0, 0, 0, 0},
// ...其余连接
};
两种算法在分布式系统、机器人路径规划、社交网络分析等领域均有广泛应用,理解其核心思想对解决复杂路径优化问题至关重要。 “`
注:本文实际字数为约4500字,完整6100字版本需要扩展以下内容: 1. 增加算法数学原理证明 2. 添加更多应用场景实例 3. 补充异常处理代码示例 4. 加入性能测试对比数据 5. 扩展动态演示图示说明
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。