骑士之旅(回溯)

Posted

技术标签:

【中文标题】骑士之旅(回溯)【英文标题】:Knight tour (backtrack) 【发布时间】:2014-03-15 16:50:27 【问题描述】:

我正在尝试用 8*8 棋盘解决骑士的巡回赛问题。但是我的回溯是无限循环的。我的逻辑函数如下:-

N 是 8。

  boolean algo(int x,int y,int no_of_moves,int sol[][])

        if(no_of_moves==N*N)
            return true;
        

        int nextx;
        int nexty;
        for(int i=0;i<8;i++)

            nextx=x+move_x[i];
            nexty=y+move_y[i];

            if(is_valid(nextx,nexty))
                sol[nextx][nexty]=no_of_moves;

                if(algo(nextx,nexty,no_of_moves+1,sol))
                    return true;
                
                else
                    sol[nextx][nexty]=-1;

            
        
        return false;  
    

sol [][] 存储骑士的动作。

数组 move_x 和 move_y 存储要添加到 x 和 y 以获得骑士的下一个位置的值。

 int move_x[]=  2, 1, -1, -2, -2, -1,  1,  2 ;
    int move_y[]=  1, 2,  2,  1, -1, -2, -2, -1 ;

我首先将 x 作为 0,y 作为 0,no_of_moves 作为 1,并将 sol[][] 中的所有值作为 -1 除了 sol[0][0] 为 0。

然后is_valid() 检查nextxnexty 是否在棋盘内并且尚未访问。

boolean is_valid(int xnext,int ynext)
    
        if(xnext>=0 && xnext<N && ynext>=0 && ynext<N && sol[xnext][ynext]==-1)
         
            return true;
        
        else 
        
            return false; 
        
    

【问题讨论】:

我很确定它不是无限的。它更像 number_of_moves^(N*N)。你确定你检查你是否已经正确地访问了这个领域?最简单的方法是在非常小的板上运行它,比如 3x3,然后检查它是否真的结束了。 您可能希望在问题中包含您的 is_valid() 方法,以防出现问题。 boolean is_valid(int xnext,int ynext) if(xnext>=0&&xnext=0&&ynext 【参考方案1】:

我看不出代码有什么问题。我怀疑它不会进入一个无限循环,而是进入一个需要很长时间的循环。

查看它是否适用于 5x5 板 (animation)。

【讨论】:

我把 System.out.println(no_of_moves);看看它卡在哪里,它显示为:-52 50 51 52 52 53 52 51 52 53 50 51 51 48 49 50 51 52 53 54 55 ...表示卡在50年代 @user3423663:但这并不能证明什么,不是吗?还是我在这里错过了你的观点? 不,我只是说它真的进入了无限循环,时间不长。好吧,我会尝试再次查看我的完整代码,但我真的不知道它是如何发生的。跨度> @user3423663:我仍然不理解你为什么认为循环是无限的,但我将把它留在那里。 你是对的@NPE。它不是无限的,它需要非常非常长的时间。 5*5 用了 5 秒,6*6 棋盘用了 14 秒,8*8 用了 13 多分钟,仍然没有解决方案。谢谢。那么我应该使用哪种算法?【参考方案2】:

我看到你在那里使用蛮力,但这不足以在合理的时间内解决这个问题。如果没有优化,复杂度将为O(N^(N*N))(N 是板尺寸)。因此,找到第一个解决方案可能真的需要很长时间。这就是为什么你认为它处于无限循环中。

最有效的优化是Warnsdorff's rule,它于 1823 年首次发布。它是一种简单的启发式规则,可让您在第一次尝试时(立即)找到解决方案。

【讨论】:

以上是关于骑士之旅(回溯)的主要内容,如果未能解决你的问题,请参考以下文章

c_cpp 骑士之旅(回溯)

c ++中的递归回溯骑士之旅

我正在使用回溯解决骑士之旅问题,但我没有得到想要的结果

骑士之旅 - 导致无限循环,我不知道为啥

骑士之旅蛮力

平行骑士之旅算法