江苏专业做网站的公司品牌营销策略分析
最短路径算法
- 1、Dijkstra算法
- 1.2 使用优先队列 优化 查找每轮中距离起点最近的节点下标`(推荐)`
- 2、BellmanFord算法
- 2.1 邻接表List\<Edge\>实现图的方式(稍微比邻接矩阵快一点)
- 2.2 邻接矩阵实现图的方式(优点像Floyd算法)`不推荐`
- 3、Floyd-Warshall算法
1、Dijkstra算法
原理:
1)每一次循环确定一个距离起点最短的节点的路径长度;
2)确定节点后,以它为中间点去更新与其相连的节点距离起点的路径长度;
准备:
1)路径图,int[][] graph;
2)节点是否使用过,boolean[] used;
3)节点距离起点的最短路径长度,int[] shortLen;
核心:两个判断条件
1)当前循环的最近节点判断:
1、未使用过;2、与起点间存在路径;3、小于其他节点到起点距离;
2)更新当前轮相邻节点距起点的最短路径长度判断:
1、未使用过;2、与index节点相连;3、更新后的距离小于之前达到起点的距离 或 还没有到达起点的路径;
public static void main(String[] args) {//路径图int[][] len = new int[2022][2022];boolean[] used = new boolean[2022]; //起点到达每个节点的最短路径长度int[] shortLen = new int[2022];for(int i=1;i<2022;i++){shortLen[i] = len[1][i];}used[1] = true;//n个节点,要去寻找其他n-1个节点距离起点的最短路径长度,所以要遍历n-1次!!for(int i=2;i<2022;i++){//记录当前轮的最近未使用节点下标int index = 0;//记录当前轮的距离起点的最近未使用节点的路径长度int min = Integer.MAX_VALUE;//遍历最短路径节点,寻找当前轮未使用的最短路径长度及节点下标for(int j=2;j<2022;j++){if(!used[j] && shortLen[j]!=0 && min>shortLen[j]){ //条件:1、未使用过;2、与起点间存在路径;3、小于其他节点到起点距离;min = shortLen[j];index = j;}}//找到最近节点后,将其标识为已使用used[index] = true;//根据标记的最近节点,将其作为中间节点,去重新更新其他与其相连但未使用节点的shortLenfor(int j=2;j<2022;j++){if(!used[j] && len[index][j]!=0 && (len[index][j]+min < shortLen[j] || shortLen[j]==0)){ //条件:1、未使用过;2、与index节点相连;3、更新后的距离小于之前达到起点的距离 或 还没有到达起点的路径;shortLen[j] = len[index][j] + min;}}}System.out.println(shortLen[2021]);}
注意:
如果将不相连的节点路径设置为Integer.MAX_VALUE,则可以优化掉两个核心判断条件中的shortLen[j]!=0 和 shortLen[j]==0条件,
不足:
路径中不能包含负权重!
1.2 使用优先队列 优化 查找每轮中距离起点最近的节点下标(推荐)
public static void dijkstra(int[][] graph, int start) {int n = graph.length; // 节点数量int[] dist = new int[n]; // 存储从起点到各节点的最短距离boolean[] visited = new boolean[n]; // 标记节点是否已被处理// 初始化距离数组Arrays.fill(dist, Integer.MAX_VALUE);dist[start] = 0; // 起点到自身的距离为 0