【问题标题】:Knight's tour problem compilation doesn't end骑士之旅问题编译没有结束
【发布时间】:2021-07-18 14:53:12
【问题描述】:

谁能指出代码中的缺陷? 我使用的想法是递归回溯,我想坚持这种解决给定问题的方式。当变量 move

//checking on which move was the square visited
int board[8][8] = {{1,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}};
int x = 0;//x and y coordinate of the knight's placement
int y = 0;
//move knight by
int move_to[8][8] = {{1,2},{-1,-2},{-1,2},{1,-2},{2,1},{-2,-1},{-2,1},{2,-1}};
//how many moves have been done
int moves = 0;

void solve()
{
    //printing one solution
    if(moves==63)
    {
        for(int k = 0; k < 8; k++)
        {
            for(int n = 0; n < 8; n++)
                cout << setw(2) << board[k][n] << " ";
            cout << "\n";
        }
        cout << "--------------------\n";
        return;
    }
    else
    {
     for(int i = 0; i < 8; i++)
    {
        //checking if knight is not leaving the board
        if(x+move_to[i][0]<0 || x+move_to[i][0]>7 || y+move_to[i][1]<0 ||
            y+move_to[i][1]>7 || board[x+move_to[i][0]][y+move_to[i][1]]>0)
            continue;
        //moving theknight
        x+=move_to[i][0];
        y+=move_to[i][1];
        //increasing the moves count
        moves++;
        //marking the square to be visited
        board[x][y] = moves+1;
        //backtracking
        solve();
        board[x][y] = 0;
        x-=move_to[i][0];
        y-=move_to[i][1];
        moves--;
    }
    }
}

int main()
{
    solve();

    return 0;
}

【问题讨论】:

  • 没有完成编译或者没有完成运行?
  • cmd.exe 在打印了几个解决方案后,打印了 '_' 所以,我认为这意味着 - 没有完成运行就是我的意思;D。会解决的。
  • 编译的时候有没有开启优化?
  • 你需要添加一个启发式来使这个计算可行,我似乎记得你应该移动到一个被已经访问过的正方形包围的正方形。
  • Ehm,在选择下一步时排除前一个方格是否有意义?如果没有,则无限循环。

标签: c++ algorithm recursion backtracking knights-tour


【解决方案1】:

我记得学习中的这个问题。我没有修复它们,但我改变了初始位置,然后更快地找到了第一条路径(这就是我通过这个实验室的方式;P)。这很正常,因为 路径数太大。

但你可以:

  • 从 move_to 中随机选择
  • 使用多个线程

另一方面,您可以阅读“约束编程”

【讨论】:

  • 我想以左上角为起点来解决问题,也许以后再推广。我看不出以随机顺序使用 move_to 如何使程序更快。至于“多线程”部分,你的意思是 CPU 中的踏板,对吗?
  • 增加概率,您将平均获得解决方案的时间。添加多个线程您可以同时找到多个路径,但您的代码不是线程保存的。您也可以在存在不可用字段时添加约束(例如:字段 [0][7] 未访问,但 [1][5] 和 [2][6] 是。您的程序永远找不到 [0][7] 的路径] 但路径将继续被搜索)。
  • 我不想完全靠运气,我只想让算法高效。我已经运行了打印移动 = 60 的解决方案的代码,确实从未访问过正方形 [0][7],但我不明白你的推理。你能详细说明一下吗?
  • 您无法实时搜索每条路径。 {{-2,-1},{2,-1},{-2,1},{2,1},{-1,-2},{1,-2},{-1,2} ,{1,2}} - 尝试使用该 move_to 数组。通过增加概率,您可以避免不幸的移动顺序。约束 - 您不能打印少于 64 条的方式。当前的移动是 { {1,X,0,...,0}, {0,0,0,3,0,...,0} , {5,2,7,0,...,0}, {8,0,4,0,...,0}, ... } X 字段不可用,但您的程序仍可使用此字段路径。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-12
相关资源
最近更新 更多