迪杰斯特拉算法求图的某个顶点到其他顶点的最短路径问题

2023-11-17

在这里插入图片描述
迪杰斯特拉算法:使用图的广度优先遍历算法,比如先从G点出发,找到能与G直接连接的顶点,然后才从与G最近的A出发,找到与A相邻的节点。通过比较G到每个顶点的距离大小,筛选出到每个点的最短路径
代码:

/**
 * 迪杰斯特拉算法球最短路径问题
 */
public class Dijkstra {
    public static void main(String[] args) {
        char[] vertexs = {'A','B','C','D','E','F','G'};
        final int N = 65535;//N表示两点之间不直连
        //邻接矩阵
        int[][] weight = {
                {N,5,7,N,N,N,2},
                {5,N,N,9,N,N,3},
                {7,N,N,N,8,N,N},
                {N,9,N,N,N,4,N},
                {N,N,8,N,N,5,4},
                {N,N,N,4,5,N,6},
                {2,3,N,N,4,6,N},
        };

        Graph graph = new Graph(vertexs, weight);
        graph.print();
        graph.dijkstra(6);
        graph.show();
    }
}

//图
class Graph{
   private char[] vertexs;//顶点数组
   private  int[][] weight;//邻接矩阵
   private VisitedVertex vv;

    public Graph(char[] vertexs, int[][] weight) {
        this.vertexs = vertexs;
        this.weight = weight;
    }

    public void print(){
        for(int[] link:weight){
            System.out.println(Arrays.toString(link));
        }
    }

    /**
     * 迪杰斯特拉算法
     * @param index  初始节点
     */
    public void dijkstra(int index){
        vv = new VisitedVertex(vertexs.length,index);
        update(index);
        for(int j = 1;j<vertexs.length;j++){//初始节点已经处理过了,所以需要处理vetexs.length - 1 次
            index = vv.updateArray();
            update(index);
        }
    }

    //输出结果
    public void show(){
        vv.show();
    }

    //更新index下标顶点到周围顶点的距离和前驱节点
    private void update(int index){
        int len = 0;
        //根据遍历我们邻接矩阵的 weight[index]行
        for(int j = 0;j<weight[index].length;j++){
        //这个距离是:初始顶点到index这个点的距离+index点的相邻节点的距离
        //比如index为A点,就是遍历A点的相邻节点
        //但是G到这个节点的距离就是GA的距离加上A到这个节点的距离
            len = vv.getDis(index)+weight[index][j];
            //如果j没有被访问过,并且len小于出发顶点到j点的距离,就要更新
            if(!vv.visited(j) && len<vv.getDis(j)){
               vv.updatePre(index,j);//更新j的前驱节点为index
               vv.updateDis(j,len);//更新初始节点到j的距离为len
            }
        }
    }

}

class VisitedVertex{
    public int[] already_arr;//记录每个顶点是否访问过
    public int[] per_visited;//每个顶点对应的前驱节点的下标数组
    public int[] dis;//记录出发顶点到其他所有顶点的距离,如G为出发点,则会记录G到其他顶点的距离

    //构造器
    /**
     *
     * @param length 顶点的个数
     * @param index  出发顶点对应的下标
     */
    public VisitedVertex(int length,int index){
        this.already_arr = new int[length];
        this.per_visited = new int[length];
        this.dis = new int[length];
        //将初始节点设置为以访问
        this.already_arr[index] = 1;
        //初始化dis
        Arrays.fill(dis,65535);
        this.dis[index] = 0;//设置出发顶点到其他顶点的距离65535,到自己为0
    }

    //判断传入的节点是否访问过
    public boolean visited(int index){
        return already_arr[index] == 1;
    }

    /**
     * 更新出发顶点到index顶点的距离
     * @param index
     * @param len  距离
     */
    public void updateDis(int index,int len){
        dis[index] = len;
    }

    /**
     * 更新pre顶点的前驱节点为index
     * @param index
     * @param pre
     */
    public void updatePre(int index,int pre){
       per_visited[pre] = index;
    }

    /**
     * 返回出发顶点到index顶点的距离
     * @param index
     */
    public int getDis(int index){
        return dis[index];
    }

    /**
     * 继续选择并返回新的访问节点,例如G结束以后,就是处理A节点,因为A离G最近
     * @return
     */
    public int updateArray(){
        int min = 65536;
        int index = 0;
        for(int i = 0;i<already_arr.length;i++){
            if(already_arr[i] == 0 && dis[i]<min){
                min = dis[i];
                index = i;
            }
        }
        //将index设置为以访问
        already_arr[index] = 1;
        return index;
    }

    //显示最后的结果,即输出三个数组
    public void show(){
        System.out.println("===============================================================");
        for(int i :already_arr){
            System.out.print(i+" ");
        }
        System.out.println();
        System.out.println("===============================================================");

        for(int i:per_visited){
            System.out.print(i+" ");
        }
        System.out.println();
        System.out.println("===============================================================");

        for(int i:dis){
            System.out.print(i+" ");
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

迪杰斯特拉算法求图的某个顶点到其他顶点的最短路径问题 的相关文章

  • umi学习总结

    文章目录 umi介绍 umi是什么 umi的特性 开发环境 Node js 依赖管理工具 目录结构 路由 配置路由 页面跳转 Link组件 路由组件参数 路由动态参数 query信息 样式 使用css样式 dva 为什么需要状态管理 umi

随机推荐

  • Qt弹出窗口

    Qt弹出Widget窗口置顶 1 需求 Widget每次都弹出且为非模态窗口 2 老版代码 if widget NULL widget new QWidget widget gt show 想象 弹出窗口后 如果发生窗口切换 再次点击时 弹
  • Go语言常用的标准库

    文章目录 打印日志 系统调用命令 json的序列化和反序列化 base64 压缩和解压 标准输入 文件操作 目录操作 init函数 包的可见性 数学库 生成随机数 时间函数 打印日志 package main import log os f
  • Java内存回收机制

    C C 等语言中 内存的分配和释放由程序代码来完成 容易出现由于程序员漏写内存释放代码引起的内存泄露 最终导致系统内存耗尽 Java代码运行在JVM中 由JVM来管理 堆Heap 内存的分配和回收 Garbage Collection 把程
  • 接口如何处理重复请求?

    本文主要来源于 处理重复请求的三种方式 服务端如何高效的处理重复请求 对其整理和总结 用于学习记录 重复请求常用的处理方式就是幂等性处理 幂等性可以理解为 无论执行了多少次重复请求 数据只会处理一次 在数据库里也只会有一条数据 和数据库的唯
  • 以太坊智能合约各方法对应的签名编码

    erc20智能合约常见方法对应的签名编码 常见例如交易 transfer address uint256 编码为 web3 sha3 transfer address uint256 substring 0 10 gt 0xa9059cbb
  • Solidity合约中Merkle Root验证的一点实践

    背景 在上一篇文章 Solidity合约中签名验证的一点实践 中提到过 白名单机制一般有两种 除了签名验证的方式外 就是本文讲述的Merkle Root验证的方式 主要做法是在服务端对白名单地址列表整体构建Merkle树 计算出树的root
  • 解决Hbase报错java.lang.IllegalStateException: The procedure WAL relies on the ability to hsync for....

    完整报错为 java lang IllegalStateException The procedure WAL relies on the ability to hsync for proper operation during compo
  • set的使用

    创建集合 set 1 2 3 4 转化为列表list 1 如果我要在许多列表中找出相同的项 那么用集合是最好不过的了 用集合只用一行就可以解决 x y z 交集 2 去重 gt gt gt lst 1 2 3 4 1 gt gt gt pr
  • 毕业那天我们一起失恋

    毕业那天我们一起失恋 原载 婚姻家庭 VOL 1大四快开学了 我提前了几天来学校 俗话说 磨刀不误砍柴功 我提早来学校 把床铺好 把蚊帐挂起来 把厕所弄干净 把寝室打扫一下 寝室里只有我做这种打扫的事情 寝室有三个人 我一个 丸子一个 还有
  • 【翻译】对计算机未来的10个预测或;我们的首席科学家的无稽之谈

    TLDR WASM将无处不在 编译目标 部署目标 物联网 插件生态系统 这已经在发生了 1 5年 Rust将继续流行 根据RedMonk的指数 在未来几年将超过Go 2 4年 将出现一个严重的Kubernetes的对手 如果它使用WASM并
  • 写个爬虫吧

    import requests url https image baidu com search acjson tn resultjson com ipn rj ct 201326592 is 0 2C0 fp detail logid 1
  • 03-MySQL数据类型

    一 数值类型 整数 MySQL 主要提供的整数类型有 TINYINT SMALLINT MEDIUMINT INT BIGINT 浮点数 浮点类型有两种 分别是单精度浮点数 FLOAT 和双精度浮点数 DOUBLE 定点类型 只有一种 就是
  • 记录一次 JS 解密去混淆的经历 -- 如何破解加密的 JS 代码(一)

    写在前头 昨天发了一个 某JS最牛加密脱壳解密破解去混淆工具 有朋友说上代码不如讲一下思路 于是今天准备捋一下这个思路 顺便当整理复习了 需要直接解密代码的请看上一篇文章 这里只有思路与过程 阅读此文默认你有一定的 JavaScript 基
  • vscode工作区同时显示多个文件

    有时候安装的vscode打开一个文件又打开另一个文件只会保存新的文件 旧的文件别替换 这样做项目比较难受 所以用下面方法可以打开多个文件 workbench editor showTabs true
  • 【E2E】Tesseract5+VS2017+win10源码编译攻略

    一 记录我目前在win10 X64和VS2017的环境下成功编译Tesseract5 0的方式 二 记录在VS2017 C 工程中调用Tesseract4 0的方法 三 记录编译和调用Tesseract4 0过程中踩到的坑和相应的解决方案或
  • IMU立大功:有效减小建筑工人高空坠落风险

    尽管建筑行业不断努力改善工作场所安全 但它仍然是全球最危险的行业之一 建筑行业的工作死亡或致命工伤比例为25 在这些致命伤害中 大约36 是由高空坠落造成的 这是建筑行业从业者意外死亡的主要原因之一 其他国家 包括澳大利亚 中国和韩国 也因
  • 使用eclipse创建JAVA项目

    打开eclipse软件 选择好工作区域 就是项目的储存地址 后登陆 File New Project 选择 Java Project 输入项目名称 点击Finish SRC是专门放java源代码的文件夹 就是你在IDE里编写的各个java类
  • C语言上机实验思路分享9

    实验项目名称 实验十 C 文件基本操作 实验目的及要求 1 掌握文件和文件指针的概念以及文件的定义方法 2 了解文件打开和关闭的概念和方法 3 掌握有关文件操作的函数 实验内容 方法和步骤 1 文件 stu info1 txt 包含学生的基
  • 模板型模板参数报错,无法调试通过,---《深入实践c++模板》例子

    include
  • 迪杰斯特拉算法求图的某个顶点到其他顶点的最短路径问题

    迪杰斯特拉算法 使用图的广度优先遍历算法 比如先从G点出发 找到能与G直接连接的顶点 然后才从与G最近的A出发 找到与A相邻的节点 通过比较G到每个顶点的距离大小 筛选出到每个点的最短路径 代码 迪杰斯特拉算法球最短路径问题 public