0097 弗洛伊德算法,马踏棋盘算法

news2024/9/21 14:32:50

 

 

 

 

 

 

 

import java.util.Arrays;

/*
 * 弗洛伊德算法
 * 1.和迪杰斯特拉算法一样,弗洛伊德算法也是一种用于寻找给定的加权图中顶点间最短路径的算法
 * 2.迪杰斯特拉算法用于计算图中某一顶点到其他顶点的最短路径
 *   弗洛伊德算法计算图中各个顶点之间的最短路径
 * 3.迪杰斯特拉算法通过选定的被访问顶点,求出从出发访问顶点到其他顶点的最短路径
 *   弗洛伊德算法中每一个顶点都是出发访问点,求出从每一个顶点到其他顶点的最短路径
 *   
 * 过程
 * 1.设置顶点vi到顶点vk的最短路径已知为Lik,顶点vk到vj的最短路径已知为Lkj,顶点vi到vj的路径为Lij
 *   则vi到vj的最短路径为:min((Lik+Lkj),Lij),vk取值为图中所有顶点,则可获得vi到vj的最短路径
 * 2.vi到vk的最短路径Lik或vk到vj的最短路径Lkj,以同样方式获得
 * 
 * 步骤
 * 1.第一轮循环,把A(下标为0)作为中间顶点,更新距离和前驱关系
 * 2.重复执行....
 * 
 * 应用——最短路径问题
 */
public class Floyd {
    public static void main(String[] args) {
        char[] vertex = {'A','B','C','D','E','F','G'};
        //创建邻接矩阵
        int[][] matrix = new int[vertex.length][vertex.length];
        final int N = 65535;
        matrix[0] = new int[] {0,5,7,N,N,N,2};
        matrix[1] = new int[] {5,0,N,9,N,N,3};
        matrix[2] = new int[] {7,N,0,N,8,N,N};
        matrix[3] = new int[] {N,9,N,0,N,4,N};
        matrix[4] = new int[] {N,N,8,N,0,5,4};
        matrix[5] = new int[] {N,N,N,4,5,0,6};
        matrix[6] = new int[] {2,3,N,N,4,6,0};
        
        //创建Graph对象
        Graph2 graph = new Graph2(vertex.length, matrix, vertex);
        //弗洛伊德
        graph.floyd();
        graph.show();
    }
}

class Graph2{
    private char[] vertex;//存放顶点数组
    private int[][] dis;//保存从各个顶点出发到其他顶点的距离
    private int[][] pre;//保存到达目标顶点的前驱顶点
    
    //构造器
    //length:大小,matrix:邻接矩阵,vertex:顶点数组
    public Graph2(int length,int[][] matrix,char[] vertex) {
        this.vertex = vertex;
        this.dis = matrix;
        this.pre = new int[length][length];
        //对pre数组初始化(存放的是前驱顶点下标)
        for(int i = 0;i < length;i++) {
            Arrays.fill(pre[i],i);
        }
    }
    
    //显示pre数组和dis数组
    public void show() {
        char[] vertex = {'A','B','C','D','E','F','G'};
        for(int k = 0;k < dis.length;k++) {
            //输出pre数组的一行
            for(int i = 0;i < dis.length;i++) {
                System.out.print(vertex[pre[k][i]] + " ");
            }
            System.out.println();
            //输出dis数组的一行
            for(int i = 0;i < dis.length;i++) {
                System.out.print("(" + vertex[k] + "到" + vertex[i] + "的最短路径:" + dis[k][i]+")");
            }
            System.out.println();
            System.out.println();
        }
    }
    
    //弗洛伊德算法
    public void floyd() {
        int len = 0;//保存距离
        //对中间顶点遍历,k为中间顶点下标
        for(int k = 0;k < dis.length;k++) {
            //从i顶点开始出发,经过中间顶点
            for(int i = 0;i < dis.length;i++) {
                //到达j顶点
                for(int j = 0;j < dis.length;j++) {
                    len = dis[i][k] + dis[k][j];//从i顶点出发,经过k中间顶点,到达j顶点的距离
                    if (len < dis[i][j]) {
                        dis[i][j] = len;//更新距离
                        pre[i][j] = pre[k][j];//更新前驱顶点
                    }
                }
            }
        }
    }
}

/*
 * 马踏棋盘算法(骑士周游问题
 * 将马随机放在国际象棋的8*8棋盘的某个方格中,马按规则(走日字)进行移动
 * 要求每个方格只进入一次,走遍棋盘上全部64个方格
 * 
 * 1.马踏棋盘问题实际上是图的深度优先搜索(DFS)的应用
 * 2.如果使用回溯(深度优先搜索)来解决,加入马走了x个点,发现已走到尽头
 *   就只能回退,查看其他路径
 * 
 * 思路
 * 1.创建棋盘chessBoard,二维数组
 * 2.将当前位置设置为已经访问,根据当前位置,计算马还能走哪些位置,
 *   并放入一个集合中(ArrayList),最多有8个位置
 *   每走一步,就step+1
 * 3.遍历ArrayList中存放的所有位置,看看哪个能走通
 *   走通就继续,走不通回溯
 * 4.判断马是否完成了任务,使用step和应该走的步数比较,如没达到,棋盘置0
 * 
 * //不同的走法(策略),得到不同的结果,效率也会有影响
 * 
 * 使用贪心算法进行优化
 * 1.获取当前位置可以走的下一个位置的集合
 *         ArrayList<Point> ps = next(new Point(column, row));
 * 2.对ps中所有point的下一步的所有集合的数目,通过非递减排序
 */

import java.awt.Point;
import java.util.ArrayList;
import java.util.Comparator;

public class HorseChessBoard {
    
    private static int X;//棋盘列数
    private static int Y;//棋盘行数
    //创建一个数组,标记棋盘的各个位置是否被访问过
    private static boolean visited[];
    //使用一个属性,标记棋盘的所有位置是否都被访问
    private static boolean finished;
    
    public static void main(String[] args) {
        X = 8;
        Y = 8;
        int row = 1;//马初始位置的行,从1开始
        int column = 1;//初始位置的列,从1开始
        //创建棋盘
        int[][] chessboard = new int[X][Y];
        visited = new boolean[X * Y];//初始为false
        //测试耗时
        long start = System.currentTimeMillis();
        traversalChessboard(chessboard, row - 1, column - 1, 1);
        long end = System.currentTimeMillis();
        System.out.println("共耗时:" + (end - start) + "ms");
        
        //输出棋盘最后情况
        for(int[] rows : chessboard) {
            for(int step : rows) {
                System.out.print(step + "\t");
            }
            System.out.println();
        }
    }
    
    //马踏棋盘算法
    //chessbo:棋盘,row:当前位置的行(从0开始)column:当前位置的列(从0开始)step:第几步,初始位置为第一步
    public static void traversalChessboard(int[][] chessboard,int row,int column,int step) {
        chessboard[row][column] = step;
        //row=4,X=8,column=4,当前位置为4*8+4=36
        visited[row * X + column] = true;//标记已访问
        //获取当前位置的下一个位置集合
        ArrayList<Point> ps = next(new Point(column, row));
        //对ps排序
        sort(ps);
        //遍历ps
        while(!ps.isEmpty()) {
            Point p = ps.remove(0);//取出下一个可以走的位置
            //判断是否已经访问过
            if (!visited[p.y * X + p.x]) {//说明还没访问过
                traversalChessboard(chessboard, p.y, p.x, step + 1);
            }
        }
        //判断马是否完成了任务,使用step和应该走的步数比较,如没达到,棋盘置0
        //step < X * Y 成立情况有两种
        //1.棋盘到目前位置,仍然没有走完
        //2.棋盘处于一个回溯过程
        
        if (step < X * Y && !finished) {
            chessboard[row][column] = 0;
            visited[row * X + column] = false;
        }else {
            finished = true;
        }
    }
    
    //根据当前位置(Point对象),计算马还能走哪些位置,并放入一个集合中(ArrayList)
    //curPoint:当前位置
    public static ArrayList<Point> next(Point curPoint){
        //创建ArrayList
        ArrayList<Point> ps = new ArrayList<Point>();
        //创建一个Point
        Point p1 = new Point();
        //最多有8个位置
        //判断马儿能不能往左移动两列,往上移动一行
        if ((p1.x = curPoint.x - 2) >= 0 && (p1.y = curPoint.y - 1) >= 0) {
            ps.add(new Point(p1));
        }
        //判断马儿能不能往左移动一列,往上移动两行
        if ((p1.x = curPoint.x - 1) >= 0 && (p1.y = curPoint.y - 2) >= 0) {
            ps.add(new Point(p1));
        }
        //判断马儿能不能往右移动一列,往上移动两行
        if ((p1.x = curPoint.x + 1) < X && (p1.y = curPoint.y - 2) >= 0) {
            ps.add(new Point(p1));
        }
        //判断马儿能不能往右移动两列,往上移动一行
        if ((p1.x = curPoint.x + 2) < X && (p1.y = curPoint.y - 1) >= 0) {
            ps.add(new Point(p1));
        }
        //判断马儿能不能往右移动两列,往下移动一行
        if ((p1.x = curPoint.x + 2) < X && (p1.y = curPoint.y + 1) < Y) {
            ps.add(new Point(p1));
        }
        //判断马儿能不能往右移动一列,往下移动两行
        if ((p1.x = curPoint.x + 1) < X && (p1.y = curPoint.y + 2) < Y) {
            ps.add(new Point(p1));
        }
        //判断马儿能不能往左移动一列,往下移动两行
        if ((p1.x = curPoint.x - 1) >= 0 && (p1.y = curPoint.y + 2) < Y) {
            ps.add(new Point(p1));
        }
        //判断马儿能不能往左移动两列,往下移动一行
        if ((p1.x = curPoint.x - 2) >= 0 && (p1.y = curPoint.y + 1) < Y) {
            ps.add(new Point(p1));
        }
        return ps;
    }
    
    //根据当前这个位置的所有下一步的选择位置进行非递减排序,减少回溯
    public static void sort(ArrayList<Point> ps) {
        ps.sort(new Comparator<Point>() {

            @Override
            public int compare(Point o1, Point o2) {
                //获取到o1的下一步的所有位置个数
                int count1 = next(o1).size();
                int count2 = next(o2).size();
                if (count1 < count2) {
                    return -1;
                }else if (count1 == count2) {
                    return 0;
                }else {
                    return 1;
                }
            }
        });
    }
    
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/13044.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IT就业专业为什么要选择大数据技术应用?

IT就业专业为什么要选择大数据技术应用&#xff1f;目前大数据领域从业人员的薪资高涨幅空间大&#xff0c;大数据人才供不应求。各大数据开发方向&#xff0c;数据挖掘、数据分析和机器学习方向&#xff0c;大数据运维和云计算方向。 一、大数据技术应用发展前景好&#xff1…

物联网协议MQTT

物联网协议MQTT 1.MQTT简介 MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在 TCP/IP协议族上&#xff0c;是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议&#xff0c;为此&#xff0c;它需要一…

必考设计模式

文章目录一、单例模式&#xff08;创建型&#xff09;1、饿汉式2、懒汉式3、双重检验锁&#xff08;DCL&#xff09;4、sync.once实现单例二、工厂模式&#xff08;创建型&#xff09;1、简单工厂模式2、工厂方法模式3、抽象工厂模式&#xff08;暂时不写&#xff09;三、装饰模…

高通SDX12:SFE(shortcut-fe)软加速驱动效果调测

背景 USB转PHY RTL8153不支持高通IPA硬加速,所以采用SFE软加速 调试设备为基于Cat.6通信模组的整机 SFE软加速前:UXM环境实际测速100Mbps,设备内部sirq 87% SFE软加速驱动调测 SFE驱动代码路径:sdx12-ap\shortcut-fe\shortcut-fe SFE驱动编译文件路径:sdx12-ap\poky\m…

阿里云ACP考试内容是什么?考试时间是什么时候?

对于现在的人来说&#xff0c;网络就是帮助自己了解世界的好帮手、就是让自己生活得更方便的好工具&#xff0c;这样一来&#xff0c;市场就需要大量的人才来满足需求&#xff0c;相对应的岗位也逐渐增多。于是就有大批的大学生在填报志愿的时候&#xff0c;选择IT专业&#xf…

使用Docker发布部署C# .NET core WebApi到服务器

1、启用Docker支持 如果我们使用vs2022新建WebApi项目的时候需要勾选 启用Docker &#xff1a; 如果没有勾选或者使用VS019创建的项目&#xff0c;可以在项目右键 添加 docker支持 2、发布运用程序 接下来开始发布程序&#xff0c;右键点击项目 发布 提示在哪里发布内容&am…

什么?console.log打印出的数据不对?

背景 都怪我年轻不懂事&#xff0c;调试代码只会用console.log。那么&#xff0c;就在今天&#xff0c;出事儿了&#xff01; 看图说话。上面的111和222后面跟的数据竟然不一致&#xff1f; 在我的认知中&#xff0c;JSON里面的parse和stringify方法只是类型的转换啊&#xff…

深浅拷贝小整理(对象赋值请注意)

深浅拷贝小整理1. 一些基础知识 js数据类型分为基本数据类型>Number、String、Boolean、Null、Undefined和引用(对象)数据类型>Object包括有Function、Array、Date&#xff1b;基本数据类型存放在栈中&#xff0c;访问是按值访问&#xff1b;引用类型指的是对象&#xf…

痛定思痛!!!结合fidller抓包,简单介绍http请求报文和http响应报文

简单介绍http请求报文和http响应报文前言1. http请求报文的组成1.1 请求行的内容1.2 请求头的组成1.3 请求体2. HTTP响应报文组成前言 各类书上在介绍http请求报文和http响应报文时花的太过于专业&#xff0c;没有结合实际&#xff0c;当时读的时候可能是我太笨了&#xff0c;…

今天给在家介绍一篇健身俱乐部信息管理系统设计与实现

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

安装包UI美化之路-nsNiuniuSkin界面在线设计引擎

一年多前&#xff0c;我们自己开发了一个用于编辑、预览、调试nsNiuniuSkin的UI界面工具&#xff0c;越来越觉得好用&#xff0c;忍不住想要分享出来&#xff01; 今天我把这个工具重新整理了一下&#xff0c;功能又完善了一些&#xff1b;下面就介绍一下这个工具的功能和使用…

深度解析:Web 3.0和元宇宙

导读:元宇宙的终极形态势必是去中心化的,而现在的网络生态并不能完全满足元宇宙去中心化的需求。一些人认为,即将到来的Web 3.0时代和元宇宙需要的网络生态高度重合。Web 3.0或许能够成为人类迈向元宇宙道路上重要的一步。 01 Web的三次技术迭代 Web 3.0通过新技术体现出来,…

蓝桥杯2022年第十三届决赛真题-围栏(求凸多边形的面积)

题目描述 这天&#xff0c;小明在造围栏。 他提前在地上 (二维平面) 打好了 n 个洞&#xff0c;这 n 个洞的位置形成了一个凸多边形。当他准备把固定围栏的木杆插进去的时候&#xff0c;突然发现自己少准备了两根木杆。 如图&#xff0c;他现在只能在这 n 个洞中选出 n − 2 …

【linux】软件管理

linux软件管理 文章目录linux软件管理桥接模式下配置虚拟机连接互联网nmcli相关命令windows和linux之间的FTPlinux中的软件包类型rpm相关命令搭建本地软件仓库测试本地仓库重新挂载仓库到http服务器上设置仓库镜像开机自动挂载dnf相关命令配置EPEL&#xff08;Extra Packages f…

学生个人网页设计作品:旅游网页设计与实现——成都旅游网站4个页HTML+CSS web前端网页设计期末课程大作业 学生DW静态网页设计 学生个人网页设计作品

&#x1f468;‍&#x1f393;静态网站的编写主要是用 HTML DⅣV CSSJS等来完成页面的排版设计&#x1f469;‍&#x1f393;&#xff0c;一般的网页作业需要融入以下知识点&#xff1a;div布局、浮动定位、高级css、表格、表单及验证、js轮播图、音频视频Fash的应用、uli、下拉…

【YSYY】DSPE-PEG-Transferrin;DSPE-PEG-TF转铁蛋白的主动靶向介绍;磷脂-聚乙二醇-转铁蛋白

产品简称&#xff1a;DSPE-PEG-Transferrin&#xff1b;DSPE-PEG-TF 中文名称&#xff1a;磷脂-聚乙二醇转铁蛋白 产品全称&#xff1a; 1,2-dipalmitoyl-sn-glycero-3-phosphoethanolamine-N-(polyethylene glycol)-Transferrin 产品外观&#xff1a;白色固体 结 构 式&a…

Kubernetes NUMA 感知

TopologyManager TopologyManager 在1.18版本中处于 Beta 状态&#xff0c;该功能支持 CPU 和外围设备&#xff08;例如 SR-IOV VF 和 GPU&#xff09;的 NUMA 对齐&#xff0c;使工作负载能够在针对低延迟优化的环境中运行。 在引入 TopologyManager 之前&#xff0c;CPU 和…

2022-11-17 更高效的Cascades优化器 - Columbia Query Optimizer

在较早的文章中介绍了些Volcano/Cascades优化器框架的设计理念和实现思路&#xff0c;基本是基于论文的解读: https://zhuanlan.zhihu.com/p/364619893 https://zhuanlan.zhihu.com/p/365085770 虽然cascades号称目前最为先进的优化器搜索框架&#xff0c;但不得不说这2篇pa…

ZNS SSD是否真的前途一片光明?

引言 在上次存储随笔更新了一篇ZNS相关的文章“炙手可热的ZNS SSD将会为数据中心带来什么&#xff1f;”以后&#xff0c;在存储圈也一度引发关注。某公司相关同学也在朋友圈疯狂转发&#xff0c;让一些朋友误以为是存储随笔专为某公司写的技术推广软文。 借这个机会在这里再次…

【算法100天 | 20】有环/无环链表的相交问题(Java实现)

若两个链表相交&#xff0c;请返回相交的第一个节点。 给定两个有可能有环也有可能无环的单链表&#xff0c;头节点head1和head2。 实现一个函数&#xff0c;如果两个链表相交&#xff0c;请返回相交的第一个节点&#xff08;从这个节点开始&#xff0c;后续结构都一样&#…