Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 递归回溯算法不能解决某些情况_Java_Algorithm_Recursion_Backtracking_Recursive Backtracking - Fatal编程技术网

Java 递归回溯算法不能解决某些情况

Java 递归回溯算法不能解决某些情况,java,algorithm,recursion,backtracking,recursive-backtracking,Java,Algorithm,Recursion,Backtracking,Recursive Backtracking,我目前正在编程一个递归算法来解决一个假摔接龙游戏 该算法需要使用“回溯”方法来求解电路板。我想我已经找到了一个非常接近正确的解决方案。似乎我的代码正确地解决了所有可解板的问题。它似乎也能正确地确定什么时候一块板是不可解的,但只有当钉子的数目不是太多的时候 我的递归方法如下所示: public static void solve() { if(isSolved()) { long endTime=System.currentTimeMillis();

我目前正在编程一个递归算法来解决一个假摔接龙游戏

该算法需要使用“回溯”方法来求解电路板。我想我已经找到了一个非常接近正确的解决方案。似乎我的代码正确地解决了所有可解板的问题。它似乎也能正确地确定什么时候一块板是不可解的,但只有当钉子的数目不是太多的时候

我的递归方法如下所示:

public static void solve()
{
    if(isSolved())
    {
        long endTime=System.currentTimeMillis();
        System.out.println("Solved");
        solved=true;
        printArr(board);

    }
    else
    {
            for(int i=0;i<7;i++)
            {
                for(int j=0;j<7;j++)
                {
                    for (int k=0;k<4;k++)
                    {
                        if(makeMove(new int[]{i,j,k}))
                        {
                            if(solved!=true)
                            {
                                solve();
                                undoMove();
                            }
                        }


                    }
                }
            }
        }
    }
publicstaticvoidsolve()
{
if(isSolved())
{
long-endTime=System.currentTimeMillis();
系统输出打印项次(“已解决”);
已解决=正确;
printArr(董事会);
}
其他的
{

对于(int i=0;i,由于peg纸牌中的每一个移动都会移除一个peg,所以你不可能回到以前的状态:比如说,在简单的路径规划中,机器人可能永远在两个正方形之间来回移动。所以不是这样

那么,您的算法错了吗?为简单起见,将其简化为:

solve (board state) is

if the board is solved, record success
else
   for all possible moves from this board state
      if move is possible
        make it
        call solve
        undo the move
这个算法不可能让你陷入循环;当它递归时,它会深入搜索空间(也就是说,它会移动)。所以这不是问题所在

您可能在一些未显示的函数(makemove、undomove)中出错。如果makemove不起任何作用,则无论问题的大小,您的程序都不会结束

然后我会得出结论,问题是一个非常大的搜索问题可能需要很长时间。你可以利用问题的大小。如果它对大小为N的问题有效,它对大小为N+1的问题有效吗?花几秒钟来解决大小为N的问题表明你可以忘记让它解决N+10的问题(我说,基于类似问题的经验):这不仅仅是因为这是一个指数问题,而是因为当系统试图获得足够的内存时,您可能会受到冲击

有时,一个解决方案是跟踪您已经尝试过的节点,以减少冗余搜索。我怀疑您在这个问题上不会得到太多帮助--您无法保存访问状态的列表(这将需要指数内存),并且保留前几个级别访问过的州的列表不会将搜索的深度扩大那么多


这一切都有助于其他人得出的结论:这只是一个大问题。

您的算法是否可能只需要很长时间,或者执行两个不会改变游戏状态的移动?即将卡a移动到堆栈B,然后将其移回?您是否可以将日志添加到不同的步骤中,以查看它进入无限loo的位置p?@MrHug从技术上讲,该算法尝试到已解决电路板的每一条“路径”,直到找到其中一条,或者特定的“路径”到达无法解决的电路板,在这一点上,递归的一系列方法调用终止,并撤销移动()调用。然后该过程从板上的下一个可用点开始重复,因此我看不出它是如何被卡住的。@KurtDuBois,我尝试过类似的方法,但由于板不断变化,日志记录似乎毫无用处(事实上,我所有的可解板卡在到达解决方案之前通常都会进行300000次以上的撤销调用,因此很难识别无限循环。你能显示完整的代码吗?试一下板卡大小为7*7*4的每种排列都是
(7*7*4)!
,这是非常巨大的