Bellman-Ford算法求解单源最短路径Java实现
来源:互联网 发布:淘宝买家信誉快速 编辑:程序博客网 时间:2024/05/16 17:47
Bellman-Ford算法解决的是一般情况下的单源最短路径问题,在这里,边的权重可以是负值。如果存在一个从源结点可以到达的权重为负值的环路,则算法将还会告诉我们 不存在解决方案,否则算法将给出最短路径和它们的权重。该算法用到了松弛(relaxation)技术。对于每一个结点v来说,我们维持两个属性,一个是v.d,用来记录从源结点s到结点v的最短路径权重的上界,我们称v.d为s到v的最短路径估计。另一个是v.π,用来记录当前从源结点s到结点v的最短路径中v的前驱结点。对于所有的结点将这两个属性进行初始化,v.d设置为无穷大,v.π设置为不存在(NIL),将源结点的s.d设置为0 。
则对一条边(u,v)的松弛过程为:首先测试一下是否可以对从s到v的 最短路径进行改善。测试的方法是,将从结点s到u之间的最短路径距离加上u与v之间的边的权重,并与当前的s到v的最短路径估计进行比较,如果前者更小,则对v.d和v.π进行更新。松弛可能降低最短路径的估计值v.d并更新v的前驱属性v.π 。
而Bellman-Ford算法就是对每一条边进行|V|-1次的松弛操作。其伪代码如下
下图 是一个Belllman-Ford算法求解单源最短路径的一个例子。
以下是Java代码的 实现
package test6;/** * 边 * @author sdu20 * */public class Edge {private int v1;private int v2;private int weight;public Edge(int v1,int v2,int weight){this.v1 = v1;this.v2 = v2;this.weight = weight;}public boolean equals(Edge edge){return this.v1==edge.getV1() && this.v2==edge.getV2() &&this.weight == edge.getWeight();}public int getV1(){return v1;}public int getV2(){return v2;}public int getWeight(){return weight;}public String toString(){String str = "[ "+v1+" , "+v2+" , "+weight+" ]";return str;}}
package test6;import java.util.*;/** * 图类 * @author sdu20 * */public class Graph {private LinkedList<Edge>[] edgeLinks;private int vNum;//顶点数private int edgeNum;//边数private int[] distance;//存放v.dprivate int[] prenode;//存放前驱节点public static final int INF = 10000;//无穷大public static final int NIL = -1;//表示不存在public Graph(int vnum){this.vNum = vnum;edgeLinks = new LinkedList[vnum];edgeNum = 0;distance = new int[vnum];prenode = new int[vnum];for(int i = 0;i<vnum;i++)edgeLinks[i] = new LinkedList<>();}public void insertEdge(Edge edge){int v1 = edge.getV1();edgeLinks[v1].add(edge);edgeNum++;}public void bianli(){System.out.println("共有 "+vNum+" 个顶点, "+edgeNum+" 条边");for(int i = 0;i<vNum;i++){LinkedList<Edge> list = (LinkedList<Edge>) edgeLinks[i].clone();while(!list.isEmpty()){Edge edge = list.pop();System.out.println(edge.toString());}}}/** * 对最短路径估计和前驱节点进行初始化 * @param start */public void INITIALIZE_SINGLE_SOURCE(int start){for(int i = 0;i<vNum;i++){distance[i] = INF;prenode[i] = NIL;}distance[start] = 0;}/** * 松弛 * @param edge */public void RELAX(Edge edge){int v1 = edge.getV1();int v2 = edge.getV2();int w = edge.getWeight();if(distance[v2]>distance[v1]+w){distance[v2] = distance[v1]+w;prenode[v2] = v1;}}/** * Bellman-Ford算法实现 * @return 是否没有负环 */public boolean BELLMAN_FORD(int start){INITIALIZE_SINGLE_SOURCE(start);for(int i = 0;i<vNum-1;i++){for(int j = 0;j<vNum;j++){LinkedList<Edge> list = (LinkedList<Edge>) edgeLinks[j].clone();while(!list.isEmpty()){Edge edge = list.pop();RELAX(edge);}}}for(int i = 0;i<vNum;i++){LinkedList<Edge> list = (LinkedList<Edge>) edgeLinks[i].clone();while(!list.isEmpty()){Edge edge = list.pop();int v1 = edge.getV1();int v2 = edge.getV2();int w = edge.getWeight();if(distance[v2]>distance[v1]+w)return false;}}return true;}/** * 显示结果 */public void showResult(){Stack<Integer>[] routes = new Stack[vNum];for(int i = 0;i<vNum;i++){routes[i] = new Stack<>();int j = i;while(j != NIL){routes[i].push(j);j = prenode[j];}System.out.print(i+"("+distance[i]+") : ");while(!routes[i].isEmpty()){int k = routes[i].pop();System.out.print("-->"+k);}System.out.println();}}public int[] getDistance(){return distance;}public int[] getPrenode(){return prenode;}}
package test6;public class Main {public static void main(String[] args) {// TODO Auto-generated method stubint vnum = 5;Graph graph = new Graph(vnum);Edge[] edges = new Edge[10];edges[0] = new Edge(0,1,6);edges[1] = new Edge(0,3,7);edges[2] = new Edge(1,2,5);edges[3] = new Edge(1,3,8);edges[4] = new Edge(1,4,-4);edges[5] = new Edge(2,1,-2);edges[6] = new Edge(3,2,-3);edges[7] = new Edge(3,4,9);edges[8] = new Edge(4,0,2);edges[9] = new Edge(4,2,7);for(int i = 0;i<10;i++){graph.insertEdge(edges[i]);}graph.bianli();boolean success = graph.BELLMAN_FORD(0);if(success){System.out.println("没有负环");graph.showResult();}else{System.out.println("存在负环");}}}
运行截图如下所示
阅读全文
0 0
- Bellman-Ford算法求解单源最短路径Java实现
- Bellman-Ford 算法实现单源最短路径
- 单源最短路径Bellman-Ford算法
- 单源最短路径 : Bellman-Ford 算法
- 单源最短路径-Bellman-Ford算法
- 单源最短路径--Bellman-Ford算法
- 单源最短路径-Bellman-Ford算法
- 单源最短路径-Bellman-ford算法
- Bellman-Ford 单源最短路径算法
- 单源最短路径算法之Bellman-Ford算法
- Bellman-Ford算法—求解带负权边的最短路径
- Bellman-Ford算法 单源最短路径(o(nm))
- 算法导论 ch24 单源最短路径 Bellman-Ford
- Bellman-Ford算法:计算单源最短路径
- Bellman-Ford 算法 单源最短路径问题
- 图的单源最短路径Bellman-Ford算法
- 单源最短路径的Bellman-Ford算法。
- 单源最短路径——Bellman--Ford算法
- 归并排序
- Handler机制
- 机器学习实战-预测数值型数据:回归
- php基础学习
- 新建maven工程时报错:Could not resolve archetype org.apache.maven.archetypes .
- Bellman-Ford算法求解单源最短路径Java实现
- Spring五个事务隔离级别和七个事务传播行为
- Python-类与对象-子类扩展父类属性
- LeetCode OJ 57 Insert Interval [hard]
- API-集合框架(1)-介绍
- 实现安卓计时器
- C++中this指针详解
- android Studio 导入 早期项目 遇到refreshing gradle project
- 使用m2eclipse为eclipse集成Maven