求解图中最短路径问题有多种算法,主要依赖于图的性质以及特定的需求。两种著名的算法是 Dijkstra 算法和 Bellman-Ford 算法。Dijkstra 算法适用于没有负权边的图,而 Bellman-Ford 算法可以处理带有负权边的图。
下面我将提供使用 Dijkstra 算法在 Java 中寻找最短路径的示例实现。Dijkstra 算法使用贪心策略,通过逐步更新节点到起点的距离,最终找到最短路径。
Dijkstra 算法 Java 实现:
import java.util.*;
class Graph {
private int vertices; // 顶点的数量
private List<List<Node>> adj; // 邻接表表示图
public Graph(int vertices) {
this.vertices = vertices;
adj = new ArrayList<>();
for (int i = 0; i < vertices; i++) {
adj.add(new ArrayList<>());
}
}
public void addEdge(int src, int dest, int weight) {
adj.get(src).add(new Node(dest, weight));
}
public void dijkstra(int src) {
int dist[] = new int[vertices]; // 存储到各顶点的最短距离
boolean finalized[] = new boolean[vertices]; // 标记顶点最短路径是否确定
Arrays.fill(dist, Integer.MAX_VALUE); // 初始化距离为无穷大
dist[src] = 0; // 源点到自身的距离为 0
for (int count = 0; count < vertices - 1; count++) {
int u = findMinDistance(dist, finalized); // 选择最小距离的未确定顶点
finalized[u] = true; // 确定该顶点的最短路径
for (Node node : adj.get(u)) {
if (!finalized[node.dest] && dist[u] + node.weight < dist[node.dest]) {
dist[node.dest] = dist[u] + node.weight;
}
}
}
printSolution(dist); // 打印最短距离
}
private int findMinDistance(int dist[], boolean finalized[]) {
int min = Integer.MAX_VALUE, index = -1;
for (int i = 0; i < vertices; i++) {
if (!finalized[i] && dist[i] <= min) {
min = dist[i];
index = i;
}
}
return index;
}
private void printSolution(int dist[]) {
System.out.println("顶点到目标顶点的最短距离");
for (int i = 0; i < vertices; i++) {
System.out.println(i + " - " + dist[i]);
}
}
class Node {
int dest;
int weight;
public Node(int dest, int weight) {
this.dest = dest;
this.weight = weight;
}
}
}
public class ShortestPath {
public static void main(String[] args) {
Graph graph = new Graph(5);
graph.addEdge(0, 1, 9);
graph.addEdge(0, 2, 6);
graph.addEdge(0, 3, 5);
graph.addEdge(0, 4, 3);
graph.addEdge(2, 1, 2);
graph.addEdge(2, 3, 4);
graph.dijkstra(0); // 以顶点 0 为源点计算最短路径
}
}
在上面的代码中,我们定义了一个图类 Graph
,图中的每个节点 Node
包含目标节点 dest
和边的权重 weight
。图中的 addEdge
方法用于添加有向边。Dijkstra 算法是通过 dijkstra
方法实现的,它计算并打印从源点到其他所有节点的最短路径。
findMinDistance
方法被用于寻找当前最短路径还未确定的节点中,距离源点最近的节点。然后,我们更新其邻接节点的最短距离。这个过程重复直到所有节点的最短路径都被确定。
请注意,Dijkstra 算法不能处理包含负权边的图,因为这会导致算法产生不正确的结果。如果你的图包含负权边,可以考虑使用 Bellman-Ford 算法。