一尘不染

得到最大和的子矩阵?

algorithm

输入 :具有正负元素的二维数组NxN-矩阵。

输出 :任意大小的子矩阵,使得其总和在所有可能的子矩阵中最大。

要求 :算法复杂度为 O(N ^ 3)

历史: 在算法学家,拉里(Larry)和对Kadane算法的修改的帮助下,我设法 部分地 解决了该问题,该问题仅在Java中确定求和。
感谢 Ernesto ,他设法解决了剩下的问题,即确定矩阵的边界,即Ruby中的左上角,右下角。


阅读 166

收藏
2020-07-28

共1个答案

一尘不染

关于恢复实际子矩阵,而不仅仅是恢复最大和,这就是我得到的。抱歉,我没有时间将我的代码转换为您的Java版本,因此我要在关键部分发表一些评论的Ruby代码

def max_contiguous_submatrix_n3(m)
  rows = m.count
  cols = rows ? m.first.count : 0

  vps = Array.new(rows)
  for i in 0..rows
    vps[i] = Array.new(cols, 0)
  end

  for j in 0...cols
    vps[0][j] = m[0][j]
    for i in 1...rows
      vps[i][j] = vps[i-1][j] + m[i][j]
    end
  end

  max = [m[0][0],0,0,0,0] # this is the result, stores [max,top,left,bottom,right]
  # these arrays are used over Kadane
  sum = Array.new(cols) # obvious sum array used in Kadane
  pos = Array.new(cols) # keeps track of the beginning position for the max subseq ending in j

  for i in 0...rows
    for k in i...rows
      # Kadane over all columns with the i..k rows
      sum.fill(0) # clean both the sum and pos arrays for the upcoming Kadane
      pos.fill(0)
      local_max = 0 # we keep track of the position of the max value over each Kadane's execution
      # notice that we do not keep track of the max value, but only its position
      sum[0] = vps[k][0] - (i==0 ? 0 : vps[i-1][0])
      for j in 1...cols
        value = vps[k][j] - (i==0 ? 0 : vps[i-1][j])
        if sum[j-1] > 0
          sum[j] = sum[j-1] + value
          pos[j] = pos[j-1]
        else
          sum[j] = value
          pos[j] = j
        end
        if sum[j] > sum[local_max]
          local_max = j
        end
      end
      # Kadane ends here

      # Here's the key thing
      # If the max value obtained over the past Kadane's execution is larger than
      # the current maximum, then update the max array with sum and bounds
      if sum[local_max] > max[0]
        # sum[local_max] is the new max value
        # the corresponding submatrix goes from rows i..k.
        # and from columns pos[local_max]..local_max
        # the array below contains [max_sum,top,left,bottom,right]
        max = [sum[local_max], i, pos[local_max], k, local_max]
      end
    end
  end

  return max # return the array with [max_sum,top,left,bottom,right]
end

需要澄清的一些注意事项:

为了方便起见,我使用数组存储与结果有关的所有值。您可以只使用五个独立变量:max,top,left,bottom,right。在一行中分配给数组更容易,然后子例程将返回包含所有所需信息的数组。

如果您将此代码复制并粘贴到具有Ruby支持的启用文本高亮的编辑器中,您显然会更好地理解它。希望这可以帮助!

2020-07-28