【问题标题】:Number of paths in a matrix矩阵中的路径数
【发布时间】:2012-11-24 13:08:36
【问题描述】:

给定一个p x q 大小的矩阵,并从右上角删除一个大小为a x b 的矩阵。找到总数。从左上角到右下角的路径,只允许向右和向下移动。任何路径都不应进入已移除的矩阵。

例如-

 _
|_|_
|_|_|

这是从右上角删除(1x1) 矩阵后的(2x2) 矩阵。不。方法 - 5.

我能够找出路径的总数,但我正在考虑消除进入已删除部分的路径的方法非常基本,因此效率不高。

那么,有没有更好的算法呢?

【问题讨论】:

  • 想一个一般的有向无环图。如果您有图形的拓扑排序,则顶点数有一个线性时间算法。这转化为矩阵大小的二次算法。
  • 您在寻找组合(数学)解决方案还是算法解决方案?请注意,表示您的矩阵的图是一个 DAG,因此如果您正在寻找算法解决方案,可能应该使用它。
  • 这可以在网格大小的线性时间内解决(假设为常数时间数学)。
  • “比什么更好”?您声称已经能够找到路径的总数。请在问题中发布如何。
  • 我开发了一个数学解决方案,它涉及从所有可能点进入已删除路径并从所有可能点出来的所有路径的总和。

标签: algorithm math combinatorics


【解决方案1】:

您可以利用网格的结构:

正方形网格上从一个角到另一个角的路径数由帕斯卡三角形的网格大小给出:(x+y) choose x

每条路径必须恰好穿过每条对角线上的一个点。

取对角线上通过内角的所有点,计算通过每个点的路径数,然后求和。

这导致O(min(p-a, q-b)) 算法假设恒定时间算术。

在您的情况下:(到中心的两条路径)*(从中心的两条路径)+(通过拐角的一条路径)=(通过中心的四条路径)+(通过拐角的一条路径)=(五条路径)

+-+-+
| | |
+-+-A-+-+
| | | | |
+-B-+-+-+
| | | | |
C-+-+-+-+
| | | | |
+-+-+-+-+

  (1+2) choose 1 * (2+3) choose 2 (through A)
+ (2+1) choose 2 * (3+2) choose 3 (through B)
+ (3+0) choose 3 * (4+1) choose 4 (through C)

= 3 choose 1 * 5 choose 2
+ 3 choose 2 * 5 choose 3
+ 3 choose 3 * 5 choose 4

= 3*10
+ 3*10
+ 1*5

= 30+30+5 = 65 paths

【讨论】:

  • 我也开发了它并得到了类似的解决方案,将结果求和:对于 [0,q-a] chose(i+b,q-a) * chose(q-a+p-b,p-b) 中的每个 i。 (到达q-a * p-b 矩形中最低行中每个正方形的方法数乘以从正方形到末端的路径数)。当然,两者都是有效的。
  • @amit 你确定你不会得到重复的路径吗?
  • @acbruptenda 现在呢?
  • @JanDvorak: 肯定的,这些是不同的路径,总和中的每个“元素”都是i“正确”的步骤,直到某个(定义明确的)行,对于不同的is 你必须得到不同的路径,乘以从广场到它到尽头的不同路径
  • @amit 如果你走i 正确的步骤,下一步必须向下,否则你实际上做了i+1 正确的步骤。你对此负责吗?
【解决方案2】:

在代表问题的DAG1 上执行topological sort

然后从最后一个(sink)迭代到第一个(source):

f(v) = Sum(f(u)) for each (v,u) in E
base: f(sink) = 1

复杂性与图的大小成线性关系(每个顶点只迭代一次)(使用矩阵的维度是O(p*q-a*b)


(1) 图 G=(V,E) 为:

V = { (i,j) | for each i,j in the matrix that was not deleted }
E = { ((i1,j1),(i2,j2)) | (i1,j1) is to the left/up of (i2,j2) }

【讨论】:

    【解决方案3】:
    //assume we are moving from m,n to 1,1
    int  numberOfPaths(int m, int n)
    {
    /*If the m,n  is left-bordered to the removed matrix, then move only downwards 
      till the end of removed matrix,then we can move in two directions*/
     //l1=numberOfrows(bigMatrix)-numberOfRows(smallMatrix), similarly l2 for columns
     if(m==l1&&n>=l2)
       return numberOfPaths(l1-1,l2+2)+numberOfPaths(l1,l2+1);
    // If either given row number is first or given column number is first
    if (m == 1 || n == 1)
        return 1;
    
     return  numberOfPaths(m-1, n) + numberOfPaths(m, n-1); 
    }
    

    【讨论】:

      猜你喜欢
      • 2017-12-20
      • 2015-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-25
      • 2014-08-28
      相关资源
      最近更新 更多