其他分享
首页 > 其他分享> > 骑士周游问题

骑士周游问题

作者:互联网

算法

1. 骑士周游问题

  1. 马踏棋盘算法也被称为骑士周游问题

  2. 将马随机放在国际象棋的 8x8 棋盘中[0~7][0~7]的某个方格中,马鞍走起规则(马走日字)进行移动。要求每个方格只进入一次,走遍棋盘上全部64个方格

    image-20211121140959076

​ 3. 会使用到图的遍历算法(DFS)+ 贪心算法优化

1.1 普通方法

package com.example.mhl_demo.day01;

import java.awt.*;
import java.util.ArrayList;

/**
 * 骑士周游
 */
public class HouseChessBoard {
    //定义属性
    private static int X = 6;//表示 col
    private static int Y = 6;//表示 row
    //棋盘
    private static int[][] chessBoard = new int[Y][X];
    //记录某个位置是否走过
    private static boolean[] visited = new boolean[X * Y];
    //记录马儿是否遍历完棋盘
    private static boolean finished = false;

    public static void main(String[] args) {
        int row = 5;
        int col = 5;
        //测试
        long start = System.currentTimeMillis();
        traversalChessBoard(chessBoard,row-1,col - 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();
        }

    }

    /*
        编写最核心的算法,遍历棋盘,入股遍历成功,finished 设置为true,
            并且将马儿走的每一步 step,记录到 chessBoard
     */
    public static void traversalChessBoard(int[][] chessBoard,int row,int col,int step){
        //先把step记录到chessBoard
        chessBoard[row][col] = step;
        //把这个位置,设置为已访问
        visited[row * X + col] = true;
        //获取当前位置可以走的下一个位置有哪些
        ArrayList<Point> ps = next(new Point(col, row));
        //遍历
        while (!ps.isEmpty()){
            //取出当前ps的第一个位置
            Point p = ps.remove(0);
            //判断该位置是否走过,如果没有没有走过,就递归遍历
            if (!visited[p.y * X + p.x]){
                //可以走
                traversalChessBoard(chessBoard,p.y,p.x,step + 1);
            }
        }

        /*
            当退出while,查看是否遍历成功.
                如果没有遍历成功,就重置当前位置,回溯
                如果成功,设置走完整个棋盘
         */
        if (step < X * Y && !finished ){
            //重置
            chessBoard[row][col] = 0;
            visited[row * X + col] = false;
        }else {
            finished = true;
        }
    }


    //编写方法,可以获取当前位置的下一步的所有位置
    public static ArrayList<Point> next(Point curPoint) {
        //创建一个ArrayList
        ArrayList<Point> ps = new ArrayList<>();

        //创建一个point(点),准备放入ps
        Point p1 = new Point();

        //判断是否可以走5的位置
        if ((p1.x = curPoint.x - 1) >= 0 && (p1.y = curPoint.y - 1) >=0){
            //这里一定new point
            ps.add(new Point(p1));
        }
        //判断是否可以走6的位置
        if ((p1.x = curPoint.x - 1) >= 0 && (p1.y = curPoint.y - 2) >=0){
            //这里一定new point
            ps.add(new Point(p1));
        }
        //判断是否可以走7的位置
        if ((p1.x = curPoint.x + 1) < X && (p1.y = curPoint.y - 2) >=0){
            //这里一定new point
            ps.add(new Point(p1));
        }
        //判断是否可以走0的位置
        if ((p1.x = curPoint.x + 2) < X && (p1.y = curPoint.y - 1) >=0){
            //这里一定new point
            ps.add(new Point(p1));
        }
        //判断是否可以走1的位置
        if ((p1.x = curPoint.x + 2) < X && (p1.y = curPoint.y + 1) < Y){
            //这里一定new point
            ps.add(new Point(p1));
        }
        //判断是否可以走2的位置
        if ((p1.x = curPoint.x + 1) < X && (p1.y = curPoint.y + 2) < Y){
            //这里一定new point
            ps.add(new Point(p1));
        }
        //判断是否可以走3的位置
        if ((p1.x = curPoint.x - 1) >= 0 && (p1.y = curPoint.y + 2) < Y){
            //这里一定new point
            ps.add(new Point(p1));
        }
        //判断是否可以走4的位置
        if ((p1.x = curPoint.x - 2) >= 0 && (p1.y = curPoint.y + 1) < Y){
            //这里一定new point
            ps.add(new Point(p1));
        }
        return ps;
    }
}

1.2 贪心算法优化

使用贪心算法,进行优化,提高速度

分析

/*
    编写一个方法,对ps的各个位置,可以走的下一个位置的次数进行排序,
    按照从小到大的顺序进行排序
 */
public static void sort(ArrayList<Point> ps){
    ps.sort((o1, o2) -> next(o1).size() - next(o2).size());
}

traversalChessBoard中获取next方法之后 进行排序

/*
    编写最核心的算法,遍历棋盘,入股遍历成功,finished 设置为true,
        并且将马儿走的每一步 step,记录到 chessBoard
 */
public static void traversalChessBoard(int[][] chessBoard,int row,int col,int step){
    //先把step记录到chessBoard
    chessBoard[row][col] = step;
    //把这个位置,设置为已访问
    visited[row * X + col] = true;
    //获取当前位置可以走的下一个位置有哪些
    ArrayList<Point> ps = next(new Point(col, row));
    //排序
    sort(ps);
    //遍历
    while (!ps.isEmpty()){
        //取出当前ps的第一个位置
        Point p = ps.remove(0);
        //判断该位置是否走过,如果没有没有走过,就递归遍历
        if (!visited[p.y * X + p.x]){
            //可以走
            traversalChessBoard(chessBoard,p.y,p.x,step + 1);
        }
    }
}

标签:ps,周游,p1,Point,int,问题,curPoint,new,骑士
来源: https://blog.csdn.net/weixin_42553198/article/details/121455544