Dijkstra算法(戴克斯特拉算法)

Dijkstra算法是一种用于寻找图中节点间最短路径的算法。它由荷兰计算机科学家艾兹格·戴克斯特拉(Edsger W. Dijkstra)在1956年提出,并且在1959年发表。Dijkstra算法可以用于有向图和无向图,图中的边可以有权重,但权重必须是非负的。该算法不能用于包含负权边的图,因为它可能会导致算法无法正确计算最短路径。

Dijkstra算法的核心思想是贪心算法。它从起始节点开始,逐步扩展到达图中所有其他节点的最短路径。在每一步扩展中,算法都会寻找当前可达的、具有最小“已知最短路径”成本的节点,并且基于这个节点更新其邻居节点的最短路径成本。

以下是Dijkstra算法的基本步骤:

  1. 初始化:将所有节点的最短路径估计值设为无穷大,除了起始节点,其最短路径值设为0。定义一个优先队列(或者称为最小堆),用于存放所有节点,按照最短路径估计值排序。

  2. 选择最小估计值的节点:从优先队列中取出最短路径估计值最小的节点。对于第一次迭代,这个节点将是起始节点。

  3. 更新邻居的最短路径估计值:对于当前节点的每个邻居,检查是否可以通过当前节点到达它们的路径比已知的路径更短。如果是,则更新这些邻居的最短路径估计值和它们的前驱节点。

  4. 重复步骤2和3:重复这个过程,直到优先队列为空。此时,算法已找到从起始节点到图中所有其他节点的最短路径。

  5. 最终结果:算法结束后,可以从终点节点逆向追踪回起点节点,得到最短路径。

下面是Dijkstra算法的一个简单Java实现示例,假设我们使用邻接表来表示图:

import java.util.*;

public class DijkstraAlgorithm {

    static class Edge {
        int to, weight;

        Edge(int to, int weight) {
            this.to = to;
            this.weight = weight;
        }
    }

    static class Node implements Comparable<Node> {
        int id, dist;

        Node(int id, int dist) {
            this.id = id;
            this.dist = dist;
        }

        @Override
        public int compareTo(Node other) {
            return Integer.compare(this.dist, other.dist);
        }
    }

    public static int[] dijkstra(List<List<Edge>> graph, int start) {
        PriorityQueue<Node> queue = new PriorityQueue<>();
        int[] distances = new int[graph.size()];
        Arrays.fill(distances, Integer.MAX_VALUE);
        distances[start] = 0;
        queue.offer(new Node(start, 0));

        while (!queue.isEmpty()) {
            Node current = queue.poll();
            int currentNodeId = current.id;
            int currentDist = current.dist;

            if (currentDist > distances[currentNodeId]) continue;

            for (Edge edge : graph.get(currentNodeId)) {
                int next = edge.to;
                int nextDist = currentDist + edge.weight;
                if (nextDist < distances[next]) {
                    distances[next] = nextDist;
                    queue.offer(new Node(next, nextDist));
                }
            }
        }

        return distances;
    }

    public static void main(String[] args) {
        // 示例:图的初始化
        int n = 5; // 节点总数
        List<List<Edge>> graph = new ArrayList<>();
        for (int i = 0; i < n; i++) graph.add(new ArrayList<>());
        // 添加边示例:graph.get(0).add(new Edge(1, 4)); // 表示从节点0到节点1的边,权重为4

        // 添加更多边以形

成图...

        // 执行Dijkstra算法
        int[] distances = dijkstra(graph, 0); // 假设从节点0开始

        // 输出结果
        System.out.println(Arrays.toString(distances));
    }
}

这段代码展示了Dijkstra算法的核心实现,包括图的表示、优先队列的使用以及最短路径的更新过程。在实际应用中,你可能需要根据具体问题调整图的构建和最短路径的提取方式。

posted @ 2024-03-05 10:00  真哩迈  阅读(101)  评论(0)    收藏  举报