Dijkstra和Floyd算法


public class Dijkstra {

	/**
	 * 典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径
	 * 该算法要求图中不存在负权边
	 * 把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示)
	 * 第二组为其余未确定最短路径的顶点集合(用U表示)
	 */
	public static int MAXNUM = 6;
	static int M = Integer.MAX_VALUE;
	
	public static int[] dist = new int[MAXNUM + 1]; // 计算v0点到任何一点的距离
	public static int[] prev = new int[MAXNUM + 1]; // 保存到i这一点最近的上一个节点
	public static void main(String[] args) {
		int[][] A = {
				 {0, 7, 9, M, M, 14},
				 {7, 0, 10, 15, M, M},
				 {9, 10, 0, 11, M, 2},
				 {M, 15, 11, 0, 6, M},
				 {M, M, M, 6, 0, 9},
				 {14, M, 2, M, 9, 0}
		 };
		dijkstra(1, A);
		for (int a : dist) {
			System.out.println(a);
		}
		
	}
	public static void dijkstra(int v0, int[][] A) {
		boolean S[] = new boolean[MAXNUM + 1]; // 判断是否已存入该点到S集合中,初始为false
		S[v0] = true; 
		int n = MAXNUM;
   		// 计算v0到其他点的距离,dist1-6:0,7,9,M,M,14.第一次找的的点prev一定是v0
		for (int i = 1; i <= n; i++) { // 1-n
			dist[i] = A[v0 - 1][i - 1];
			if (dist[i] == Integer.MAX_VALUE) {
				prev[i] = -1;
			} else {
				prev[i] = v0;
			}
		}
		// 计算v0的邻接点中距离最短的一个点u
		for (int i = 2; i <= n; i++) {
			int mindist = Integer.MAX_VALUE;
			int u = v0; // 找出当前未使用的点j的dist[j]最小值
			for(int j = 1; j <= n; ++j) {
				if(!S[j] && dist[j] < mindist) {
					u = j;  // u保存当前邻接点中距离最小的点的号码 
					mindist = dist[j];
				}
			}
			S[u] = true;
			// 为每一点j找到最短的路径(初始化均为v0至j),若从u到j比从v0直接到j小,则更新
			for (int j = 1; j <= n; j++) {
				if (!S[j] && A[u - 1][j - 1] < Integer.MAX_VALUE) {
					if (dist[u] + A[u - 1][j - 1] < dist[j]) {
						dist[j] = dist[u] + A[u - 1][j - 1];
						prev[j] = u; // 记录前驱顶点
					}
				}
			}
		}
	}
}


2.项目中的Dijkstra算法

public class Dijkstra {

    private static final Logger LOG = LoggerFactory.getLogger(Dijkstra.class);

    public static void computePaths(Vertex source,Set<Vertex> all_node,long bW) {
        LOG.info("===aoniBod Start computePaths():source={},Set<Vertex>={}",source.name,all_node);
        source.minDistance = 0;
        PriorityQueue<Vertex> vertexQueue = new PriorityQueue<Vertex>();
        vertexQueue.add(source);
        all_node.remove(source);
        while (!all_node.isEmpty()) {
            LOG.info("===aoniBod number of left node ={}",all_node.size());
            Vertex u = vertexQueue.poll();
            LOG.info("===aoniBod Dijkstra Current u={}",u.name);

            //update the shortest distance of all nodes that are adjacent to node u
            for (Edge e : u.adjacencies) {
                LOG.info("****adjacent node name={}",e.target.name);
                for(Vertex node : all_node){
                    if(node.name.equals(e.target.name)){
                        LOG.info("*****Find target.name=node.name={}",node.name);
                        double weight = e.weight;
                        double distanceThroughU = u.minDistance + weight;
                        if (distanceThroughU < node.minDistance) {
                            node.minDistance = distanceThroughU ;
                            node.previous = u;
                        }
                    }
                }
            }
            LOG.info("====Finish Updating the shortest distance====");
            //find the nearest node from source node
            Vertex tmp_node = null;
            double tmp_dist = Double.MAX_VALUE;
            for(Vertex node:all_node){
                if(node.minDistance < tmp_dist) {
                    tmp_dist = node.minDistance;
                    tmp_node = node;
                }
            }
            LOG.info("===the shortest node from source is {}", tmp_node.name);
            //LOG.info("=====The node nearest from source is:{}",tmp_node);
            vertexQueue.add(tmp_node);
            all_node.remove(tmp_node);
        }
        LOG.info("===aoniBod Finish computePaths()====");
    }

    public static List<Vertex> getShortestPathTo(Vertex target) {
        LOG.info("===aoniBod Start getShortestPathTo Vertex={}",target.name);
        List<Vertex> path = new ArrayList<Vertex>();
        List<Long> nameList = new ArrayList<Long>();
        for (Vertex vertex = target; vertex != null; vertex = vertex.previous){
            path.add(vertex);
            nameList.add(vertex.name);
        }
        Collections.reverse(path);
        Collections.reverse(nameList);
        LOG.info("===aoniBod Path Result={}",nameList);
        return path;
    }
}



/*
 * Floyd,图的最短路径(动态规划)
 */
public class Floyd {
	public static int M = Integer.MAX_VALUE;
	/**
	 * 
	 */
	public static void main(String[] args) {
		int[][] dist = {
				{0, 1, 4, M, M, M},
				{1, 0, 2, 7, 5, M},
				{4, 2, 0, M, 1, M},
				{M, 7, M, 0, 3, 2},
				{M, 5, 1, 3, 0, 6},
				{M, M, M, 2, 6, 0}
		};
		int[][] res = floyd(dist, 6);
		for (int[] a : res) {
			for (int b: a) {
				System.out.print(b);
			}
			System.out.println();
		}
		
	}
	  public void printG(int[][] G,int n){  
	        for(int i=0;i<n;i++){  
	            for(int j=0;j<n;j++){  
	                System.out.println(i+"->"+j+"  "+G[i][j]);  
	            }
	        }  
	    }  
	  
	    public static int[][] floyd(int[][] G,int n){  
	        int[][] Dis = new int[n][n];  
	        for(int q = 0; q < n; q++) {  
	            for(int w = 0; w < n; w++) {  
	                Dis[q][w] = G[q][w];  
	            }  
	        }  
	        for(int k = 0; k < n; k++) {  // k步从i到j
	            for(int i = 0; i < n; i++ ) {  
	                for(int j = 0; j < n; j++) {  
	                    if(Dis[i][k] != M && Dis[k][j] != M && Dis[i][j] > Dis[i][k] + Dis[k][j]) { // 考虑M + 任何为负
	                        Dis[i][j]=Dis[i][k]+Dis[k][j];  
	                    }  
	                }  
	            }  
	        }  
	        return Dis;  
	    }  
}



参考链接及相应算法讲解:

http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html

http://blog.csdn.net/limao314/article/details/14451193

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值