最短路径BellmanFord , Dijsktra
最短路径算法也是常用的图算法,在网上看到了一份c的代码,写的很清楚,今天有空给写成java的了,就当练手了。另,算法导论362页详细介绍了Bellman-Ford算法,本来打算再写个Dijsktra算法的,可是今天比较赖,就写这一个算法吧。
package path; import java.util.HashSet; public class BellmanFord { private int MAX = Integer.MAX_VALUE; private int N = 1024; //顶点数 , 边数 , 起点 private int nodenum, edgenum, original; //图的边 private Edge [] edge = new Edge[N]; //保存距离 private double [] dis = new double[N]; private int [] pre = new int[N]; /** * @function * @return */ boolean calculate() { for(int i = 1; i <= nodenum; ++i) //初始化 dis[i] = (i == original ? 0 : MAX); for(int i = 1; i <= nodenum - 1; ++i) for(int j = 1; j <= edgenum; ++j) //松弛 if(dis[edge[j].v] > dis[edge[j].u] + edge[j].cost){ dis[edge[j].v] = dis[edge[j].u] + edge[j].cost; pre[edge[j].v] = edge[j].u; } boolean flag = true; //判断是否含有负权回路 for(int i = 1; i <= edgenum; ++i) if(dis[edge[i].v] > dis[edge[i].u] + edge[i].cost){ flag = false; break; } return flag; } void print_path(int root) //打印最短路的路径(反向) { while(root != pre[root]){ //前驱 System.out.print(root + "-->"); root = pre[root]; } if(root == pre[root]) System.out.print(root + "\n"); } public boolean init(Edge [] edges){ try{ nodenum = edgenum = 0; HashSet<Integer> vSet = new HashSet<Integer>(); for(int i = 1 ; i < edges.length ; ++i){ edgenum++; edge[i] = edges[i]; vSet.add(edges[i].u); vSet.add(edges[i].v); } nodenum = vSet.size(); return true; }catch(Exception e){ e.printStackTrace(); return false; } } private void calcShortestPath(int original){ this.original = original; pre[original] = original; if(calculate()) for(int i = 1; i <= nodenum; ++i){ //每个点最短路 System.out.print(dis[i] + "\n"); System.out.print("Path:"); print_path(i); } else System.out.println("have negative circle\n"); } public static void main(String [] args) { BellmanFord bellman = new BellmanFord(); Edge [] edges = new Edge [7]; edges[1] = new Edge(1 , 2 , 2); edges[2] = new Edge(1 , 3 , 5); edges[3] = new Edge(4 , 1 , 10); edges[4] = new Edge(2 , 4 , 4); edges[5] = new Edge(4 , 2 , 4); edges[6] = new Edge(3 , 4 , 2); bellman.init(edges); bellman.calcShortestPath(1); } } class Edge //边 { // u为边的前驱结点,v为后继结点(暂且用前驱、后继来说) int u, v; //边的权重 double cost; public Edge(int u , int v , double cost){ this.u = u; this.v = v; this.cost = cost; } }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。