Python 矩阵中的最小迭代次数,其中单元值在单个迭代中被相邻单元值的最大值替换

Python 矩阵中的最小迭代次数,其中单元值在单个迭代中被相邻单元值的最大值替换,python,algorithm,matrix,Python,Algorithm,Matrix,我有一个矩阵,每个单元格中都有值(最小值=1),其中最大值为“max” 一次,我修改每个单元格的值,修改其相邻单元格的最大值,即所有8个相邻单元格,同时对整个矩阵进行修改。我想找出在什么样的最小迭代次数之后,所有单元的值都是最大的 一种蛮力方法是用0填充矩阵,然后 for i in range (1,x_max+1): for j in range(1,y_max+1): maximum = 0 for k in range(-1,2):

我有一个矩阵,每个单元格中都有值(最小值=1),其中最大值为“max”

一次,我修改每个单元格的值,修改其相邻单元格的最大值,即所有8个相邻单元格,同时对整个矩阵进行修改。我想找出在什么样的最小迭代次数之后,所有单元的值都是最大的

一种蛮力方法是用0填充矩阵,然后

for i in range (1,x_max+1):
    for j in range(1,y_max+1):
    maximum = 0 
        for k in range(-1,2):
            for l in range(-1,2):
                if matrix[i+k][j+l]>maximum:
                    maximum = matrix[i+k][j+l]
        matrix[i][j] = maximum
但是,有没有一种更智能、更快的方法可以做到这一点呢?
提前感谢。

我认为这可以通过BFS(广度优先搜索)解决

使用“最大”值的所有矩阵单元模拟启动BFS

  dis[][]  == infinite // min. distance of cell from nearest cell with 'max' value, initially infinite for all
  Q // Queue
  M[][] // matrix
  for all i,j   // travers the matrix, enqueue all cells with 'max'
    if M[i][j] == 'max' 
       dis[i][j] = 0 , Q.push( cell(i,j) )
  while !Q.empty:
       cell Current = Q.front 
       for all neighbours Cell(p,q) of Current: 
              if dis[p][q] == infinite
                 dis[p][q] = dis[Current.row][Current.column] + 1
                 Q.push( cell(p,q))
       Q.pop()

对于所有i,j,具有max(dis[i][j])的单元将是所需的迭代次数

我认为这可以通过BFS(广度优先搜索)解决

使用“最大”值的所有矩阵单元模拟启动BFS

  dis[][]  == infinite // min. distance of cell from nearest cell with 'max' value, initially infinite for all
  Q // Queue
  M[][] // matrix
  for all i,j   // travers the matrix, enqueue all cells with 'max'
    if M[i][j] == 'max' 
       dis[i][j] = 0 , Q.push( cell(i,j) )
  while !Q.empty:
       cell Current = Q.front 
       for all neighbours Cell(p,q) of Current: 
              if dis[p][q] == infinite
                 dis[p][q] = dis[Current.row][Current.column] + 1
                 Q.push( cell(p,q))
       Q.pop()
对于所有i,j,具有max(dis[i][j])的单元将是所需的迭代次数

使用带有“边框”的数组

测试边缘条件非常繁琐,可以通过在边缘周围使数组变大1来避免,每个元素的值为
INT\u MIN

另外,考虑8个测试,而不是双嵌套循环< /P>

// Data is in matrix[1...N][1...M], yet is size matrix[N+2][M+2]
for (i=1; i <= N; i++) {
  for (j=1; j <= M; j++) {
    maximum = matrix[i-1][j-l];
    if (matrix[i-1][j+0] > maximum) maximum = matrix[i-1][j+0];
    if (matrix[i-1][j+1] > maximum) maximum = matrix[i-1][j+1];
    if (matrix[i+0][j-1] > maximum) maximum = matrix[i+0][j-1];
    if (matrix[i+0][j+0] > maximum) maximum = matrix[i+0][j+0];
    if (matrix[i+0][j+1] > maximum) maximum = matrix[i+0][j+1];
    if (matrix[i+1][j-1] > maximum) maximum = matrix[i+1][j-1];
    if (matrix[i+1][j+0] > maximum) maximum = matrix[i+1][j+0];
    if (matrix[i+1][j+1] > maximum) maximum = matrix[i+1][j+1];
    newmatrix[i][j] = maximum
//数据在矩阵[1…N][1…M]中,但它是大小矩阵[N+2][M+2]
对于(i=1;i最大值)最大值=矩阵[i-1][j+1];
如果(矩阵[i+0][j-1]>最大值)最大值=矩阵[i+0][j-1];
如果(矩阵[i+0][j+0]>最大值)最大值=矩阵[i+0][j+0];
如果(矩阵[i+0][j+1]>最大值)最大值=矩阵[i+0][j+1];
如果(矩阵[i+1][j-1]>最大值)最大值=矩阵[i+1][j-1];
如果(矩阵[i+1][j+0]>最大值)最大值=矩阵[i+1][j+0];
如果(矩阵[i+1][j+1]>最大值)最大值=矩阵[i+1][j+1];
newmatrix[i][j]=最大值
使用带有“边框”的数组

测试边缘条件非常繁琐,可以通过在边缘周围使数组变大1来避免,每个元素的值为
INT\u MIN

另外,考虑8个测试,而不是双嵌套循环< /P>

// Data is in matrix[1...N][1...M], yet is size matrix[N+2][M+2]
for (i=1; i <= N; i++) {
  for (j=1; j <= M; j++) {
    maximum = matrix[i-1][j-l];
    if (matrix[i-1][j+0] > maximum) maximum = matrix[i-1][j+0];
    if (matrix[i-1][j+1] > maximum) maximum = matrix[i-1][j+1];
    if (matrix[i+0][j-1] > maximum) maximum = matrix[i+0][j-1];
    if (matrix[i+0][j+0] > maximum) maximum = matrix[i+0][j+0];
    if (matrix[i+0][j+1] > maximum) maximum = matrix[i+0][j+1];
    if (matrix[i+1][j-1] > maximum) maximum = matrix[i+1][j-1];
    if (matrix[i+1][j+0] > maximum) maximum = matrix[i+1][j+0];
    if (matrix[i+1][j+1] > maximum) maximum = matrix[i+1][j+1];
    newmatrix[i][j] = maximum
//数据在矩阵[1…N][1…M]中,但它是大小矩阵[N+2][M+2]
对于(i=1;i最大值)最大值=矩阵[i-1][j+1];
如果(矩阵[i+0][j-1]>最大值)最大值=矩阵[i+0][j-1];
如果(矩阵[i+0][j+0]>最大值)最大值=矩阵[i+0][j+0];
如果(矩阵[i+0][j+1]>最大值)最大值=矩阵[i+0][j+1];
如果(矩阵[i+1][j-1]>最大值)最大值=矩阵[i+1][j-1];
如果(矩阵[i+1][j+0]>最大值)最大值=矩阵[i+1][j+0];
如果(矩阵[i+1][j+1]>最大值)最大值=矩阵[i+1][j+1];
newmatrix[i][j]=最大值

所有现有答案都需要检查矩阵中的每个单元格。如果你还不知道最大值的位置是什么,这是不可避免的,在这种情况下,具有最佳时间复杂度:O(wh),如果矩阵有宽度w和高度h

OTOH,也许你已经知道k最大值的位置,k相对较小。在这种情况下,下面的算法将在O(k^2*(log(k)+log(max(w,h)))时间内找到答案,当w或h较大时,这会更快。它实际上并不查看任何矩阵条目;相反,它运行一个二进制搜索来查找候选停止时间(即答案)。对于每个候选停止时间,它构建一组矩形,该矩形届时将被
max
占据,并检查是否有任何矩阵单元仍被矩形覆盖

为了解释这个想法,我们首先需要一些术语。将矩形的顶行称为“开始垂直事件”,将其底边下的行称为“结束垂直事件”。“基本间隔”是由任何一对垂直事件跨越的行间隔,这些事件之间没有第三个垂直事件(定义这些间隔的事件对可以来自相同或不同的矩形)。注意,对于k个矩形,基本间隔不能超过2k+1——这里不依赖于h

基本思想是从左向右遍历矩阵中与水平事件相对应的列:新矩形“开始”(矩形的左垂直边)或现有矩形“结束”(矩形的右垂直边右侧的列)的列,跟踪当前覆盖每个基本间隔的矩形数量。如果我们检测到一个由0个矩形覆盖的基本间隔,我们可以停止:我们发现一个列包含一个或多个在时间t尚未覆盖的单元格。如果我们到达矩阵的右边缘而没有发生这种情况,那么所有的细胞都在时间t被覆盖

这里是一个函数的伪代码,该函数检查在给定一个长度为k的数组
peak
的情况下,是否有任何矩阵单元未被时间
t
覆盖,其中
(peak[i].x,peak[i].y)
是原始矩阵中包含第i个
max
单元的位置,按x坐标的递增顺序排列(因此最左边的
max
包含单元格位于
(峰值[1].x,峰值[1].y)

函数IsMatrixcevered(t,峰值[]){
#发现所有垂直事件和基本间隔
设vertEvents[]为空整数数组。
对于从1到k的i:
顶部=最大值(1,峰值[i].y-t)
bot=min(h,峰值[i].y+t)
将top追加到vertEvents[]
将bot+1附加到vertEvents[]
按递增顺序对事件排序,并删除重复项。
x=1
设horizEvents[]为{col,type,top,bot}结构的空数组。
对于从1到k的i:
#计算峰值[i]在时间t将覆盖的(剪裁)矩形:
lft=max(1,峰值[i].x-t)
rgt=min(w,峰值[i].x+t)
顶部=最大值(1,峰值[i].y-t)
bot=min(h,峰值[i].y+t)
#将垂直位置转换为垂直事件索引
T