C ++中矩阵两点之间的所有可能路径

时间:2017-06-02 13:15:21

标签: c++ algorithm recursion path iteration

给定NxM平面,找到两个点之间的所有可能路径,包括三个运动:右,下和对角线(右下,315º)。 Example

我坚持这个问题。我必须通过两种方式解决它:递归和迭代。对于迭代我有想法,但不知道如何实现它。

我的想法的描述是:

(谷歌翻译)。我们面对的是N列宽度和M行高度的板。我们必须从点(x1,y1)到达另一点(x2,y2),因此(xi,yj)不能分别大于N或M.移动的限制是我们只能向右移动(1),向右下方(2)和向下移动(3),每次移动我们在括号中分配数字。鉴于这些运动,我们意识到我们不能向左或向上,所以x1必须小于x2且y1必须大于y2。 该算法将从第一个点(x1,y1)开始,并尝试创建三个“子”,每个运动一个: 对(x1 + 1) 对角线(x1 + 1,y1-1) 向下(y1-1) 要接受的每个孩子的条件是那些已经说过的条件,x1< = N,y1< = M,x1< = x2,y1> = y2。

迭代将尝试从每个被接受的孩子中再创建3个孩子(每个动作一个)。

这个迭代的结尾是每个孩子的(x1,y1)等于(x2,y2)。

提前致谢。

2 个答案:

答案 0 :(得分:2)

迭代方法: 这可以通过memoization来解决,这意味着你可以跟踪no。在矩阵M中到达某个单元格的方法。

最初M[x][y] = 0 , for all x,y. b/w sx, dx and sy,dy respecitevly

<强>伪代码: 我们首先从源单元(sx,sy)开始,只有一种方法可以达到它,因此

sx,sy // source cell
dx,dy // destination cell
M[sx][sy] = 1 ;
for row x between sx, dx :
  for column y between sx, dy:
     if y-1 >= sy:
          M[x][y] += M[x][y-1] //  coming to x,y from left cell 
     if x-1 >= sx:
          M[x][y] += M[x][y-1] //  coming to x,y from top cell  
     if x-1 >= sx && y-1 >= sy:
          M[x][y]  += M[x-1][y-1] // coming from diagonal left cell.

答案是M [dx] [dy]。

递归方法: 采用与迭代方法相同的思想,也可以递归地实现:

Initially M[x][y] == -1: for all x b/w sx and dx , for all y b/w sy and dy

path( row, col )
 if row == dx && col == dy:
    return 1  
 if M[x][y] != -1: return M[x][y] // this means result for this is already calculated
 M[x][y] = 0                     
 if col+1 <= dy:
       M[row][col] += path(row, col+1)  // going right
 if row+1 <= dx:
       M[row][col] += path (row+1, col)  // going down
 if row+1 <= dx && col+1 <= dy: 
      M[row][col] += path(row+1, col+1) // going diagonally right

 return M[row][col]  

答案是M [sx] [sy]

答案 1 :(得分:0)

一个简单的递归解决方案是使用每个递归调用创建新的子代,例如

int foundSolutions = 0;
boolean pathExistsBetweenPoints(Point source, Point target, List<Point> previousPoints) {
    //Check if we're there yet
    if(source.x == target.x && source.y == target.y) {
        foundSolutions++;
        //Here you can display previousPoints if you want a possible solution
        return true; 
    }
    if(source.x > N || source.y > M || source.x > target.x || source.y > target.y)  {
        return false; //This trail is out of bounds
    }
    //Add this point to the list of points
    List<Point> newPoints = previousPoints.add(source);
    //Get the childpoints
    Point rightPoint = new Point(source.x, source.y + 1);
    Point diagonalPoint = new Point(source.x + 1, source.y + 1);
    Point downPoint = new Point(source.x + 1, source.y);
    //Check if any of the childs can reach the target
    boolean validPath = pathExistsBetweenPoints(rightPoint, target, previousPoints);
    validPath = validPath || pathExistsBetweenPoints(diagonalPoint, target, previousPoints);
    validPath = validPath || pathExistsBetweenPoints(downPoint, target, previousPoints);
    return validPath;
}

我不熟悉C ++语法,但这应该是可以翻译的