【问题标题】:Knights tour backtracking lasts too long骑士巡回赛回溯持续时间过长
【发布时间】:2013-12-26 11:04:27
【问题描述】:

在 8x8 板上使用回溯解决骑士巡回赛问题需要多长时间?因为我的算法已经以某种方式计算得太长了,而且看起来,它不会完成。但是当我尝试 6x6 或 5x5 板时,它成功完成。

代码:

class KnightsTour{

private boolean[][] board;
private int count, places;
private static final Point[] moves = new Point[]{
    new Point(-2, -1),
    new Point(-2, 1),
    new Point(2, -1),
    new Point(2, 1),
    new Point(-1, -2),
    new Point(-1, 2),
    new Point(1, -2),
    new Point(1, 2)
};

public KnightsTour(int n) {
    board = new boolean[n][n];
    places = n*n;
    count = 0;
     }

public boolean ride(int x, int y) {
    
    
    board[x][y] = true;
    count++;
    
    if (count == places) {
        return true;
    }

    for (Point p : moves) {
        int nextX = x + p.x;
        int nextY = y + p.y;

        if (nextX < 0 || nextX >= board.length || nextY < 0 || nextY >= board.length || board[nextX][nextY]) {
            continue;
        } 
        if (ride(nextX, nextY)) {
            return true;
        }
    }
    
    board[x][y] = false;
    count--;
    
    return false;
}
}

【问题讨论】:

  • 你不妨修复pole -> boardplaces/spaces
  • 您可以做的一件事是计算每个电路板尺寸(4、5、6、7)调用ride() 的次数,然后查看它的增长情况。这可能会给您深度优先搜索与棋盘大小的时间复杂度的粗略概念。考虑到您必须搜索的状态空间的大小,难怪需要这么长时间才能完成......

标签: java time-complexity recursive-backtracking knights-tour


【解决方案1】:

我遇到了同样的问题。一切都运行顺利,直到 n=7,突然间计算n=8 需要很长时间。我希望这对某人有帮助:)

问题在于您检查移动的顺序。您正在使用:

xMove[8] = { -2, -2, 2, 2, -1, -1, 1, 1}

yMove[8] = { -1, 1, -1, 1, -2, 2, -2, 2}

如果您在 2D 平面中绘制这些向量,它们的放置是随意的。换句话说,它们不是以顺时针或逆时针方式排列的。考虑一下这个:

xMove[8] = { 2, 1, -1, -2, -2, -1, 1, 2 }

yMove[8] = { 1, 2, 2, 1, -1, -2, -2, -1 }

如果您绘制这些向量,它们会整齐地排列成逆时针圆圈。 不知何故,这导致递归对于n 的大值运行得非常快。请注意,从 n=9 开始计算仍然需要很长时间。

【讨论】:

  • 令人惊讶的是,正如作者所描述的那样,该解决方案有效(对于 n = 7、8 和 9)。任何人都可以解释为什么会发生这种情况吗?分支预测?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-04
  • 1970-01-01
  • 2019-07-15
  • 1970-01-01
  • 2014-01-12
相关资源
最近更新 更多