假设我们有一个大小为n*n
(n <10)的网格。我们必须从源(a,b)
迁移到目标(x,y)
。网格中填充0's and 1's
,其中0
表示允许路径,1
表示阻止路径。在每个步骤中,您可以对周围的8个网格中的任何一个进行chess piece king
s'移动,即。{/ p>
我必须从源头获得多种到达目的地的方法。如果你走一条路并向后追溯它,那就不要算了(否则路径的数量将是无限的)。即使我没有确切的数字,它的罚款但接近近似也是有效的(即如果它至少能给出一致的结果,即使是错误的想法也会受到赞赏)。
任何语言(最好是c ++,java)的任何想法,伪代码,片段都会有所帮助。
PS:如果解决方案对移动有限制(例如只有向右和向上和r / u对角线),但可以扩展到其他类似的约束,它也会有所帮助。
答案 0 :(得分:0)
通过从合并排序中借用这个想法,您可以尝试一种比DFS更高效的算法。
这个想法是标记一个区域,为它做一个详尽的搜索(另一个DFS),并标记进出的顶点对和为该区域做的方法的数量。这可以避免在同一区域一次又一次地遍历,从而导致复杂性。
然而,在10 * 10电路板上实现一个简洁的伪代码可能会很笨拙,因为它不是2的指数,但是用你喜欢的随机数切割电路板可以完成这项工作。
答案 1 :(得分:0)
由于您不想重复单元格(图形节点),您可以通过的大多数节点将是10x10,即100.
一个近似值可能是考虑通过它所有组合中的所有自由单元格。这将成为它(#free cells)!最多100个!但这可能是一个严重的高估。
更保守的方法,可能更接近实际数字是使用我们拥有的两个约束,100个节点和8个分支方向,并使其为8 ^ 100。这个数字每步近似分支8次,直到耗尽100个细胞(如果它们都是空的)。
略小的近似值不会自行回归,因此只有7个分支方向使其为7 ^ 100。这种近似估计7 ^(#自由单元格)。
考虑到分支估计的阻塞单元数量的更小的近似值可以将阻塞单元的百分比缩小7,即使用(7 x#free_cells / 100)^(#free_cells)。一旦被阻止的细胞数量达到足够接近(或小于)1的指数基数,这肯定会开始被低估。
您没有说明为什么要这个号码。希望这些方法能帮到你。
答案 2 :(得分:0)
如果您愿意接受无法导致循环的路线解决方案,您可以通过动态编程解决此问题。
例如,如果您只能向下,向右:
d[i, j] = number of ways of reaching [i, j] from [1, 1]
我们有:
d[1, 1] = 1
d[i, j] = d[i - 1, j] + <- move down from (i - 1, j) to (i, j)
d[i, j - 1] <- move right from (i, j - 1) to (i, j)
注意:请务必忽略无效索引。
要仅从(a, b)
移至(x, y)
,您可以设想将d
的左上角设置为(a, b)
,然后计算到d[x - a + 1, y - b + 1]
。
要处理被阻止的单元格,只需将d
设置为0
作为其位置。
这很容易扩展到不会导致循环的其他动作对(或三元组)。你可以通过旋转矩阵并做同样的事情,或者稍微调整公式来做到这一点。
例如,对于向上和向右,您必须:
d[i, j] = d[i + 1, j] + d[i, j - 1]
您需要通过从下到上迭代行来计算,而不是通常的从上到下。
请注意,某些方向对与其他方向相同:例如,向上和向左的答案与向下<的答案相同/ strong>和正确。