最短路问题之Bellman-ford算法
题目:
最短路:给定两个顶点,在以这两个点为起点和终点的路径中,边的权值和最小的路径。考虑权值为点之间的距离。
单源最短路问题,Bellman-ford算法
思路:每次循环检查所有边,可优化。
应用于旅游等路径最小问题。
代码:
1 import java.util.Arrays; 2 3 public class 图的最短路问题_单源 { 4 public static void main(String[] args) { 5 int[] shortestPath = shortestPath(0); 6 System.out.println(Arrays.toString(shortestPath)); 7 // 输出[0, 2, 5, 7, 11, 8, 16] 8 } 9 10 /** 11 * 求起点到各顶点的最短距离 12 * 13 * @param s 起点 14 * @return 15 */ 16 private static int[] shortestPath(int s) { 17 int n = graph.length; 18 // 记录s到各顶点的最短距离 19 int[] d = new int[n]; 20 for (int i = 0; i < n; i++) { 21 d[i] = Integer.MAX_VALUE; 22 } 23 d[s] = 0;// 到自己的距离为0 24 while (true) { 25 boolean update = false; 26 // 扫描所有的边 27 for (int i = 0; i < n; i++) { 28 // 起点到i的最短距离还没算出来 29 if (d[i] == Integer.MAX_VALUE) 30 continue; 31 for (int j = 0; j < n; j++) { 32 int cost = graph[i][j]; // i,j之间的距离 33 if (cost > 0) { // i,j 两点之间有边,起点是i 34 if (d[j] > d[i] + cost) { // 起点先到i,i->j 35 // 两端距离加起来比起点直接到j的距离短,则更新 36 update = true; 37 d[j] = d[i] + cost; 38 } 39 } 40 } 41 } 42 // 无需任何更新,退出外循环 43 if (!update) 44 break; 45 } 46 return d; 47 } 48 49 static int[][] graph = { 50 { 0, 2, 5, 0, 0, 0, 0 }, 51 { 2, 0, 4, 6, 10, 0, 0 }, 52 { 5, 4, 0, 2, 0, 0, 0 }, 53 { 0, 6, 2, 0, 0, 1, 0 }, 54 { 0, 10, 0, 0, 0, 3, 5 }, 55 { 0, 0, 0, 1, 3, 0, 9 }, 56 { 0, 0, 0, 0, 5, 9, 0 } 57 }; 58 }
对于上一个代码。可以先把边集提取出来,这样不用每次扫描二维数组。
Edge类:
1 /** 2 * 边 的封装 3 * 边集可以用来表示图 4 */ 5 public class Edge<T> implements Comparable<Edge> { 6 private T start; 7 private T end; 8 private int distance; 9 10 public Edge(T start, T end, int distance) { 11 this.start = start; 12 this.end = end; 13 this.distance = distance; 14 } 15 16 public T getStart() { 17 return start; 18 } 19 20 public void setStart(T start) { 21 this.start = start; 22 } 23 24 public T getEnd() { 25 return end; 26 } 27 28 public void setEnd(T end) { 29 this.end = end; 30 } 31 32 public int getDistance() { 33 return distance; 34 } 35 36 public void setDistance(int distance) { 37 this.distance = distance; 38 } 39 40 @Override 41 public String toString() { 42 return start + "->" + end + ":" + distance; 43 } 44 45 @Override 46 public int compareTo(Edge obj) { 47 int targetDis = obj.getDistance(); 48 return distance > targetDis ? 1 : (distance == targetDis ? 0 : -1); 49 } 50 }
View Code
优化过后的代码:
1 import java.util.ArrayList; 2 import java.util.Arrays; 3 import java.util.List; 4 5 public class 图的最短路问题_优化_边集 { 6 public static void main(String[] args) { 7 edges = buildEdges(graph); 8 int[] shortestPath = shortestPath(0); 9 System.out.println(Arrays.toString(shortestPath)); 10 // 输出[0, 2, 5, 7, 11, 8, 16] 11 } 12 13 /** 14 * 求起点到各顶点的最短距离 15 * 16 * @param s 17 * 起点 18 * @return 19 */ 20 private static int[] shortestPath(int s) { 21 int n = graph.length; 22 // 记录s到各顶点的最短距离 23 int[] d = new int[n]; 24 for (int i = 0; i < n; i++) { 25 d[i] = Integer.MAX_VALUE; 26 } 27 d[s] = 0;// 到自己的距离为0 28 while (true) { 29 boolean update = false; 30 31 for (Edge<Integer> e : edges) { 32 if (d[e.getStart()] != Integer.MAX_VALUE && d[e.getEnd()] > d[e.getStart()] + e.getDistance()) { 33 update = true; 34 d[e.getEnd()] = d[e.getStart()] + e.getDistance(); 35 } 36 } 37 38 if (!update) 39 break; 40 } 41 return d; 42 } 43 44 static List<Edge<Integer>> edges; 45 46 static List<Edge<Integer>> buildEdges(int[][] graph) { 47 int n = graph.length; 48 List<Edge<Integer>> edges = new ArrayList<>(); 49 for (int i = 0; i < n; i++) { 50 for (int j = 0; j < n; j++) { 51 int cost = graph[i][j]; // i,j之间的距离 52 if (cost > 0) { // i,j 两点之间有边,起点是i 53 edges.add(new Edge<>(i, j, cost)); 54 } 55 } 56 } 57 return edges; 58 } 59 60 static int[][] graph = { 61 { 0, 2, 5, 0, 0, 0, 0 }, 62 { 2, 0, 4, 6, 10, 0, 0 }, 63 { 5, 4, 0, 2, 0, 0, 0 }, 64 { 0, 6, 2, 0, 0, 1, 0 }, 65 { 0, 10, 0, 0, 0, 3, 5 }, 66 { 0, 0, 0, 1, 3, 0, 9 }, 67 { 0, 0, 0, 0, 5, 9, 0 } 68 }; 69 }
View Code
转载于:https://www.cnblogs.com/xiaoyh/p/10415935.html
最短路问题之Bellman-ford算法相关推荐
- Bellman Ford算法详解
一.用途 1. Bellman Ford算法是解决拥有负权边最短路问题的方法之一.还有一种方法是SPFA算法. 2. 二者相比,SPFA算法在效率方面是优于Bellman Ford算法的.但在某些情况 ...
- bellman ford 算法 判断是否存在负环
Flyer 目录视图 摘要视图 订阅 微信小程序实战项目--点餐系统 程序员11月书讯,评论得书啦 Get IT技能知识库,50个领域一键直达 关闭 bellman for ...
- Bellman——Ford算法
Bellman--Ford 算法介绍 思路讲解 案例分析与代码实现 案例分析 代码实现 优先队列优化(SPFA) 优化原理 代码实现 算法介绍 我们知道Dijkstra算法只能用来解决正权图的单源最短 ...
- bellman - ford算法c++
(最短路III)bellman - ford算法(适用于含负权边的图) 注意:用该算法求最短路,在有边数限制的情况下可以存在负权回路!且对所走的边的数量有要求时只能用该算法实现! 解析:因为如果没有边 ...
- Bellman ford算法(贝尔曼·福特算法)
Bellman - ford算法是求含负权图的单源最短路径的一种算法,效率较低,代码难度较小.其原理为连续进行松弛,在每次松弛时把每条边都更新一下,若在n-1次松弛后还能更新,则说明图中有负环,因此无 ...
- LeetCode 787. K 站中转内最便宜的航班(图/Bellman Ford算法)
文章目录 贝尔曼-福特算法(Bellman-Ford) 简介 算法思想 算法执行过程 应用 题目描述 分析 代码 LeetCode 787. K 站中转内最便宜的航班 题目描述 Bellman For ...
- 图解Bellman Ford算法
Bellman Ford 单源最短路径算法[中字] Bellman Ford 单源最短路径算法[中字]_哔哩哔哩_bilibili 贝尔曼-福特算法(Bellman–Ford algorithm )油 ...
- bellman ford 算法
Dijkstra算法是处理单源最短路径的有效算法,但它局限于边的权值非负的情况,若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的.这时候,就需要使用其他的算法来求解最短 ...
- 单源最小路径BellMan Ford算法
Bellman-Ford 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法. 输入:带权图 输出:从第0个点到其他点的最短路径值 B ...
- c语言bellman算法,求 最短路径中BELLMAN FORD算法实现的C程序
匿名用户 1级 2010-06-01 回答 //这个是邻接表 typedef struct oo { int len,num; struct oo *next; } link; typedef str ...
最新文章
- TCP丢包检测技术详解
- mysql-sql语句
- Percona Server for MySQL 5.5.30-30.2
- 数据结构与算法(6) -- heap
- Api网关Kong集成Consul做服务发现及在Asp.Net Core中的使用
- 如何导入数据模板到MVC
- 解读NoSQL最新现状和趋势:云NoSQL数据库将成重要增长引擎
- 获取数据库名称dbName
- aop源码分析之 —— 创建代理对象
- 清空linux+history_1分钟学会的Linux小技巧,大大提高你的工作效率
- 【BZOJ1823】 [JSOI2010]满汉全席
- 【Windows】合并分区教程(解决C盘空间不足)
- pillow图像格式转化和缩放操作
- html上自动显示汉字拼音,原来html上用这个标签显示拼音
- 日暮途远,故吾倒行而逆施之.
- 由于CredSSP加密数据库修正
- 【2022年高教杯数学建模】C题:古代玻璃制品的成分分析与鉴别方案及代码实现(一)
- /usr/bin/ld: cannot find -lxxx错误的通用解决方法
- 网易2018校园招聘编程题真题集合 详解
- cad重新加载php命令,cad无限缩小的命令是什么