龙空技术网

JAVA-图论算法-最短路径算法

Bit旅人 103

前言:

今天咱们对“最短时间算法”大概比较注意,咱们都想要学习一些“最短时间算法”的相关知识。那么小编同时在网络上搜集了一些关于“最短时间算法””的相关内容,希望兄弟们能喜欢,同学们一起来了解一下吧!

图论算法的最短路径算法是一种用于在图(由节点和边组成的数据结构)中找到两个节点之间的最短路径的算法。最常用的最短路径算法包括Dijkstra算法和Floyd算法。

Dijkstra算法

Dijkstra算法是一种用于求解带权重图的最短路径问题的算法。它适用于所有节点对之间的最短路径问题,但不适用于带有负权重的图。

算法步骤初始化:将起始节点的距离设为0,将其它节点的距离设为无限大(表示尚未到达该节点)。选择最小距离节点:从未被选中的节点中选择距离最小的节点,并将该节点标记为已选中。更新距离:对于与该节点相邻的节点,如果通过该节点到达这些节点的距离比原来的距离短,则更新这些节点的距离。重复执行步骤2和3,直到所有节点都被选中或者没有可以更新的节点。时间复杂度

Dijkstra算法的时间复杂度取决于所使用的数据结构。如果使用邻接矩阵来表示图,则时间复杂度为O((V+E)logV),其中V是节点数,E是边数。如果使用邻接表来表示图,则时间复杂度为O(V+E)。

用途

Dijkstra算法可以用于各种场景,例如路由协议、交通控制、网络优化等。

Java代码实例

下面是一个简单的Java代码示例,用于实现Dijkstra算法:

import java.util.*;class ShortestPath {    // Dijkstra 算法求解最短路径    public static List<Long> dijkstra(int[][] graph, int start) {        int n = graph.length; // 图中的节点数量        List<Long> distance = new ArrayList<>(); // 存储每个节点到起点的最短距离(长整数类型)        List<Boolean> visited = new ArrayList<>(); // 存储每个节点是否被访问过        List<Boolean> shortest = new ArrayList<>(); // 存储每个节点是否已经计算出最短路径        for (int i = 0; i < n; i++) {            distance.add(Long.MAX_VALUE); // 初始化距离为无穷大            visited.add(false); // 初始化访问状态为未访问            shortest.add(false); // 初始化最短路径状态为未计算        }        distance.set(start, 0L); // 起点的距离为 0        PriorityQueue<Node> queue = new PriorityQueue<>(); // 用优先队列来存储节点,按照距离从小到大排序        Node node = new Node(start, 0L); // 将起点加入优先队列        queue.offer(node); // 将起点加入优先队列        while (!queue.isEmpty()) {            Node curr = queue.poll(); // 取出距离最小的节点            int v = curr.v; // 当前节点的编号            long dist = curr.dist; // 当前节点的距离            if (visited.get(v)) { // 如果已经访问过该节点,跳过                continue;            }            visited.set(v, true); // 将该节点标记为已访问            shortest.set(v, true); // 将该节点标记为已计算最短路径            for (int u = 0; u < n; u++) { // 遍历与当前节点相邻的节点                int weight = graph[v][u]; // 边的权重                if (weight > 0 && dist + weight < distance.get(u).longValue() && !visited.get(u)) { // 如果存在一条从 v 到 u                                                                                                    // 的路径,并且该路径比当前 u                                                                                                    // 的最短距离更短,更新距离                    distance.set(u, dist + weight);                    node = new Node(u, distance.get(u)); // 将 u 加入优先队列                    queue.offer(node); // 将 u 加入优先队列                }            }        }        return distance; // 返回每个节点到起点的最短距离    }    // 最短路径测试用例    public static void main(String[] args) {        int[][] graph = {                { 0, 14, -1, -1, -1, 15 },                { 14, 0, 10, -1, -1, -1 },                { -1, 10, 0, 15, -1, -1 },                { -1, -1, 15, 0, 20, -1 },                { -1, -1, -1, 20, 0, 25 },                { -1, -1, -1, -1, 25, 0 }        };        List<Long> distance = dijkstra(graph, 0); // 从节点 0 开始求解最短路径        for (int i = 0; i < graph.length; i++) {            System.out.println("从节点 0 到节点" + i + "的最短路径为:" + distance.get(i));        }    }    static class Node implements Comparable<Node> {        int v; // v 表示节点的编号        long dist; // dist 表示距离(长整数类型)        Node(int v, long dist) {            this.v = v;            this.dist = dist;        }        @Override        public int compareTo(Node node) {            return Long.compare(this.dist, node.dist); // 按照距离从小到大排序(长整数类型) } }};        }    }}

以上代码实现了 Dijkstra 算法,并在 main 方法中给出了一个测试用例。其中,graph 表示带权无向图,start 表示起点节点的编号。运行结果会输出从节点0到每个节点的最短路径。

Floyd算法

Floyd算法是一种动态规划算法,可以求解所有节点对之间的最短路径。

Floyd算法的基本思想是将每对节点之间的最短路径初始化为无穷大,然后通过动态规划逐步更新所有节点对之间的最短路径,直到最终得到最短路径。Floyd算法的时间复杂度为O(V^3),其中V是节点数。

Java代码实例

以下是一个简单的Floyd算法的Java实现:

public class FloydAlgorithm {      private static final int INF = 99999; // 无穷大值        public static void floyd(int[][] distance) {          int n = distance.length;          int[][] dp = new int[n][n]; // 创建一个二维数组dp          for (int i = 0; i < n; i++) {              for (int j = 0; j < n; j++) {                  dp[i][j] = distance[i][j]; // 将初始距离值复制到dp数组              }          }          for (int k = 0; k < n; k++) {              for (int i = 0; i < n; i++) {                  for (int j = 0; j < n; j++) {                      if (distance[i][k] != INF && distance[k][j] != INF && distance[i][k] + distance[k][j] < dp[i][j]) {                          dp[i][j] = distance[i][k] + distance[k][j]; // 更新dp数组                      }                  }              }          }          // 输出最短路径结果          for (int i = 0; i < distance.length; i++) {              for (int j = 0; j < distance[i].length; j++) {                  System.out.print(dp[i][j] + " ");              }              System.out.println();          }      }        public static void main(String[] args) {          int[][] distance = {              {0, 1, INF, 14},              {INF, 0, 10, INF},              {INF, INF, 0, 15},              {INF, INF, INF, 0}          };          floyd(distance);      }  }

在这个示例中,我们定义了一个名为FloydAlgorithm的类。在floyd方法中,我们首先将距离矩阵distance作为参数传入。然后,我们使用一个名为dp的二维数组来存储每个节点对之间的最短路径。我们使用一个三重循环来更新dp数组,具体来说,我们使用k作为中间节点,如果从i到j经过k的路径比当前i到j的最短路径更短,我们就更新dp[i][j]的值。最后,我们在main方法中测试了一个简单的图,并输出了所有节点对之间的最短路径。

标签: #最短时间算法 #求最优路径的算法有哪些 #动态规划算法的基本思想和求解步骤 #dijkstra最短路径算法列表 #无向图建立邻接表的空间复杂度