骑士';s-tour递归方法Java
我试图递归地实现骑士之旅。。下面是我的代码。 为了简单起见,我选择了5x5的电路板。我的目标是打印出正确的骑士位置,并可能在打印语句的同时显示回溯骑士';s-tour递归方法Java,java,recursion,Java,Recursion,我试图递归地实现骑士之旅。。下面是我的代码。 为了简单起见,我选择了5x5的电路板。我的目标是打印出正确的骑士位置,并可能在打印语句的同时显示回溯 class Knight { public boolean[][] board = new boolean[5][5]; public final int SQUARES = 5*5-1; public Knight() { for(int i=0;i<5;i++) for(int j=0;j<5;j++)
class Knight
{
public boolean[][] board = new boolean[5][5];
public final int SQUARES = 5*5-1;
public Knight()
{
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
board[i][j] = false;
}
public boolean tour(int x, int y, int visitedX, int visitedY,int n)// x,y coords, just visited x,y and counter n
{
if(x>=5||y>=5||x<0||y<0){ //out of bounds
System.out.println("Visited "+x+", "+y+" Out of bounds");
System.out.println("Back to "+visitedX+", "+visitedY);
return false;
}
else{
if(board[x][y] == true)
{return false;}
if(board[x][y]!=true){
boolean result = false;
board[x][y]=true;
System.out.println("Visited "+x+", "+y);
result = tour(x+2,y+1,x,y,n+1);
result = tour(x+2,y-1,x,y,n+1);
result = tour(x+1,y-2,x,y,n+1);
result = tour(x-1,y-2,x,y,n+1);
result = tour(x+1,y+2,x,y,n+1);
result = tour(x-1,y+2,x,y,n+1);
result = tour(x-2,y-1,x,y,n+1);
result = tour(x-2,y+1,x,y,n+1);
}
}
return false;
}
}
public class KnightTApp {
public static void main(String[] args) {
Knight k = new Knight();
k.tour(0,0,0,0,0);
}
}
我的问题是在这个过程的中间,我遇到了一个死胡同的情况(不是所有的方格都被覆盖,但是在我的索引中没有合法的动作)。因为我没有包含任何用于回溯的行。它只是跳到索引2,0,这甚至不是一个合法的骑士移动
我的问题是,如何用if语句表达一种“死胡同”?我想我应该把递归设置成某种布尔值,然后从那里开始,但我不知道怎么做
使用递归是否与使用DFS(深度优先搜索)相同,因为它们基本上有相同的想法
先谢谢你 您可能希望使用堆栈数据结构,并在每次移动时评估所有可能的有效移动,将每个移动推到堆栈上。进行有效移动时,将其从堆栈中弹出
当您的evaluate方法返回0个可能的移动时,可能会出现死胡同。您可能希望使用堆栈数据结构,并在每次移动时评估所有可能的有效移动,将每个移动推到堆栈上。进行有效移动时,将其从堆栈中弹出
当您的evaluate方法返回0个可能的移动时,就会出现死路一条。您需要弄清楚是否正在尝试识别所有可能的移动 或者只是为了找到一个有效的旅行 要获得完整的回溯,您需要在返回调用方时,在巡更结束时再次将board字段标记为空闲 其次,您需要检查
tour()
上每个递归调用的结果。
如果为true,则找到一个有效的星座,也可以返回true。
否则,尝试下一步可能的行动。如果没有向左移动,返回false
最后,您缺少一个适当的终止条件:“什么是成功?”
在您的情况下,如果5x5
成功移动,则所有字段都已访问,您可以返回true
表示成功
您可能还希望跟踪移动的顺序,以便有机会输出成功的巡演
以上内容旨在确定一次成功的旅行。通过跟踪移动序列,您可以跟踪所有成功的巡更,而不是在最深的递归中返回true。检查已知巡更,如果是新的巡更,则返回true 请参考修改后的代码版本,添加“查找任何”部分:
职业骑士{
公共最终静态整数大小=5;
公共布尔值[][]板=新布尔值[SIZE][SIZE];
公共字符串[]移动=新字符串[大小*大小];
公共骑士(){
对于(int i=0;i<5;i++){
对于(int j=0;j<5;j++){
董事会[i][j]=虚假;
}
}
}
公共布尔巡更(最终整数x、最终整数y、最终整数n)
{
如果(n>=大小*大小){
返回true;
}如果(x>=5 | | y>=5 | | x<0 | | y<0){//越界
返回false;
}否则,如果(板[x][y]){
返回false;
}否则{
//System.out.println(“检查“+n+”:“+x+”,“+y”);
董事会[x][y]=正确;
移动[n]=x+“-”+y;
如果(巡更(x+2,y+1,n+1)){
返回true;
}
如果(巡更(x+2,y-1,n+1)){
返回true;
}
如果(巡更(x+1,y-2,n+1)){
返回true;
}
if(巡更(x-1,y-2,n+1)){
返回true;
}
如果(巡更(x+1,y+2,n+1)){
返回true;
}
如果(巡更(x-1,y+2,n+1)){
返回true;
}
如果(巡更(x-2,y-1,n+1)){
返回true;
}
if(巡更(x-2,y+1,n+1)){
返回true;
}
板[x][y]=假;
移动[n]=null;
返回false;
}
}
公共静态void main(最终字符串[]args){
最终骑士k=新骑士();
对于(int i=0;i
您需要弄清楚您是否正在尝试确定所有可能的旅行
或者只是为了找到一个有效的旅行
要获得完整的回溯,您需要在返回调用方时,在巡更结束时再次将board字段标记为空闲
其次,您需要检查tour()
上每个递归调用的结果。
如果为true,则找到一个有效的星座,也可以返回true。
否则,尝试下一步可能的行动。如果没有向左移动,返回false
最后,您缺少一个适当的终止条件:“什么是成功?”
在您的情况下,如果5x5
成功移动,则所有字段都已访问,您可以返回true
表示成功
您可能还希望跟踪移动的顺序,以便有机会输出成功的巡演
以上内容旨在确定一次成功的旅行。通过跟踪移动顺序,您可以跟踪所有成功的旅行,而不是ju
Visited 4, 0
Visited 6, 1 Out of bounds
Back to 4, 0
Visited 6, -1 Out of bounds
Back to 4, 0
Visited 5, -2 Out of bounds
Back to 4, 0
Visited 3, -2 Out of bounds
Back to 4, 0
Visited 5, 2 Out of bounds
Back to 4, 0
Visited 2, -1 Out of bounds
Back to 4, 0
Visited 2, 0
class Knight {
public final static int SIZE = 5;
public boolean[][] board = new boolean[SIZE][SIZE];
public String[] moves = new String[SIZE * SIZE];
public Knight() {
for (int i = 0; i < 5; i++ ) {
for (int j = 0; j < 5; j++ ) {
board[i][j] = false;
}
}
}
public boolean tour(final int x, final int y, final int n)
{
if (n >= SIZE * SIZE) {
return true;
} else if (x >= 5 || y >= 5 || x < 0 || y < 0) { // out of bounds
return false;
} else if (board[x][y]) {
return false;
} else {
// System.out.println("Checking " + n + ": " + x + "," + y);
board[x][y] = true;
moves[n] = x + "-" + y;
if (tour(x + 2, y + 1, n + 1)) {
return true;
}
if (tour(x + 2, y - 1, n + 1)) {
return true;
}
if (tour(x + 1, y - 2, n + 1)) {
return true;
}
if (tour(x - 1, y - 2, n + 1)) {
return true;
}
if (tour(x + 1, y + 2, n + 1)) {
return true;
}
if (tour(x - 1, y + 2, n + 1)) {
return true;
}
if (tour(x - 2, y - 1, n + 1)) {
return true;
}
if (tour(x - 2, y + 1, n + 1)) {
return true;
}
board[x][y] = false;
moves[n] = null;
return false;
}
}
public static void main(final String[] args) {
final Knight k = new Knight();
for (int i = 0; i < SIZE; i++ ) {
System.out.println("Starting at " + i + " 0");
if (k.tour(i, 0, 0)) {
k.printTour(true);
break;
}
k.printTour(true);
}
}
/**
* @param result
*/
private void printTour(final boolean result) {
System.out.println("Found tour: " + result);
int i = 0;
if (result) {
for (final String m : moves) {
System.out.println("M-" + i + ": " + moves[i]);
i++ ;
}
}
}
}