最短路径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;
	}
}

  

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。