最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java學習筆記之馬踏棋盤算法

 更新時間:2022年02月14日 16:09:01   作者:touteng55  
這篇文章主要為大家詳細介紹了java學習筆記之馬踏棋盤算法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

馬踏棋盤或騎士周游問題

1、馬踏棋盤算法也被稱為騎士周游問題
2、將馬隨機放在國際象棋的 8×8 棋盤 Board[0~7][0~7]的某個方格中,馬按走棋規(guī)則(馬走日字)進行移動。要求每個方格只進入一次,走遍棋盤上全部 64 個方格

思路

會使用到深度優(yōu)先思想和類似迷宮問題的尋路策略問題,和八皇后問題也有相似。

1、用一個二維數(shù)組建立整張棋盤。用另外一個二維數(shù)組保存棋盤的每一個位置是否走過
2、馬在棋盤上有一個初始位置,將這個位置設(shè)為已走過,并將步數(shù)設(shè)為1.
3、獲得在這個位置上,馬下一步能走的位置集合。
4、遍歷集合里的所有位置,如果那個位置沒走過,下一步(步數(shù)+1)就走它(遞歸)
5、設(shè)置遞歸結(jié)束的標志.用一個布爾變量標志游戲是否成功。當游戲成功時,步數(shù)應(yīng)該等于棋盤格子數(shù)。假如某一次,馬走完了所有能走的下一步位置,步數(shù)還小于棋盤格子數(shù)并且還沒成功,說明這個位置不能成功的完成游戲,就把這個位置恢復原樣(棋盤設(shè)為0,設(shè)為未走過),接下來的遞歸會重新去尋找合適的路。如果步數(shù)等于棋盤總格子數(shù),說明游戲成功,把標志的布爾變量設(shè)為true,這樣在層層返回時就不會再進入上面的條件,遞歸就會逐漸結(jié)束而不會深入下去。

涉及到的方法:

根據(jù)此時的位置,判斷馬接下來能走的位置集合。
x的值代表列而y的值代表行
馬是按照日字走的,所有當它在中間時最多有8種位置可以走,一 一判斷那個位置是否超過棋盤邊界。
每種可能都是if,而不是if-else if,因為要獲得所有的可能性,而不是找出一個
假如list時一定要新建一個坐標,不能使用同一個,不然值就會互相影響

/**
? ? ?* 根據(jù)現(xiàn)在的坐標返回可以走的坐標 x列y行
? ? ?*
? ? ?* @param current
? ? ?* @return
? ? ?*/
? ? public static ArrayList<Point> findWay(Point current) {
? ? ? ? ArrayList<Point> res = new ArrayList<>();
? ? ? ? //可以走的坐標
? ? ? ? Point p = new Point();
? ? ? ? //5
? ? ? ? if ((p.x = current.x - 2) >= 0 && (p.y = current.y - 1) >= 0) {
? ? ? ? ? ? res.add(new Point(p));
? ? ? ? }
? ? ? ? //6
? ? ? ? if ((p.x = current.x - 1) >= 0 && (p.y = current.y - 2) >= 0) {
? ? ? ? ? ? res.add(new Point(p));
? ? ? ? }
? ? ? ? //7
? ? ? ? if ((p.x = current.x + 1) < X && (p.y = current.y - 2) >= 0) {
? ? ? ? ? ? res.add(new Point(p));
? ? ? ? }
? ? ? ? //0
? ? ? ? if ((p.x = current.x + 2) < X && (p.y = current.y - 1) >= 0) {
? ? ? ? ? ? res.add(new Point(p));
? ? ? ? }
? ? ? ? //1
? ? ? ? if ((p.x = current.x + 2) < X && (p.y = current.y + 1) < Y) {
? ? ? ? ? ? res.add(new Point(p));
? ? ? ? }
? ? ? ? //2
? ? ? ? if ((p.x = current.x + 1) < X && (p.y = current.y + 2) < Y) {
? ? ? ? ? ? res.add(new Point(p));
? ? ? ? }
? ? ? ? //3
? ? ? ? if ((p.x = current.x - 1) >= 0 && (p.y = current.y + 2) < Y) {
? ? ? ? ? ? res.add(new Point(p));
? ? ? ? }
? ? ? ? //4
? ? ? ? if ((p.x = current.x - 2) >= 0 && (p.y = current.y + 1) < Y) {
? ? ? ? ? ? res.add(new Point(p));
? ? ? ? }
? ? ? ? return res;
? ? }

馬塔棋盤

不能單純以step < X * Y來判斷是否完成游戲,因為遞歸回溯時步數(shù)也會回溯,所以要設(shè)置一個變量

?/**
? ? ?* 馬踏棋盤算法
? ? ?*
? ? ?* @param chess 棋盤
? ? ?* @param row ? 坐標行
? ? ?* @param col ? 坐標列
? ? ?* @param step ?步數(shù)
? ? ?*/
? ? public static void traversalChessboard(int[][] chess, int row, int col, int step) {
? ? ? ? //先走一步
? ? ? ? chess[row][col] = step;
? ? ? ? visit[row][col] = true;
? ? ? ? //下一步能走的地
? ? ? ? ArrayList<Point> way = findWay(new Point(col, row));
? ? ? ? while (!way.isEmpty()) {
? ? ? ? ? ? //取出一個能走的地方
? ? ? ? ? ? Point point = way.remove(0);
? ? ? ? ? ? //走下一步
? ? ? ? ? ? if (!visit[point.y][point.x]) {
? ? ? ? ? ? ? ? traversalChessboard(chess, point.y, point.x, step + 1);
? ? ? ? ? ? }

? ? ? ? }
? ? ? ? //判斷是否完成游戲,如果沒完成就要回溯
? ? ? ? if (step < X * Y && !finshed) {
? ? ? ? ? ? chess[row][col] = 0;
? ? ? ? ? ? visit[row][col] = false;
? ? ? ? }else {
? ? ? ? ? ? finshed=true;
? ? ? ? }
? ? }

優(yōu)化

這樣計算效率比較低,算法比較慢。實際上當我們獲得下一步可以走的位置數(shù)組時是按照固定的56701234順序排列的,但是這樣效率不高,我們在考慮到走下一步時,應(yīng)該先走對應(yīng)下一步的可能性最少的那一步,比如如果7的下一步有3種可能,而5的下一步有6種可能,那先7后5的效率會更高。

所以我們可以使用貪心算法對獲得的這個步數(shù)集合根據(jù)他們下一步的可能性進行由小到大的排序。

/**
? ? ?* 貪心算法優(yōu)化
? ? ?* @param ps
? ? ?*/
? ? public static void sort(ArrayList<Point> ps){
? ? ? ? ps.sort(new Comparator<Point>() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public int compare(Point o1, Point o2) {
? ? ? ? ? ? ? ? int way1 = findWay(o1).size();
? ? ? ? ? ? ? ? int way2 = findWay(o2).size();
? ? ? ? ? ? ? ? if(way1<way2){
? ? ? ? ? ? ? ? ? ? return -1;
? ? ? ? ? ? ? ? }else if(way1==way2){
? ? ? ? ? ? ? ? ? ? return 0;
? ? ? ? ? ? ? ? }else {
? ? ? ? ? ? ? ? ? ? return 1;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? });
}

對Comparetor.compare(o1, o2)方法的返回值,如果返回的值小于零,則不交換兩個o1和o2的位置;如果返回的值大于零,則交換o1和o2的位置。 注意,不論在compare(o1, o2)中是如何實現(xiàn)的(第一種實現(xiàn)方式是 o1-02, 第二種實現(xiàn)方式是 o2 - o1),都遵循上述原則,即返回值小于零,則交換o1和o2的位置;返回值大于零,則不交換o1和o2的位置。 所以,如果采用第一種實現(xiàn)方式,即 o1 - o2, 那么將是升序排序。因為在原始排序中o1在o2的前邊,如果o1小于o2,那么o1 - o2小于零,即返回值是小于零,但是小于零是不會交換o1和o2的位置的,所以o1依然排在o2的前邊,是升序;如果o1大于o2,那么o1 - o2大于零,即返回值是大于零,大于零是要交換o1和o2的位置的,所以要改變原始排序中o1和o2的位置,那么依然是升序

最終代碼

package algorithm;

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

/**
?* 馬踏棋盤算法
?*/
public class HorseChessboard {
? ? static int X;//列
? ? static int Y;//行
? ? static boolean[][] visit;
? ? static boolean finshed;

? ? public static void main(String[] args) {
? ? ? ? X = 8;
? ? ? ? Y = 8;
? ? ? ? visit = new boolean[X][Y];
? ? ? ? finshed = false;
? ? ? ? int[][] chess = new int[X][Y];
? ? ? ? long s = System.currentTimeMillis();

? ? ? ? traversalChessboard(chess, 2, 0, 1);
? ? ? ? long e=System.currentTimeMillis();
? ? ? ? System.out.println(e-s);

? ? ? ? for (int i = 0; i < chess.length; i++) {
? ? ? ? ? ? System.out.println(Arrays.toString(chess[i]));
? ? ? ? }

? ? }

? ? /**
? ? ?* 馬踏棋盤算法
? ? ?*
? ? ?* @param chess 棋盤
? ? ?* @param row ? 坐標行
? ? ?* @param col ? 坐標列
? ? ?* @param step ?步數(shù)
? ? ?*/
? ? public static void traversalChessboard(int[][] chess, int row, int col, int step) {
? ? ? ? //先走一步
? ? ? ? chess[row][col] = step;
? ? ? ? visit[row][col] = true;
? ? ? ? //下一步能走的地
? ? ? ? ArrayList<Point> way = findWay(new Point(col, row));
? ? ? ? sort(way);
? ? ? ? while (!way.isEmpty()) {
? ? ? ? ? ? //取出一個能走的地方
? ? ? ? ? ? Point point = way.remove(0);
? ? ? ? ? ? //走下一步
? ? ? ? ? ? if (!visit[point.y][point.x]) {
? ? ? ? ? ? ? ? traversalChessboard(chess, point.y, point.x, step + 1);
? ? ? ? ? ? }

? ? ? ? }
? ? ? ? if (step < X * Y && !finshed) {
? ? ? ? ? ? chess[row][col] = 0;
? ? ? ? ? ? visit[row][col] = false;
? ? ? ? }else {
? ? ? ? ? ? finshed=true;
? ? ? ? }
? ? }

? ? /**
? ? ?* 根據(jù)現(xiàn)在的坐標返回可以走的坐標 x列y行
? ? ?*
? ? ?* @param current
? ? ?* @return
? ? ?*/
? ? public static ArrayList<Point> findWay(Point current) {
? ? ? ? ArrayList<Point> res = new ArrayList<>();
? ? ? ? //可以走的坐標
? ? ? ? Point p = new Point();
? ? ? ? //5
? ? ? ? if ((p.x = current.x - 2) >= 0 && (p.y = current.y - 1) >= 0) {
? ? ? ? ? ? res.add(new Point(p));
? ? ? ? }
? ? ? ? //6
? ? ? ? if ((p.x = current.x - 1) >= 0 && (p.y = current.y - 2) >= 0) {
? ? ? ? ? ? res.add(new Point(p));
? ? ? ? }
? ? ? ? //7
? ? ? ? if ((p.x = current.x + 1) < X && (p.y = current.y - 2) >= 0) {
? ? ? ? ? ? res.add(new Point(p));
? ? ? ? }
? ? ? ? //0
? ? ? ? if ((p.x = current.x + 2) < X && (p.y = current.y - 1) >= 0) {
? ? ? ? ? ? res.add(new Point(p));
? ? ? ? }
? ? ? ? //1
? ? ? ? if ((p.x = current.x + 2) < X && (p.y = current.y + 1) < Y) {
? ? ? ? ? ? res.add(new Point(p));
? ? ? ? }
? ? ? ? //2
? ? ? ? if ((p.x = current.x + 1) < X && (p.y = current.y + 2) < Y) {
? ? ? ? ? ? res.add(new Point(p));
? ? ? ? }
? ? ? ? //3
? ? ? ? if ((p.x = current.x - 1) >= 0 && (p.y = current.y + 2) < Y) {
? ? ? ? ? ? res.add(new Point(p));
? ? ? ? }
? ? ? ? //4
? ? ? ? if ((p.x = current.x - 2) >= 0 && (p.y = current.y + 1) < Y) {
? ? ? ? ? ? res.add(new Point(p));
? ? ? ? }
? ? ? ? return res;
? ? }

? ? /**
? ? ?* 貪心算法優(yōu)化
? ? ?* @param ps
? ? ?*/
? ? public static void sort(ArrayList<Point> ps){
? ? ? ? ps.sort(new Comparator<Point>() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public int compare(Point o1, Point o2) {
? ? ? ? ? ? ? ? int way1 = findWay(o1).size();
? ? ? ? ? ? ? ? int way2 = findWay(o2).size();
? ? ? ? ? ? ? ? if(way1<way2){
? ? ? ? ? ? ? ? ? ? return -1;
? ? ? ? ? ? ? ? }else if(way1==way2){
? ? ? ? ? ? ? ? ? ? return 0;
? ? ? ? ? ? ? ? }else {
? ? ? ? ? ? ? ? ? ? return 1;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? });
? ? }
}

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 如何動態(tài)替換Spring容器中的Bean

    如何動態(tài)替換Spring容器中的Bean

    這篇文章主要介紹了如何動態(tài)替換Spring容器中的Bean,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • idea本地merge如何合并代碼

    idea本地merge如何合并代碼

    這篇文章主要介紹了idea本地merge如何合并代碼問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • Java多線程下載網(wǎng)圖的完整案例

    Java多線程下載網(wǎng)圖的完整案例

    這篇文章主要給大家介紹了關(guān)于Java多線程下載網(wǎng)圖的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • mybatis-plus生成mapper擴展文件的方法

    mybatis-plus生成mapper擴展文件的方法

    這篇文章主要介紹了mybatis-plus生成mapper擴展文件的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-09-09
  • Spring Data JPA使用Sort進行排序(Using Sort)

    Spring Data JPA使用Sort進行排序(Using Sort)

    本篇文章主要介紹了Spring Data JPA使用Sort進行排序(Using Sort),具有一定的參考價值,有興趣的可以了解一下
    2017-07-07
  • java“與”符號寫法與用法

    java“與”符號寫法與用法

    在本篇文章里小編給大家整理的是關(guān)于java“與”符號寫法與用法,對此有需要的朋友們可以學習下。
    2020-02-02
  • Spring Security使用Lambda DSL配置流程詳解

    Spring Security使用Lambda DSL配置流程詳解

    Spring Security 5.2 對 Lambda DSL 語法的增強,允許使用lambda配置HttpSecurity、ServerHttpSecurity,重要提醒,之前的配置方法仍然有效。lambda的添加旨在提供更大的靈活性,但是用法是可選的。讓我們看一下HttpSecurity的lambda配置與以前的配置樣式相比
    2023-02-02
  • 使用監(jiān)聽器對Spring bean id進行唯一校驗過程解析

    使用監(jiān)聽器對Spring bean id進行唯一校驗過程解析

    這篇文章主要介紹了使用監(jiān)聽器對Spring bean id進行唯一校驗過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-08-08
  • SpringBoot集成WebSocket實現(xiàn)后臺向前端推送信息

    SpringBoot集成WebSocket實現(xiàn)后臺向前端推送信息

    在一次項目開發(fā)中,使用到了Netty網(wǎng)絡(luò)應(yīng)用框架,以及MQTT進行消息數(shù)據(jù)的收發(fā),這其中需要后臺來將獲取到的消息主動推送給前端,所以本文記錄了SpringBoot集成WebSocket實現(xiàn)后臺向前端推送信息的操作,需要的朋友可以參考下
    2024-02-02
  • SpringCloud?Hystrix?斷路器的實現(xiàn)

    SpringCloud?Hystrix?斷路器的實現(xiàn)

    本文主要介紹了SpringCloud?Hystrix?斷路器的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-03-03

最新評論

凌海市| 丰台区| 灵台县| 桦南县| 东兴市| 铜鼓县| 吉首市| 蒙阴县| 衡山县| 田阳县| 安庆市| 大城县| 红安县| 连南| 丰顺县| 潼关县| 嫩江县| 杭州市| 驻马店市| 莆田市| 云安县| 陆丰市| 惠来县| 商南县| 大石桥市| 永昌县| 山阳县| 九龙城区| 肥东县| 安宁市| 勃利县| 卓尼县| 广元市| 汕头市| 宣化县| 文成县| 临夏市| 通河县| 晴隆县| 闻喜县| 蓝山县|