Flyod和Warshall

Floyd算法用于求解任意两点间的最短距离,准许两点间有负的权值,但是一般不准许出现负的环路,其算法复杂度为O(n3),相对于Dijkstra算法,其计算更为简单,但我自己重新复习的时候,觉得原理越简单,其实理解起来越难,也许你会明白程序怎么写,但为什么这样有时候总容易忘记。

今天闲来无事,复习一下Floyd算法和Warshall算法,将自己写的一个垃圾代码放上去,供自己以后看看,代码质量肯定不高,所以诸位别太。。。。看懂原理就可以。

Warshall算法用来求传递闭包,也是路径存在否,算法处理逻辑和Flyod差不多。

代码如下:

 

ExpandedBlockStart.gif 代码
import  java.io.BufferedReader;
import  java.io.DataInputStream;
import  java.io.IOException;
import  java.io.InputStream;
import  java.io.InputStreamReader;
public   class  Warshall {

    
/**
     * 默认尺寸
     
*/
    
private   static   int  DEFAULTSIZE  =   7 ;
    
/**
     * 距离数组
     
*/
    
private   int [][] distances;

    
/**
     * 默认构造函数
     * 
     * 
@throws  IOException
     
*/
    
public  Warshall()  throws  IOException {

        distances 
=   new   int [DEFAULTSIZE][DEFAULTSIZE];
        
for  ( int  i  =   1 ; i  <  DEFAULTSIZE; i ++ ) {
            
for  ( int  j  =   1 ; j  <  DEFAULTSIZE; j ++ ) {
                distances[i][j] 
=   0 ;
            }
        }
        InputStream stream 
=  Floyd. class
                .getResourceAsStream(
" /distance2.properties " );
        DataInputStream in 
=   new  DataInputStream(stream);
        BufferedReader d 
=   new  BufferedReader( new  InputStreamReader(in));
        String temp 
=   null ;
        
while  ((temp  =  d.readLine())  !=   null ) {
            String[] a 
=  temp.split( "   " );
            distances[Integer.parseInt(a[
0 ])][Integer.parseInt(a[ 1 ])]  =  Integer
                    .parseInt(a[
2 ]);
        }
    }

    
/**
     * 计算
     
*/
    
public   void  calculateDistance() {
        
for  ( int  k  =   1 ; k  <   7 ; k ++ ) {
            
for  ( int  i  =   1 ; i  <   7 ; i ++ ) {
                
for  ( int  j  =   1 ; j  <   7 ; j ++ ) {
                    distances[i][j] 
=  distances[i][j]
                            
|  (distances[i][k]  &  distances[k][j]);
                }
            }
        }
    }

    
public   void  display() {
        
for  ( int  i  =   1 ; i  <   7 ; i ++ ) {
            
for  ( int  j  =   1 ; j  <   7 ; j ++ ) {
                
if  (distances[i][j]  !=   0 ) {
                    System.out.println(i 
+   "  -->  "   +  j  +   "  has road " );
                }
            }
        }
    }

    
/**
     * 运行函数
     * 
     * 
@param  args
     * 
@throws  IOException
     
*/
    
public   static   void  main(String[] args)  throws  IOException {
        Warshall warshall 
=   new  Warshall();
        warshall.calculateDistance();
        warshall.display();
    }

}

 

 

ExpandedBlockStart.gif 代码

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class Floyd {

 /**
  * 最长路径,修订
  */
 private static int LONGESTPATH = 10000;
 /**
  * 默认尺寸
  */
 private static int DEFAULTSIZE = 7;
 /**
  * 距离数组
  */
 private int[][] distances;
 /**
  * 轨迹数组
  */
 private int[][] path;

 /**
  * 默认构造函数
  *
  * @throws IOException
  */
 public Floyd() throws IOException {

  distances = new int[DEFAULTSIZE][DEFAULTSIZE];
  path = new int[DEFAULTSIZE][DEFAULTSIZE];
  for (int i = 1; i < DEFAULTSIZE; i++) {
   for (int j = 1; j < DEFAULTSIZE; j++) {
    distances[i][j] = LONGESTPATH;
   }
  }
  // 从文件中读取图中各个节点的距离,如无连线,默认为LONGESTPATH,更为稳妥的办法是得到所有边的最大值,令a>=max(边长)
  InputStream stream = Floyd.class
    .getResourceAsStream("/distance.properties");
  DataInputStream in = new DataInputStream(stream);
  BufferedReader d = new BufferedReader(new InputStreamReader(in));
  String temp = null;
  while ((temp = d.readLine()) != null) {
   String[] a = temp.split(" ");
   distances[Integer.parseInt(a[0])][Integer.parseInt(a[1])] = Integer
     .parseInt(a[2]);
   distances[Integer.parseInt(a[1])][Integer.parseInt(a[0])] = Integer
     .parseInt(a[2]);
  }
 }

 /**
  * 计算距离
  */
 public void calculateDistance() {
  for (int k = 1; k < 7; k++) {
   for (int i = 1; i < 7; i++) {
    for (int j = 1; j < 7; j++) {
     // 计算距离最小值
     // 可以进一步优化,判断distances[i][k]或者distances[k][j]是否为LONGESTPATH,如是可以不进入循环,减少循环次数
     if (distances[i][j] > (distances[i][k] + distances[k][j])) {
      distances[i][j] = distances[i][k] + distances[k][j];
      // 记录轨迹
      path[i][j] = k;
     }
    }
   }
  }
  print(distances);
  printPath();
 }

 /**
  * 打印距离
  *
  * @param distance
  *            距离数组
  */
 public void print(int[][] distance) {
  for (int i = 1; i < DEFAULTSIZE; i++) {
   for (int j = i + 1; j < DEFAULTSIZE; j++) {
    System.out.println(i + ", " + j + " : " + distance[i][j]);
   }
  }
 }

 /**
  * 打印轨迹
  */
 public void printPath() {
  for (int i = 1; i < DEFAULTSIZE; i++) {
   for (int j = i + 1; j < DEFAULTSIZE; j++) {
    System.out.print(i);
    printPath0(i, j);
    System.out.print(j);
    System.out.println(" ");
   }
  }
 }

 /**
  * 打印轨迹
  *
  * @param i
  *            始发
  * @param j
  *            终止
  */
 private void printPath0(int i, int j) {
  int k = path[i][j];
  if (k != 0) {
   printPath0(i, k);
   System.out.print(" " + k + " ");
   printPath0(k, j);
  } else {
   System.out.print(" ");
  }
 }

 /**
  * 运行函数
  *
  * @param args
  * @throws IOException
  */
 public static void main(String[] args) throws IOException {
  Floyd floyd = new Floyd();
  floyd.calculateDistance();
 }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值