簡體   English   中英

這個騎士的巡演算法怎么修?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM