zoukankan      html  css  js  c++  java
  • 马踏棋盘(骑士周游问题)

    马踏棋盘问题(骑士周游问题)

    • 实际上是图的深度优先搜索(DFS)的应用。
    • 如果使用回溯(就是深度优先搜索)来解决,假如马儿踏了53个点,如图:走到了第53个,坐标(1,0),发现已经走到尽头,没办法,那就只能回退了,查看其他的路径,就在棋盘上不停的回溯…… ,思路分析+代码实现
    • 使用贪心算法(greedyalgorithm)进行优化。解决马踏棋盘问题.

    /**
     * 〈马踏棋盘 算法〉
     *
     * @author LZ
     * @create 2019/9/29
     * @since 1.0.0
     */
    public class HorseChessboard {
        /**
         * 列数
         */
        private int width;
        /**
         * 行数
         */
        private int height;
        /**
         * 访问记录
         */
        private boolean[] visited;
        /**
         * 棋盘
         */
        private int[][] chessboard;
    
        /**
         * 是否完成
         */
        private boolean finished = false;
    
        public static void main(String[] args) {
            HorseChessboard horseChessboard = new HorseChessboard(8, 8);
            long start = System.currentTimeMillis();
            horseChessboard.start(new Point(0, 0), 1);
            long end = System.currentTimeMillis();
            System.out.println(end - start);
            horseChessboard.show();
        }
    
    
        /**
         * 初始化属性
         *
         * @param width  棋盘 宽度
         * @param height 棋盘 高度
         */
        public HorseChessboard(int width, int height) {
            this.width = width;
            this.height = height;
            this.chessboard = new int[width][height];
            this.visited = new boolean[width * height];
            Arrays.fill(this.visited, false);
        }
    
    
        /**
         * 开始游戏
         *
         * @param p    起始点
         * @param step 第几步
         */
        public void start(Point p, int step) {
            // 标记该点第几步
            this.chessboard[p.x][p.y] = step;
            // 标记以访问过
            int index = p.y * width + p.x;
            this.visited[index] = true;
            // 寻找下一个
            List<Point> ps = findNextStep(p);
            sort(ps);
            while (!ps.isEmpty()) {
                Point point = ps.remove(0);
                // 判断是否访问过
                if (!in(point)) {
                    this.start(point, step + 1);
                }
            }
            //  回溯
            if (step < width * height && !finished) {
                chessboard[p.x][p.y] = 0;
                visited[p.y * width + p.x] = false;
            } else {
                finished = true;
            }
        }
    
    
        /**
         * 寻找下步可能性
         *
         * @param p 当前点
         * @return list
         */
        private List<Point> findNextStep(Point p) {
            List<Point> ps = new ArrayList<>();
            Point nextPoint = new Point();
            // 0
            if ((nextPoint.x = p.x + 2) < width && (nextPoint.y = p.y + 1) < height) {
                ps.add(new Point(nextPoint));
            }
            // 7
            if ((nextPoint.x = p.x + 1) < width && (nextPoint.y = p.y + 2) < height) {
                ps.add(new Point(nextPoint));
            }
            // 6
            if ((nextPoint.x = p.x - 1) >= 0 && (nextPoint.y = p.y + 2) < height) {
                ps.add(new Point(nextPoint));
            }
            // 5
            if ((nextPoint.x = p.x - 2) >= 0 && (nextPoint.y = p.y + 1) < height) {
                ps.add(new Point(nextPoint));
            }
            // 4
            if ((nextPoint.x = p.x - 2) >= 0 && (nextPoint.y = p.y - 1) >= 0) {
                ps.add(new Point(nextPoint));
            }
            // 3
            if ((nextPoint.x = p.x - 1) >= 0 && (nextPoint.y = p.y - 2) >= 0) {
                ps.add(new Point(nextPoint));
            }
            // 2
            if ((nextPoint.x = p.x + 1) < width && (nextPoint.y = p.y - 2) >= 0) {
                ps.add(new Point(nextPoint));
            }
            // 1
            if ((nextPoint.x = p.x + 2) < width && (nextPoint.y = p.y - 1) >= 0) {
                ps.add(new Point(nextPoint));
            }
            return ps;
        }
    
        /**
         * 展示
         */
        public void show() {
            for (int[] ints : this.chessboard) {
                for (int anInt : ints) {
                    System.out.print(anInt + "	");
                }
                System.out.println();
            }
        }
    
    
        /**
         * 判断是否访问过
         *
         * @param p 待判断的端点
         * @return boolean
         */
        private boolean in(Point p) {
            return this.visited[p.y * width + p.x];
        }
    
        /**
         * 进行非递减排序
         *
         * @param ps 待排序的集合
         */
        public void sort(List<Point> ps) {
            ps.sort((item1, item2) -> {
                int count1 = findNextStep(item1).size();
                int count2 = findNextStep(item2).size();
                return Integer.compare(count1, count2);
    //            if (count1 < count2) {
    //                return -1;
    //            } else if (count1 == count2) {
    //                return 0;
    //            } else {
    //                return 1;
    //            }
            });
        }
    
    
  • 相关阅读:
    Hive中将文件加载到数据库表失败解决办法
    Hive安装及配置
    Hadoop下MapReduce实现Pi值的计算
    CentOS下Hadoop运行环境搭建
    kettle案例实现
    假期周总结报告03
    假期周总结报告02
    假期周进度报告01
    阅读笔记6
    阅读笔记5
  • 原文地址:https://www.cnblogs.com/MND1024/p/11611478.html
Copyright © 2011-2022 走看看