通过4x4网格查找所有路径

时间:2013-11-10 11:19:37

标签: c++ algorithm recursion graph big-o

你如何解决这个问题::

机器人位于4x4网格的左上角。机器人可以向上,向下,向左或向右移动,但不能两次访问同一地点。机器人正试图到达网格的右下角。

我的想法:

回溯解决方案,我们遍历所有解决方案的树,并在达到目标单元格后打印。我实现了这个,但我不确定它是正确的还是有意义的,或者它是否是正确的方法。我在这里发布了代码,如果有人能解释它的错误,我会非常感激。

递归解决方案,我从起始单元格开始,并递归地从每个相邻单元格中找到目标单元格的路径,基本情况是命中目标单元格。

问题:

1)这两种表达方式是否相同?

2)这些想法是否有意义?

3)每种解决方案的时间复杂度是多少?我认为第二个是4 ^ n?

4)我的回溯代码是否有意义?

5)有更简单的方法吗?

这是我的代码,它打印N = 4的正确路径数。是否正确?

#define N 4
int counter = 0;
bool legal_move(int x, int y, int array[N+2][N+2]){
  bool ret = (array[x][y] == 1);
  array[x][y] = 0;
  return ret;
}

/*
void print_array(int array[N+2][N+2]){
  for(int i = 0; i < N+2; i++){
    for(int j = 0; j < N+2; j++)
      cout << array[i][j] << " ";
    cout << endl;
  }
  cout << endl << endl;
}
*/

void print_paths(int x, int y, int n, int m, int array[N+2][N+2]){
  if(x == n && y == m){
    print_array(array);
    counter++;
  }
  else {
    int dx = 1;
    int dy = 0;
    for(int i = 0; i < 4; i++){
      if(legal_move(x + dx, y + dy, array)){
        print_paths(x + dx, y + dy, n, m, array);
        array[x+dx][y+dy] = 1;
      }
      swap(dx,dy);
      if(i == 1)
        dx = -dx;
    }
  }
}

int main(){

  int array[N+2][N+2];

  for(int i = 1; i < N+1; i++)
    for(int j = 1; j < N+1; j++)
      array[i][j] = 1;

  for(int i = 0; i < N+2; i++)
    array[0][i] = array[i][0] = array[N+1][i] = array[i][N+1] = 0;

//print_array(array);
  array[1][1] = 0;  //Set start cell to be seen.
  print_paths(1,1,N,N,array);
  cout << counter << endl;
}

2 个答案:

答案 0 :(得分:1)

我认为这是一样的想法。

您的代码存在的问题是您没有正确实施“但不能两次访问同一地点”。

假设您的机器人已经通过某种路径从S到A,并且您现在正在检查是否要转到与A相邻的B.测试应该是'机器人在当前路径之前到过B ”。但你所实现的是“机器人在任何路径之前访问过B”。

换句话说,您需要修改print_paths以为当前路径获取额外参数,并使用它来正确实现测试。

答案 1 :(得分:1)

这是一个部分答案,主要讨论复杂性(我认为你的代码是正确的,在john建议的小错误修正之后,回溯可能是你想做的最简单的方法)。

对我来说,时间复杂度似乎与O(3^n^2)类似 - 最多有n^2个节点,并且在每个节点上要检查3种可能性。实际上有更少的节点,因为回溯的工作方式,但复杂性至少 O(2^(n^2/4)),所以它比任何指数都大。 (最后一个公式中的O实际上是theta)。

下图描述了这个下限。由?标记的单元格中有一个“决定” - 机器人可能决定直行或转弯。至少有n^2/4个此类单元格,因此路径数量至少为2^(n^2/4)

?->-?->-?->-V
| | | | | | |
>-^ >-^ >-^ V
            |
V-<-?-<-?-<-?
| | | | | | |
V ^-< ^-< ^-<
|
...