顶点对之间的最短路径---Floyd

单源最短路径引出相关问题顶点对之间的最短路径问题,对于有向图G<V,E>的任意一组顶点对 v1,v2找出v1到v2的最短距离和v2到v1的最短路径。其中一种方案是对每一个顶点调用一次Dijkstra算法,时间复杂度为O(n^3),另外一种就是Floyd算法

     Floyd是一种动态规划思想,距离Ak[i][j]表示第k次计算是点 i 到点 j的最短距离,那么A0[i][j]就是初始时 i->j的距离, An[i][j]就是最短路径。即:

A0[i][j]=cost[i][j] //邻接矩阵

Ak[i][j]=min{ Ak-1[i][k]+Ak-1[k][j] , Ak-1[i][j] },即在第k步引入中间节点k是否能够缩短i->j之间距离

/**   
* @Title: Floyd.java  
* @Package floy  
* @Description: 顶点对之间的距离
* @author LingLee 
* @date 2017年3月20日 上午11:25:00  
* @version V1.0   
*/   
package floy;

import java.util.ArrayList;
import java.util.List;

/**   
 * @Title: Floyd   
 * @Description: 
 */
public class Floyd {
	private static int INF=Integer.MAX_VALUE;
	private int[][] dist;//i->j的最小路径
	private int[][] path;//i->j最短路径中,j的前驱节点
	private List<Integer> result;
	/**
	 * 
	 */
	public Floyd(int n) {
		// TODO Auto-generated constructor stub
		dist=new int[n][n];
		path=new int[n][n];
		result=new ArrayList();
	}
	public void floydMethod(int[][] matrix){
		for(int i=0;i<matrix.length;i++){//初始化
			for(int j=0;j<matrix[0].length;j++){
				dist[i][j]=matrix[i][j];
				path[i][j]=-1;
			}
		}
		for(int k=0;k<matrix.length;k++){//引入中间节点k,有向图i->j和j->i不同,所以ikj均0->n
			for(int i=0;i<matrix.length;i++){
				for(int j=0;j<matrix.length;j++){
					if(dist[i][k]!=INF&&dist[k][j]!=INF
							&&dist[i][k]+dist[k][j]<dist[i][j]){
						dist[i][j]=dist[i][k]+dist[k][j];
						path[i][j]=k;
					}
				}
			}
		}
	}
	
	public void findPath(int i,int j){
		int k=path[i][j];
		if(k==-1) return;
		result.add(k);
		findPath(i,k);
		findPath(k, j);
	}
	
	public void findCheapestPath(int begin,int end,int[][] matrix){
		floydMethod(matrix);
		result.add(begin);
		findPath(begin, end);
		result.add(end);
	}
	
	public static void main(String[] args){
		Floyd f=new Floyd(4);
		int[][] m={
				{0,1,4,INF},
				{INF,0,INF,9},
				{INF,2,0,8},
				{3,5,6,0}};
		
				f.findCheapestPath(0, 2, m);
				List<Integer> result=f.result;
				System.out.println("0->2"+" 最短路径为:"+result.toString());
				System.out.println(f.dist[0][2]);
		
		
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值