题目:

  最短路:给定两个顶点,在以这两个点为起点和终点的路径中,边的权值和最小的路径。考虑权值为点之间的距离。

  单源最短路问题,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算法相关推荐

  1. Bellman Ford算法详解

    一.用途 1. Bellman Ford算法是解决拥有负权边最短路问题的方法之一.还有一种方法是SPFA算法. 2. 二者相比,SPFA算法在效率方面是优于Bellman Ford算法的.但在某些情况 ...

  2. bellman ford 算法 判断是否存在负环

    Flyer 目录视图 摘要视图 订阅 微信小程序实战项目--点餐系统        程序员11月书讯,评论得书啦        Get IT技能知识库,50个领域一键直达 关闭 bellman for ...

  3. Bellman——Ford算法

    Bellman--Ford 算法介绍 思路讲解 案例分析与代码实现 案例分析 代码实现 优先队列优化(SPFA) 优化原理 代码实现 算法介绍 我们知道Dijkstra算法只能用来解决正权图的单源最短 ...

  4. bellman - ford算法c++

    (最短路III)bellman - ford算法(适用于含负权边的图) 注意:用该算法求最短路,在有边数限制的情况下可以存在负权回路!且对所走的边的数量有要求时只能用该算法实现! 解析:因为如果没有边 ...

  5. Bellman ford算法(贝尔曼·福特算法)

    Bellman - ford算法是求含负权图的单源最短路径的一种算法,效率较低,代码难度较小.其原理为连续进行松弛,在每次松弛时把每条边都更新一下,若在n-1次松弛后还能更新,则说明图中有负环,因此无 ...

  6. LeetCode 787. K 站中转内最便宜的航班(图/Bellman Ford算法)

    文章目录 贝尔曼-福特算法(Bellman-Ford) 简介 算法思想 算法执行过程 应用 题目描述 分析 代码 LeetCode 787. K 站中转内最便宜的航班 题目描述 Bellman For ...

  7. 图解Bellman Ford算法

    Bellman Ford 单源最短路径算法[中字] Bellman Ford 单源最短路径算法[中字]_哔哩哔哩_bilibili 贝尔曼-福特算法(Bellman–Ford algorithm )油 ...

  8. bellman ford 算法

    Dijkstra算法是处理单源最短路径的有效算法,但它局限于边的权值非负的情况,若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的.这时候,就需要使用其他的算法来求解最短 ...

  9. 单源最小路径BellMan Ford算法

    Bellman-Ford 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法. 输入:带权图 输出:从第0个点到其他点的最短路径值 B ...

  10. c语言bellman算法,求 最短路径中BELLMAN FORD算法实现的C程序

    匿名用户 1级 2010-06-01 回答 //这个是邻接表 typedef struct oo { int len,num; struct oo *next; } link; typedef str ...

最新文章

  1. TCP丢包检测技术详解
  2. mysql-sql语句
  3. Percona Server for MySQL 5.5.30-30.2
  4. 数据结构与算法(6) -- heap
  5. Api网关Kong集成Consul做服务发现及在Asp.Net Core中的使用
  6. 如何导入数据模板到MVC
  7. 解读NoSQL最新现状和趋势:云NoSQL数据库将成重要增长引擎
  8. 获取数据库名称dbName
  9. aop源码分析之 —— 创建代理对象
  10. 清空linux+history_1分钟学会的Linux小技巧,大大提高你的工作效率
  11. 【BZOJ1823】 [JSOI2010]满汉全席
  12. 【Windows】合并分区教程(解决C盘空间不足)
  13. pillow图像格式转化和缩放操作
  14. html上自动显示汉字拼音,原来html上用这个标签显示拼音
  15. 日暮途远,故吾倒行而逆施之.
  16. 由于CredSSP加密数据库修正
  17. 【2022年高教杯数学建模】C题:古代玻璃制品的成分分析与鉴别方案及代码实现(一)
  18. /usr/bin/ld: cannot find -lxxx错误的通用解决方法
  19. 网易2018校园招聘编程题真题集合 详解
  20. cad重新加载php命令,cad无限缩小的命令是什么

热门文章

  1. ehlib中dbgrideh的多选框设置
  2. 《x86汇编语言:从实模式到保护模式》视频来了
  3. Tensorflow2.0与Tensorflow1.0的理解
  4. Easyexcel文件下载时,中文名称显示为下划线
  5. 备考信息系统项目管理师-----Day1
  6. Java绘图之设置字型和颜色
  7. GAN for NLP (论文笔记及解读
  8. 干货 | 算法工程师入门第一期——罗恒讲深度学习
  9. 插件框架实现思路及原理
  10. JZOJ 3468. 【NOIP2013模拟联考7】OSU!(osu)