java數(shù)據(jù)結(jié)構(gòu)和算法之馬踏棋盤(pán)算法
本文實(shí)例為大家分享了java實(shí)現(xiàn)算法之馬踏棋盤(pán)的具體代碼,供大家參考,具體內(nèi)容如下
一、馬踏棋盤(pán)算法介紹
馬踏棋盤(pán)算法也被稱(chēng)為騎士周游問(wèn)題
將馬隨機(jī)放在國(guó)際象棋的8×8棋盤(pán)Board[0~7][0~7]的某個(gè)方格中,馬按走棋規(guī)則(馬走日字)進(jìn)行移動(dòng)。要求每個(gè)方格只進(jìn)入一次,走遍棋盤(pán)上全部64個(gè)方格
二、騎士周游問(wèn)題的思路分析
1、創(chuàng)建棋盤(pán) chessBoard , 是一個(gè)二維數(shù)組
2、將當(dāng)前位置設(shè)置為已經(jīng)訪(fǎng)問(wèn),然后根據(jù)當(dāng)前位置,計(jì)算馬兒還能走哪些位置,并放入到一個(gè)集合中(ArrayList), 最多有8個(gè)位置, 每走一步,就使用step+1
3、遍歷ArrayList中存放的所有位置,看看哪個(gè)可以走通 , 如果走通,就繼續(xù),走不通,就回溯.
4、判斷馬兒是否完成了任務(wù),使用 step 和應(yīng)該走的步數(shù)比較 , 如果沒(méi)有達(dá)到數(shù)量,則表示沒(méi)有完成任務(wù),將整個(gè)棋盤(pán)置0
5、注意:馬兒不同的走法(策略),會(huì)得到不同的結(jié)果,效率也會(huì)有影響(優(yōu)化)
三、騎士周游問(wèn)題代碼示例
1、代碼
package com.rf.data_structure_algorithm.algorithm.horseChessBoard; import java.awt.*; import java.util.ArrayList; import java.util.Comparator; /** ?* @description: 騎士周游算法示例 ?* @author: xz ?*/ public class HorseChessBoard { ? ? ?static int X;//棋盤(pán)的列數(shù) ? ? ?static int Y;//棋盤(pán)的行數(shù) ? ? ?static boolean visited[]; //標(biāo)記棋盤(pán)的各個(gè)位置是否被訪(fǎng)問(wèn)過(guò) ? ? ?static boolean finished; // 標(biāo)記是否棋盤(pán)的所有位置都被訪(fǎng)問(wèn) true:成功,false:失敗 ? ? public static void main(String[] args) { ? ? ? ? System.out.println("騎士周游算法,開(kāi)始運(yùn)行~~"); ? ? ? ? X=8; ? ? ? ? Y=8; ? ? ? ? int row=1;//馬初始位置的行,從編號(hào)1開(kāi)始 ? ? ? ? int column=1;//馬初始位置的列,從編號(hào)1開(kāi)始 ? ? ? ? //創(chuàng)建棋盤(pán) ? ? ? ? int[][] chessboard=new int[X][Y]; ? ? ? ? visited=new boolean[X*Y];//初始值都是false ? ? ? ? //測(cè)試 ? ? ? ? long startTime = System.currentTimeMillis(); ? ? ? ? horseChessBoardAlgorithm(chessboard,row-1,column-1,1); ? ? ? ? long endTime = System.currentTimeMillis(); ? ? ? ? System.out.println("總共耗時(shí):"+(endTime-startTime)+"毫秒"); ? ? ? ? System.out.println("輸出棋盤(pán)的最后情況============"); ? ? ? ? //輸出棋盤(pán)的最后情況 ? ? ? ? for(int[] rows : chessboard){ ? ? ? ? ? ? for(int step : rows){ ? ? ? ? ? ? ? ? System.out.print(step + "\t"); ? ? ? ? ? ? } ? ? ? ? ? ? System.out.println(); ? ? ? ? } ? ? } ? ? /**? ? ? * @Description: 根據(jù)當(dāng)前位置(Point),計(jì)算馬還能走哪些位置(Point) ? ? ?* ? ? ? ? ? ? ? ?并放入到一個(gè)集合中(ArrayList),最多有8個(gè)位置 ? ? * @Param: ?curPoint ? ? * @Author: xz ? ? ? */ ? ? public static ArrayList<Point> next(Point curPoint){ ? ? ? ? //創(chuàng)建一個(gè)ArrayList ? ? ? ? ArrayList<Point> list =new ArrayList<>(); ? ? ? ? //創(chuàng)建一個(gè)Point ? ? ? ? Point point=new Point(); ? ? ? ? //curPoint.x-2 表示當(dāng)前位置(curPoint)的列向左移動(dòng)2列 ? ? ? ? //curPoint.x+2 表示當(dāng)前位置(curPoint)的列向右移動(dòng)2列 ? ? ? ? //curPoint.y-1 表示當(dāng)前位置(curPoint)的列向上移動(dòng)1行 ? ? ? ? //curPoint.y+1 表示當(dāng)前位置(curPoint)的列向下移動(dòng)1行 ? ? ? ? // >= 0 表示仍然有空間可走 ? ? ? ? if((point.x = curPoint.x-2) >= 0 && (point.y = curPoint.y-1) >= 0 ){//示例圖中指定馬可以走5的位置 ? ? ? ? ? ? list.add(new Point(point)); ? ? ? ? } ? ? ? ? if((point.x = curPoint.x - 1) >=0 && (point.y=curPoint.y-2)>=0) {//示例圖中指定馬可以走6的位置 ? ? ? ? ? ? list.add(new Point(point)); ? ? ? ? } ? ? ? ? if ((point.x = curPoint.x + 1) < X && (point.y = curPoint.y - 2) >= 0) {//示例圖中指定馬可以走7的位置 ? ? ? ? ? ? list.add(new Point(point)); ? ? ? ? } ? ? ? ? if ((point.x = curPoint.x + 2) < X && (point.y = curPoint.y - 1) >= 0) {//示例圖中指定馬可以走0的位置 ? ? ? ? ? ? list.add(new Point(point)); ? ? ? ? } ? ? ? ? if ((point.x = curPoint.x + 2) < X && (point.y = curPoint.y + 1) < Y) {//示例圖中指定馬可以走1的位置 ? ? ? ? ? ? list.add(new Point(point)); ? ? ? ? } ? ? ? ? if ((point.x = curPoint.x + 1) < X && (point.y = curPoint.y + 2) < Y) {//示例圖中指定馬可以走2的位置 ? ? ? ? ? ? list.add(new Point(point)); ? ? ? ? } ? ? ? ? if ((point.x = curPoint.x - 1) >= 0 && (point.y = curPoint.y + 2) < Y) {//示例圖中指定馬可以走3的位置 ? ? ? ? ? ? list.add(new Point(point)); ? ? ? ? } ? ? ? ? if ((point.x = curPoint.x - 2) >= 0 && (point.y = curPoint.y + 1) < Y) {//示例圖中指定馬可以走4的位置 ? ? ? ? ? ? list.add(new Point(point)); ? ? ? ? } ? ? ? ? return list; ? ? } ? ? /**? ? ? * @Description: ?騎士周游算法的方法 ? ? * @Param: ?chessboard ?表示棋盤(pán) ? ? * ? ? ? ? ? row ? ? ? ? 表示馬兒當(dāng)前的位置的行 從0開(kāi)始 ? ? * ? ? ? ? ? column ? ? ?表示馬兒當(dāng)前的位置的列 ?從0開(kāi)始 ? ? * ? ? ? ? ? step ? ? ? ?表示是第幾步 ,初始位置就是第1步 ? ? * @Author: xz ? ? ? */ ? ? public static void horseChessBoardAlgorithm(int[][] chessboard, int row, int column, int step){ ? ? ? ? chessboard[row][column] = step; ? ? ? ? visited[row * X + column] = true; //標(biāo)記該位置已經(jīng)訪(fǎng)問(wèn) ? ? ? ? //獲取當(dāng)前位置可以走的下一個(gè)位置的集合 ? ? ? ? ArrayList<Point> pointList= next(new Point(column, row)); ? ? ? ? //對(duì)pointList進(jìn)行排序,排序的規(guī)則就是對(duì)pointList的所有的Point對(duì)象的下一步的位置的數(shù)目,進(jìn)行非遞減排序 ? ? ? ? sort(pointList); ? ? ? ? //遍歷 list ? ? ? ? while(!pointList.isEmpty()) { ? ? ? ? ? ? Point p = pointList.remove(0);//取出下一個(gè)可以走的位置 ? ? ? ? ? ? //判斷該點(diǎn)是否已經(jīng)訪(fǎng)問(wèn)過(guò) ? ? ? ? ? ? if(!visited[p.y * X + p.x]) {//說(shuō)明還沒(méi)有訪(fǎng)問(wèn)過(guò) ? ? ? ? ? ? ? ? horseChessBoardAlgorithm(chessboard, p.y, p.x, step + 1); ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? //判斷馬兒是否完成了任務(wù),使用step 和應(yīng)該走的步數(shù)比較 , ? ? ? ? //如果沒(méi)有達(dá)到數(shù)量,則表示沒(méi)有完成任務(wù),將整個(gè)棋盤(pán)置0 ? ? ? ? //說(shuō)明: step < X * Y ?成立的情況有兩種 ? ? ? ? //1. 棋盤(pán)到目前位置,仍然沒(méi)有走完 ? ? ? ? //2. 棋盤(pán)處于一個(gè)回溯過(guò)程 ? ? ? ? if(step < X * Y && !finished ) { ? ? ? ? ? ? chessboard[row][column] = 0; ? ? ? ? ? ? visited[row * X + column] = false; ? ? ? ? } else { ? ? ? ? ? ? finished = true; ? ? ? ? } ? ? } ? ? /** ? ? ?* @Description: 根據(jù)當(dāng)前這個(gè)一步的所有的下一步的選擇位置,進(jìn)行非遞減排序, 減少回溯的次數(shù) ? ? ?* @Param: ?ArrayList<Point> ? ? ?* @Author: xz ? ? ?*/ ? ? public static void sort(ArrayList<Point> pointList) { ? ? ? ? pointList.sort(new Comparator<Point>() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public int compare(Point o1, Point o2) { ? ? ? ? ? ? ? ? // TODO Auto-generated method stub ? ? ? ? ? ? ? ? //獲取到o1的下一步的所有位置個(gè)數(shù) ? ? ? ? ? ? ? ? int count1 = next(o1).size(); ? ? ? ? ? ? ? ? //獲取到o2的下一步的所有位置個(gè)數(shù) ? ? ? ? ? ? ? ? int count2 = next(o2).size(); ? ? ? ? ? ? ? ? if(count1 < count2) { ? ? ? ? ? ? ? ? ? ? return -1; ? ? ? ? ? ? ? ? } else if (count1 == count2) { ? ? ? ? ? ? ? ? ? ? return 0; ? ? ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? ? ? return 1; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? }); ? ? } }
2、運(yùn)行main函數(shù),輸出馬在棋盤(pán)中走的步驟和位置如下:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- java數(shù)據(jù)結(jié)構(gòu)與算法之馬踏棋盤(pán)
- 基于Java實(shí)現(xiàn)馬踏棋盤(pán)游戲算法
- java學(xué)習(xí)筆記之馬踏棋盤(pán)算法
- Java實(shí)現(xiàn)馬踏棋盤(pán)算法
- java實(shí)現(xiàn)馬踏棋盤(pán)的算法
- java實(shí)現(xiàn)馬踏棋盤(pán)的完整版
- java實(shí)現(xiàn)馬踏棋盤(pán)游戲
- Java實(shí)現(xiàn)兩人五子棋游戲(二) 畫(huà)出棋盤(pán)
- Java基于分治算法實(shí)現(xiàn)的棋盤(pán)覆蓋問(wèn)題示例
- java實(shí)現(xiàn)馬踏棋盤(pán)算法(騎士周游問(wèn)題)
相關(guān)文章
java多線(xiàn)程實(shí)現(xiàn)文件下載功能
這篇文章主要介紹了java多線(xiàn)程實(shí)現(xiàn)文件下載功能的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01SpringBoot注冊(cè)FilterRegistrationBean相關(guān)情況講解
這篇文章主要介紹了SpringBoot注冊(cè)FilterRegistrationBean相關(guān)情況,借助FilterRegistrationBean來(lái)注冊(cè)filter,可以避免在web.xml種配置filter這種原始的寫(xiě)法2023-02-02SpringBoot3集成Thymeleaf的過(guò)程詳解
在現(xiàn)代的Web開(kāi)發(fā)中,構(gòu)建靈活、動(dòng)態(tài)的用戶(hù)界面是至關(guān)重要的,Spring Boot和Thymeleaf的結(jié)合為開(kāi)發(fā)者提供了一種簡(jiǎn)單而強(qiáng)大的方式來(lái)創(chuàng)建動(dòng)態(tài)的Web應(yīng)用,本文將介紹如何在Spring Boot項(xiàng)目中集成Thymeleaf,并展示一些基本的使用方法,需要的朋友可以參考下2024-01-01Java設(shè)計(jì)模式七大原則之開(kāi)閉原則詳解
開(kāi)閉原則,又稱(chēng)為OCP原則,即一個(gè)軟件實(shí)體如類(lèi),模塊和函數(shù)應(yīng)該對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉。本文將詳細(xì)介紹Java設(shè)計(jì)模式七大原則之一的開(kāi)閉原則,需要的可以參考一下2022-02-02Java 線(xiàn)程池ThreadPoolExecutor源碼解析
這篇文章主要介紹了Java 線(xiàn)程池ThreadPoolExecutor源碼解析2022-03-03Spring中的spring.factories文件用法(Spring如何加載第三方Bean)
這篇文章主要介紹了Spring中的spring.factories文件用法(Spring如何加載第三方Bean),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10