最短路径(图中两点间最短路径)

求解城市之间的最短距离是一个非常实际的问题,其大意如下:

某地区由n个城市,如何选择路线使某个城市到某个指定城市的的距离最短?

注意:这里需要求解的最短路径指的是两个城市之间的最短距离,而不是所有城市之间最短总距离。

1.最短路径算法

    //最短路径算法
    static void distMin(GraphMatrix GM,int vend){    //vend为结束点
        int[] weight=new int[GraphMatrix.MaxNum];        //某终止点到各顶点的最短路径长度
        int i,j,k,min;
        vend--;
        for(i=0;i<GM.VertexNum;i++){        //初始化weight数组
            weight[i]=GM.EdgeWeight[vend][i];
        }
        for(i=0;i<GM.VertexNum;i++){        //初始化path数组
            if(weight[i]<MaxValue&&weight[i]>0){    //有效权值
                path[i]=vend;
            }
        }
        for(i=0;i<GM.VertexNum;i++){        //初始化tmpvertex数组
            tmpvertex[i]=0;            //初始化顶点集合为空
        }
        tmpvertex[vend]=1;        //选入顶点vend
        weight[vend]=0;
        for(i=0;i<GM.VertexNum;i++){        //查找未用顶点的最小权值
            min=MaxValue;
            k=vend;
            for(j=0;j<GM.VertexNum;j++){
                if(tmpvertex[j]==0&&weight[j]<min){
                    min=weight[j];
                    k=j;
                }
            }
            tmpvertex[k]=1;            //将顶点k选入
            for(j=0;j<GM.VertexNum;j++){        //以顶点k为中间点,重新计算权值
                if(tmpvertex[j]==0&&weight[k]+GM.EdgeWeight[k][j]<weight[j]){
                    weight[j]=weight[k]+GM.EdgeWeight[k][j];
                    path[j]=k;
                }
            }
        }
    }

2.完整的程序代码示例

package com.cn.datastruct;

import java.util.Scanner;

//最短路径求解
public class DistMin {
    static class GraphMatrix{
        static final int MaxNum=20;
        char[] Vertex=new char[MaxNum];  //保存顶点信息(序号或字母)
        int GType;    //图的类型(0:无向图,1:有向图)
        int VertexNum;        //顶点的数量
        int EdgeNum;        //边的数量
        int[][] EdgeWeight=new int[MaxNum][MaxNum];        //保存边的权
        int[] isTrav=new int[MaxNum];        //遍历标志
    }

    static final int MaxValue=65535;    //最大值(可设为一个最大整数)
    static int[] path=new int[GraphMatrix.MaxNum];    //两点经过的顶点集合的数组
    static int[] tmpvertex=new int[GraphMatrix.MaxNum];  //最短路径的起始点集合
    static Scanner input=new Scanner(System.in);

    //创建邻接矩阵图
    static void CreateGraph(GraphMatrix GM){
        int i,j,k;
        int weight;     //权
        char EstartV,EendV;        //边的起始顶点
        System.out.printf("输入图中各顶点信息\n");
        for(i=0;i<GM.VertexNum;i++){        //输入顶点
            System.out.printf("第%d个顶点:", i+1);
            GM.Vertex[i]=(input.next().toCharArray())[0];  //保存到各顶点的数组元素中
        }
        System.out.printf("输入构成各边的顶点及权值:\n");
        for(k=0;k<GM.EdgeNum;k++){            //输入边的信息
            System.out.printf("第%d条边:", k+1);
            EstartV=input.next().charAt(0);
            EendV=input.next().charAt(0);
            weight=input.nextInt();
            for(i=0;EstartV!=GM.Vertex[i];i++);      //在已有顶点中查找始点
            for(j=0;EendV!=GM.Vertex[j];j++);        //在已有的顶点中查找终点
            GM.EdgeWeight[i][j]=weight;          //对应位置保存权值,表示有一条边
            if(GM.GType==0){        //若是无向图
                GM.EdgeWeight[j][i]=weight;        //在对角位置保存权值
            }
        }
    }

    // 清空矩阵
    static void ClearGraph(GraphMatrix GM) {
        int i, j;
        for (i = 0; i < GM.VertexNum; i++) {
            for (j = 0; j < GM.VertexNum; j++) {
                GM.EdgeWeight[i][j] = MaxValue; // 设置矩阵中各元素的值为MaxValue
            }
        }
    }

    // 输出邻接矩阵
    static void OutGraph(GraphMatrix GM) {
        int i, j;
        for (j = 0; j < GM.VertexNum; j++) {
            System.out.printf("\t%c", GM.Vertex[j]); // 在第一行输出顶点信息
        }
        System.out.println();
        for (i = 0; i < GM.VertexNum; i++) {
            System.out.printf("%c", GM.Vertex[i]);
            for (j = 0; j < GM.VertexNum; j++) {
                if (GM.EdgeWeight[i][j] == MaxValue) { // 若权值为最大值
                    System.out.printf("\tZ"); // 以Z表示无穷大
                } else {
                    System.out.printf("\t%d", GM.EdgeWeight[i][j]); // 输出边的权值
                }
            }
            System.out.println();
        }
    }

    //最短路径算法
    static void distMin(GraphMatrix GM,int vend){    //vend为结束点
        int[] weight=new int[GraphMatrix.MaxNum];        //某终止点到各顶点的最短路径长度
        int i,j,k,min;
        vend--;
        for(i=0;i<GM.VertexNum;i++){        //初始化weight数组
            weight[i]=GM.EdgeWeight[vend][i];
        }
        for(i=0;i<GM.VertexNum;i++){        //初始化path数组
            if(weight[i]<MaxValue&&weight[i]>0){    //有效权值
                path[i]=vend;
            }
        }
        for(i=0;i<GM.VertexNum;i++){        //初始化tmpvertex数组
            tmpvertex[i]=0;            //初始化顶点集合为空
        }
        tmpvertex[vend]=1;        //选入顶点vend
        weight[vend]=0;
        for(i=0;i<GM.VertexNum;i++){        //查找未用顶点的最小权值
            min=MaxValue;
            k=vend;
            for(j=0;j<GM.VertexNum;j++){
                if(tmpvertex[j]==0&&weight[j]<min){
                    min=weight[j];
                    k=j;
                }
            }
            tmpvertex[k]=1;            //将顶点k选入
            for(j=0;j<GM.VertexNum;j++){        //以顶点k为中间点,重新计算权值
                if(tmpvertex[j]==0&&weight[k]+GM.EdgeWeight[k][j]<weight[j]){
                    weight[j]=weight[k]+GM.EdgeWeight[k][j];
                    path[j]=k;
                }
            }
        }
    }

    public static void main(String[] args) {
        GraphMatrix GM=new GraphMatrix();   //定义保存邻接表结构的图
        String go;
        int vend;
        int i,k;
        System.out.println("求解最短路径问题!");
        do{
            System.out.print("请先输入生成图的类型:");
            GM.GType=input.nextInt();   //图的种类
            System.out.print("请输入图的顶点数量:");
            GM.VertexNum=input.nextInt();         //输入图中顶点数
            System.out.print("请输入图的边的数量:");
            GM.EdgeNum=input.nextInt();        //输入图中边数
            ClearGraph(GM);            //清空图
            CreateGraph(GM);        //生成邻接表结构的图

            System.out.print("\n请输入结束点:");
            vend=input.nextInt();

            distMin(GM,vend);
            vend--;
            System.out.printf("\n个顶点到达顶点%c的最短路径分别为(起始点-结束点):\n",GM.Vertex[vend]);
            for(i=0;i<GM.VertexNum;i++){        //输出结果
                if(tmpvertex[i]==1){
                    k=i;
                    while(k!=vend){
                        System.out.printf("顶点%c-", GM.Vertex[k]);
                        k=path[k];
                    }
                    System.out.printf("顶点%c\n", GM.Vertex[k]);
                }else{
                    System.out.printf("%c-%c:无路径\n", GM.Vertex[i],GM.Vertex[vend]);
                }
            }
            System.out.println("\n继续玩吗(y/n)?");
            go=input.next();
        }while(go.equalsIgnoreCase("y"));
        System.out.println("游戏结束!");
    }

}

程序运行结果如下:

求解最短路径问题!
请先输入生成图的类型:0
请输入图的顶点数量:5
请输入图的边的数量:6
输入图中各顶点信息
第1个顶点:1
第2个顶点:2
第3个顶点:3
第4个顶点:4
第5个顶点:5
输入构成各边的顶点及权值:
第1条边:1 2 2
第2条边:1 3 5
第3条边:1 5 3
第4条边:2 4 4
第5条边:3 5 5
第6条边:4 5 2

请输入结束点:1

个顶点到达顶点1的最短路径分别为(起始点-结束点):
顶点1
顶点2-顶点1
顶点3-顶点1
顶点4-顶点5-顶点1
顶点5-顶点1

继续玩吗(y/n)?
n
游戏结束!
时间: 2024-10-05 00:01:49

最短路径(图中两点间最短路径)的相关文章

Dijkstra 算法,用于对有权图进行搜索,找出图中两点的最短距离

Dijkstra 算法,用于对有权图进行搜索,找出图中两点的最短距离,既不是DFS搜索,也不是BFS搜索. 把Dijkstra 算法应用于无权图,或者所有边的权都相等的图,Dijkstra 算法等同于BFS搜索. http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html 2.算法描述 1)算法思想:设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源

【最短路】求两点间最短路径的改进的Dijkstra算法及其matlab实现

代码来源:<图论算法及其matlab实现>(北京航空航天出版社) P18 书中提出了基于经典Dijkstra算法改进的两种算法. 其中算法Ⅱ的效率较高. 代码如下: 1 function a=Dijk(a) 2 %a(输入量)表示图的邻接矩阵 3 %a(输出量)表示所求最短路径的距离矩阵 4 5 %建立邻接矩阵,若不还是对称矩阵,则变为对称矩阵 6 n=length(a); 7 for i=2:n 8 for j=1:(i-1) 9 a(i,j)=a(j,i); 10 end 11 end 1

最短路径之所有顶点间最短路径(图片格式)

两点之间最短路径:弗洛伊德算法

弗洛伊德算法是计算无向有权图中两点间最短路径的算法,复杂度为O(n^3).其思路是将两点间距离分为过(指定的)第三点或是不过,然后取它们的最小值,如此循环就可以得到两点之间真正的最小值. void floyd() { for (int k = 0; k < n; ++k) { for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { //在当前i到j经过k点的路径与直连的路径中选最短 matrix[i][j] = min(ma

在图中寻找最短路径-----深度优先算法C++实现

求从图中的任意一点(起点)到另一点(终点)的最短路径,最短距离: 图中有数字的点表示为图中的不同海拔的高地,不能通过:没有数字的点表示海拔为0,为平地可以通过: 这个是典型的求图中两点的最短路径:本例,用深度优先算法来实现: 在每一个点都有四个方向(有的点的有些方向不能通过),所以在每一个点处要处理四种方向的情况: 深度优先算法函数怎么写? 也就是写递归函数...但是递归函数肿么写??? 第一:判断初始态,从起点出发,刚开始步数为0:dfs(start_x, start_y, 0); 第二:从起

基于pgrouting的任意两点间的最短路径查询函数二

在前面的博文中写过一篇查询任意两点间最短路径的函数,当时对pgrouting不熟悉,功能很low.现在对该函数进行扩展,支持用户自己输入查询的数据库表,这一点看似简单,其实意义很大,在做室内导航的时候当用户所在的楼层变化的时候最短路径函数查询的数据表名称也会发生变化,不可能一栋大楼里的道路都是一样的吧,另外进行跨楼层的最短路径规划时,需要查询从A到楼梯口的最短路径和楼梯口到B的最短路径,这些都需要进行最短路径规划的时候能够自己选择数据表. DROP FUNCTION pgr_fromAtoB(t

图——图的Dijkstra法最短路径实现

1,最短路径的概念: 1,从有向图中某一顶点(起始顶点)到达另一顶点(终止顶点)的路径中,其权值之和最小的路径: 2,问题的提法: 1,给定一个带权有向图 G 与起始顶点 v,求从 v 到 G 中其它顶点的最短路径(每条边上都存在有意义的权值): 2,Dijkstra 算法核心是通过已知最短路径寻找未知最短路径: 3,解决思路: 1,Dijkstra 提出按路径长度的递增次序,逐步产生最短路径: 1,首先求出长度最短的一条最短路径,再参照它求出长度次短的一条最短路径,依次类推,直到从起始顶点 v

最短路径规划中创建基于geoserver的wms服务

上篇文章写了求任意两点间最短路径的sql函数,这篇文章讲一下如何把上面介绍的子功能整合到系统中去. 1.geoserver登录 首先单击geoserver安装路径下的start Geoserver 待geoserver启动后,在浏览器中输入,http://localhost:8080/geoserver/web/ 输入用户名密码登录geoserver 2.创建工作区 单击左侧工作区,如下图所示: 会进入新建工作区页面,单击"添加新的工作区",如下图所示 在弹出的工作区设置中输入新工作区

两点间所有路径的遍历算法

转自:http://blog.sina.com.cn/s/blog_5ff8e88e01013lot.html 这几天,用到了这个功能,但在网上找到了一份资料,思路写的很清晰,但代码有错误.因此,我就按着这个思路,自己整理了代码,现在说明如下:(引用前部分思想,更新后部分代码) 两点间所有路径的遍历算法 中国海洋大学 信息科学与工程学院 熊建设 梁磊 摘要:本文首先简单介绍图的深度优先遍历算法,接着根据图的深度优先遍历算法求出连通图中两点间所有路径,并给出代码. 关键词:图.深度优先遍历.算法