[英]How can this knight's tour algorithm be fixed?
在8X8棋盤中,只考慮馬,如果我們從棋盤的任何一個方格開始馬,目標是覆蓋最多的方格,不重復任何一個方格。 到目前為止,我發現下面的代碼最有效的解決方案是:
60 29 34 49 0 15 46 0
35 50 1 16 45 48 11 0
30 59 28 33 2 9 14 47
51 36 31 44 17 12 3 10
58 43 52 27 32 25 8 13
37 40 55 18 23 6 21 4
42 57 38 53 26 19 24 7
39 54 41 56 0 22 5 20
其中以 1 開頭的數字表示騎士所遵循的路徑。 我的問題是可以更正此代碼以獲得 64(我的僅達到 60)的完美答案嗎?
package game;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Knight {
static int board[][]=new int[8][8];
static int value=1;
public static void zero()
{
for(int i=0;i<7;i++)
for(int j=0;j<7;j++)
board[i][j]=0;
}
public static void knightpos(int x,int y)throws IOException
{
if(value==61)
{ System.out.println();
for(int i=0;i<8;i++)
{
System.out.println();
System.out.println();
for(int j=0;j<8;j++)
System.out.print(" "+board[i][j]);
}
System.exit(0);
}
if(x+1<=7&&y+2<=7)
{
if(board[x+1][y+2]==0)
{ board[x+1][y+2]=value++;
knightpos(x+1,y+2);
}
}
if(x+2<=7&&y+1<=7)
{
if(board[x+2][y+1]==0)
{
board[x+2][y+1]=value++;
knightpos(x+2,y+1);
}
}
if(x-2>=0&&y-1>=0)
{
if(board[x-2][y-1]==0)
{board[x-2][y-1]=value++;
knightpos(x-2,y-1);
}
}
if(x+2<=7&&y-1>=0)
{
if(board[x+2][y-1]==0)
{board[x+2][y-1]=value++;
knightpos(x+2,y-1);
}
}
if(x+1<=7&&y-2>=0)
{
if(board[x+1][y-2]==0)
{board[x+1][y-2]=value++;
knightpos(x+1,y-2);}
}
if(x-1>=0&&y-2>=0)
{
if(board[x-1][y-2]==0)
{board[x-1][y-2]=value++;
knightpos(x-1,y-2);}
}
if(x-2>=0&&y+1<=7)
{
if(board[x-2][y+1]==0)
{board[x-2][y+1]=value++;
knightpos(x-2,y+1);}
}
if(x-1>=0&&y+2<=7)
{
if(board[x-1][y+2]==0)
{board[x-1][y+2]=value++;
knightpos(x-1,y+2);}
}
board[x][y]=0;
value--;
return;
}
public static boolean chk() {
for(int i=0;i<7;i++)
for(int j=0;j<7;j++)
if(board[i][j]==0)
return false;
return true;
}
public static void main(String args[])throws IOException
{
InputStreamReader ir = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(ir);
System.out.println("Knight chess game input x,y position ");
int x=Integer.parseInt(br.readLine());
int y=Integer.parseInt(br.readLine());
{
if(!chk())
{
zero();
value=1;
knightpos(x,y);
}
}
}
}
60 29 34 49 0 15 46 0
35 50 1 16 45 48 11 0
30 59 28 33 2 9 14 47
51 36 31 44 17 12 3 10
58 43 52 27 32 25 8 13
37 40 55 18 23 6 21 4
42 57 38 53 26 19 24 7
39 54 41 56 0 22 5 20
如果您查看您的解決方案,您可以分支到零的第一步是第 3 步。作為附加信息,我們看到,您可以再次從 60 跳到 1,構建一個循環(但您不能,因為你不能兩次訪問一個地方。
但是如果你從 4 開始,你可以移動到 60,從那里到 1、2、3,現在你可以訪問零字段之一。
但是,這只是 1 個字段的改進。 由於其他未訪問的字段無法按順序訪問,因此無法以相同的方式進一步改進。
一個非常適合騎士之旅(即使在紙上)的古老啟發式方法總是跳轉到最受限制的方格,這是騎士移動最少的地方。
如果有多個具有相同限制的方格,則隨機選擇其中之一。
事實證明,您理論上可以使用此規則進入死胡同,但通常(我認為超過 99%)它適用於完整的 64 次巡回演出。
您創建了一個方法,該方法返回騎士所在的給定當前單元格的可能單元格列表,然后按照每個單元格將作為候選的元素數量ascending order
。
遞歸調用將首先嘗試那些候選lower number
的單元格,並更快地找到解決方案。 不過,對於全套解決方案,您仍然需要探索整個搜索區域。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.