馬踏棋盤演算法詳解
阿新 • • 發佈:2021-06-18
馬踏棋盤演算法詳解
說明
- 馬踏棋盤是指在一個8 * 8的國際棋盤上,從某一位置開始,每次走一個日字,將所有的位置都走一遍
- 可以使用遞迴 + 回溯來解決,再加上貪心演算法來優化
- 指定某種策略,因為從棋盤的某一位置開始走,它的下一步最多有8個選擇,編寫一個方法,將下一步能走的位置記錄在集合中
- 建立一個Boolean陣列記錄當前位置是否走過,如果沒有走過則可以走,否則不能
- 從開始的位置開始,遍歷它的下一步可以走的位置的集合,如果當前位置沒有走過,則從當前位置又重新開始走,開始判斷下一次可以走的位置,如果走不通則回溯
- 直到所有的位置都訪問過,並且走完相應的步數
- 在從集合中選擇下一步時,優先選擇下一步的下一步可選擇的位置較少的位置,體現貪心的思想
- 原始碼見下
原始碼及分析
package algorithm.algorithm.horse; import java.awt.*; import java.util.ArrayList; import java.util.Comparator; /** * @author AIMX_INFO * @version 1.0 */ @SuppressWarnings("all") public class HorseChessBoard { //棋盤的列 public static int X; //棋盤的行 public static int Y; //判斷當前位置是否走過 public static boolean[] visited; //判斷是否完成 public static boolean finished; public static void main(String[] args) { X = 8; Y = 8; int row = 2; int col = 4; visited = new boolean[X * Y]; int[][] chessboard = new int[X][Y]; traversalChessBoard(chessboard, row - 1, col - 1, 1); show(chessboard); } //顯示棋盤 public static void show(int[][] chessboard){ for (int[] rol : chessboard) { for (int step : rol) { System.out.print(step + "\t"); } System.out.println(); } } /** * @param chess 棋盤 * @param row 從棋盤的哪一行開始 * @param col 那一列 * @param step 表示走的第幾步 */ public static void traversalChessBoard(int[][] chess, int row, int col, int step) { //設定當前位置是第幾步 chess[row][col] = step; //設定當前位置為已經走過 visited[row * X + col] = true; //取出當前位置可以走的下一步的集合 ArrayList<Point> ps = next(new Point(col, row)); //使用貪心演算法思想,優先走下一步選擇較少的位置 ps.sort(new Comparator<Point>() { @Override public int compare(Point o1, Point o2) { return next(o1).size() - next(o2).size(); } }); //然後遍歷下一步所有可以走的點 while (!ps.isEmpty()) { Point p = ps.remove(0); if (!visited[p.y * X + p.x]) { traversalChessBoard(chess, p.y, p.x, step + 1); } } //噹噹前位置的下一個位置走不通時,判斷是否走完,如果沒有走完,將當前位置置為未走過 if (step < X * Y && !finished) { chess[row][col] = 0; visited[row * X + col] = false; } else { finished = true; } } /** * \ * * @param cur 當前位置點的座標 * @return 返回從當前位置可以走的下一個位置的所有點的集合 */ public static ArrayList<Point> next(Point cur) { //建立集合儲存可以走的點 ArrayList<Point> ps = new ArrayList<>(); //建立一個點 Point p = new Point(); if ((p.x = cur.x - 2) >= 0 && (p.y = cur.y - 1) >= 0) { ps.add(new Point(p)); } if ((p.x = cur.x - 1) >= 0 && (p.y = cur.y - 2) >= 0) { ps.add(new Point(p)); } if ((p.x = cur.x + 2) < X && (p.y = cur.y - 1) >= 0) { ps.add(new Point(p)); } if ((p.x = cur.x + 1) < X && (p.y = cur.y - 2) >= 0) { ps.add(new Point(p)); } if ((p.x = cur.x + 2) < X && (p.y = cur.y + 1) < Y) { ps.add(new Point(p)); } if ((p.x = cur.x + 1) < X && (p.y = cur.y + 2) < Y) { ps.add(new Point(p)); } if ((p.x = cur.x - 2) >= 0 && (p.y = cur.y + 1) < Y) { ps.add(new Point(p)); } if ((p.x = cur.x - 1) >= 0 && (p.y = cur.y + 2) < Y) { ps.add(new Point(p)); } return ps; } }