最短路径算法

求解最小路径是图中很重要的算法,主要有两种迪杰斯特拉算法(Dijkstra)与弗洛伊德算法(Floyd)。

我们用上述两种方法求解以下图的最短路径:
这里写图片描述

  • 迪杰斯特拉算法(Dijkstra):
import java.util.Arrays;

/**
 * 最短路径:迪杰斯特拉算法
 * 假设:起始点为v0
 * @author 13983
 *
 */
public class Main {
    public static int path[]=new int[9];        //记录每一个顶点在最短路径中的前驱顶点是谁
    public static int distance[]=new int [9];   //记录v0到每个顶点的距离
    private static final int infinity=65536;            //设极限值为65536
    public static void main(String[] args) {
        /*
         * 构造邻接矩阵,根据上图构造,无连接则置为65536
         */
        int[][]a={{0,1,5,65536,65536,65536,65536,65536,65536},
                  {1,0,3,7,5,65536,65536,65536,65536},
                  {5,3,0,65536,1,7,65536,65536,65536},
                  {65536,7,65536,0,2,65536,3,65536,65536},
                  {65536,5,1,2,0,3,6,9,65536},
                  {65536,65536,7,65536,3,0,65536,5,65536},
                  {65536,65536,65536,3,6,65536,0,2,7},
                  {65536,65536,65536,65536,9,5,2,0,4},
                  {65536,65536,65536,65536,65536,65536,7,4,0},
                 };
        /*
         * 使用迪杰斯特拉算法
         */
        shortPath_Dijkstra(a);
        System.out.println(Arrays.toString(path));
        /*
         * 假设:终点v8
         */
        int n=8;
        findPath(path,n);
    }



    private static void findPath(int[] path,int n) {
        while(n!=0){                        //如果不是起始点则执行循环
            System.out.print("-->v"+n);
            n=path[n];

        }
        System.out.print("-->v"+0);
    }



    /*
     * 迪杰斯特拉算法实现
     */
    private static void shortPath_Dijkstra(int[][] a) {
        int min,k = 0;
        int finals[]=new int [9];       //记录每个顶点是否找到最短路径的标志
        //初始化数据
        for(int i=0;i<9;i++){
            path[i]=0;                  //初始化path   
            distance[i]=a[0][i];        //初始化举例
            finals[i]=0;                //所有顶点都未找到最短路径
        }
        distance[0]=0;                  //v0到v0的路径为0
        finals[0]=1;                    //v0找到了最短路径
        for(int i=0;i<9;i++){           //主循环   每次求得v0到某个顶点的最短路径
            min=infinity;   

            for(int j=0;j<9;j++){       //寻找离v0最近的点
                if(finals[j]==0&&distance[j]<min){
                    min=distance[j];
                    k=j;
                }

            }

            finals[k]=1;
            for(int w=0;w<9;w++){
                //如果经过k顶点的路径比当前的路径端的话
                if(finals[w]==0&&min+a[k][w]<distance[w]){
                    //说明找到了最短路径
                    distance[w]=min+a[k][w];
                    path[w]=k;
                }
            }

        }

    }

}

结果显示:
这里写图片描述

  • 弗洛伊德(Floyd)算法:
package com.xxt.path;

import java.util.Arrays;

/**
 * 最短路径:弗洛伊德算法
 * 
 * @author 13983
 *
 */
public class Test {

    public static void main(String[] args) {
        /*
         * 构造邻接矩阵
         */
        int[][]a={{0,1,5,65536,65536,65536,65536,65536,65536},
                  {1,0,3,7,5,65536,65536,65536,65536},
                  {5,3,0,65536,1,7,65536,65536,65536},
                  {65536,7,65536,0,2,65536,3,65536,65536},
                  {65536,5,1,2,0,3,6,9,65536},
                  {65536,65536,7,65536,3,0,65536,5,65536},
                  {65536,65536,65536,3,6,65536,0,2,7},
                  {65536,65536,65536,65536,9,5,2,0,4},
                  {65536,65536,65536,65536,65536,65536,7,4,0},
                 };
        /*
         * 前驱矩阵p
         */
        int [][]p=new int[9][9];
        /*
         * 调用Floyd算法
         */
        shortestPath_Floyd(a,p);
        System.out.println(Arrays.deepToString(a));
        /*
         * 根据前驱矩阵,输出最小路径,起始点0,终点8
         */
        shortPath(p,0,8);
    }

    private static void shortPath(int[][] p, int i, int j) {
        System.out.print("v"+i);
        while(p[i][j]!=i){
            System.out.print("-->v"+p[i][j]);
            i=p[i][j];
        }

    }

    private static void shortestPath_Floyd(int[][] a, int[][] p) {
        /*
         * 初始化p
         */
        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){
                p[i][j]=j;
            }
        }
        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){
                for(int w=0;w<9;w++){
                    if(a[j][w]>a[j][i]+a[i][w]){
                        //如果i顶点比员两点间路径更短
                        a[j][w]=a[j][i]+a[i][w];
                        p[j][w]=p[j][i];
                    }
                }
            }
        }
    }

}

结果显示:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值