陷入无限循环(骑士之旅问题)

Posted

技术标签:

【中文标题】陷入无限循环(骑士之旅问题)【英文标题】:Stuck in an infinite loop (Knight's Tour Problem) 【发布时间】:2019-09-24 20:41:16 【问题描述】:

骑士之旅问题: 骑士被放置在空棋盘的第一个格子上,根据国际象棋规则走棋,他必须在每个格子里走一趟。打印路径,使其覆盖所有块。

无法理解为什么代码会陷入无限循环。浪费了几个小时仍然没有头绪。 我有解决方案,但不明白为什么这个特定代码不起作用。

#include<bits/stdc++.h>
using namespace std;
#define N 8

//possible moves
int rowMove[] = 2,1,-1,-2,-2,-1,1,2;
int colMove[] = 1,2,2,1,-1,-2,-2,-1;


void printBoard(vector<vector<int>> visited)

    for(int i=0; i<N; i++)
    
        for(int j=0;j<N;j++)
            cout<<visited[i][j]<<" ";
        cout<<endl;
    
    cout<<endl;


//check if the given move is valid
bool isValid(vector<vector<int>> visited,int row, int col)

    return (row>=0 && row<N && col>=0 && col<N && visited[row][col]==0);



bool solveKnight(vector<vector<int>> visited,int row, int col,int move)

    //printBoard(visited);
    if(move==N*N)
    
        printBoard(visited);
        return true;
    

    else
    
        for(int i=0;i<8;i++)
        
            int newRow = row + rowMove[i];
            int newCol = col + colMove[i];

            if(isValid(visited,newRow,newCol))
            
                move++;
                visited[newRow][newCol] = move;
                if(solveKnight(visited,newRow,newCol,move))
                    return true;
                move--;
                visited[newRow][newCol]=0;
            
        
    
    return false;



int main()

    vector<vector<int>> visited(N,vector<int>(N,0));
    visited[0][0]=1;
    if(!solveKnight(visited,0,0,1))
        cout<<"not possible";
    return 0;

【问题讨论】:

您是否尝试在每个执行步骤中使用调试器单步执行代码,同时调查变量的值? 哎呀。在递归的每一步,您都会进行 8 次递归调用。当你的递归深度达到 8*8 = 64 级时,你就停止了。这意味着您最终会收到 8^64 = 2^192 次对 solveKnight() 的调用。对我来说,它看起来不像无限循环。只是一个非常非常低效的算法。 没有进行全面审查,但这肯定是错误的:vector&lt;vector&lt;int&gt;&gt; visited。你想在这里参考。 @scohe001 类似代码但在 2 秒内给出结果:geeksforgeeks.org/the-knights-tour-problem-backtracking-1 完全不相关的旁注:要非常小心#include&lt;bits/stdc++.h&gt;(包括整个 C++ 标准库——你没有使用的很多 smurf)和 using namespace std;(有效地放置所有东西)的组合在全局命名空间中的标准命名空间中)。这会污染全局命名空间,把你的代码变成一个噩梦般的标识符地雷,让你绊倒。 【参考方案1】:

这里有两个问题:

    您正在复制 64-int 向量 every。单身的。时间。 您将 9 行打印到标准输出 每个。单身的。时间。

这两项都是极其昂贵的操作。你最多可以递归 8^64 = 2^192 次。这不是一个微不足道的数字。

如果你通过引用传递你的向量并在每个递归调用的开头杀死printBoard...中提琴! https://ideone.com/K0DU3q

【讨论】:

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

骑士之旅(回溯)

尝试使用 Swift 实现无限滚动时陷入无限循环

Knight's Tour 代码陷入无限循环,无法解决

蝗虫负载测试陷入无限循环

C合并排序陷入无限循环

为啥这个函数不会陷入无限循环? [复制]