如何修复这个骑士的巡回算法?

时间:2012-05-15 12:27:51

标签: java algorithm

在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);
            }

}           
}
}

3 个答案:

答案 0 :(得分:1)

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场的改进。由于其他未访问的字段不能按顺序访问,因此无法以相同的方式进一步改进。

答案 1 :(得分:1)

对于骑士之旅(甚至在纸上)非常有效的旧启发式游戏总是跳到最受限制的广场,即骑士行动最少的地方。

如果有多个方格具有相同的限制,则随机选择其中一个。

事实证明,理论上你可以通过这条规则走向死胡同但通常(我认为它超过99%)它可以完成64次巡视。

答案 2 :(得分:0)

您创建一个方法,返回骑士所在的给定当前单元格的可能单元格列表,然后按ascending order中每个单元格作为候选项的元素数量排序。
递归调用将首先尝试具有lower number个候选者的单元格,并更快地获得解决方案。但是,对于完整的解决方案,您仍然需要探索整个搜索区域。