【问题标题】:Matrix with equal sum of rows and columns行列之和相等的矩阵
【发布时间】:2012-03-25 21:09:30
【问题描述】:

我有 NxM 矩阵,其中包含大于或等于 0 的整数元素。

我可以从任何单元格将 1 转移到另一个单元格(-1 到源单元格,+1 到目的地)。 使用此操作,我必须使所有行和列的总和相等。问题是如何找到最少数量的此类操作来完成我的任务。在处理期间细胞可能是阴性的。

例如,对于

1 1 2 2

1 0 1 1

0 0 1 1

1 1 1 2

答案是 3。

P.s.:我尝试过自己解决它,但只是暴力解决。

【问题讨论】:

  • @Mixo123:如果提问者有一些证据表明他/她自己解决了这个问题,那么这类问题就会得到很好的答案。现在看起来你只是想让我们为你做你的工作。一些 SOers 会,很多不会。
  • 我试过了,但没有任何想法。只有蛮力解决方案
  • 您确定问题总是有解决方案(看起来矩阵中所有元素的总和应该除以 M 和 N)吗? Nx1矩阵呢?或者你得到可以以这种方式排序的矩阵?

标签: algorithm math matrix


【解决方案1】:

首先,求每行每列的期望总和1。

rowSum = totalSum / numRows
colSum = totalSum / numCols

然后,遍历行和列并计算以下值:

rowDelta = 0
for each row r
    if sum(r) > rowSum
       rowDelta += sum(r) - rowSum

colDelta = 0
for each col c
    if sum(c) > colSum
       colDelta += sum(c) - colSum

平衡所有行和列的最小移动次数是:

minMoves = max(rowDelta, colDelta)

这是可行的,因为您必须从超过 rowSum 的行转移到不超过它的行,从超过 colSum 的列转移到不超过它的列。

如果最初rowDelta 低于colDelta,那么您将达到平衡所有行但列仍未平衡的阶段。在这种情况下,您将继续从单元格转移到同一行中的其他单元格。如果最初 colDelta 低于 rowDelta,这同样适用,这就是我们选择它们之间的最大值作为预期结果的原因。

1如果totalSum不是numRows或numCols的倍数,则问题无解。

【讨论】:

    【解决方案2】:

    让我们考虑一维的情况:您有一个数字数组,并且您可以进行一次操作:从数组的一个元素的值中取 1 并将其添加到另一个元素。目标是通过最少的操作使所有元素相等。这里的解决方案很简单:你选择随机的“太大的数字”,然后在随机的“太小的”数字上加一。现在让我描述一下这与手头的问题有何关系。

    您可以轻松计算每列和每行所需的总和。这是矩阵中所有元素的总和分别除以列数或行数。从那时起,您可以计算哪些行和列需要减少,哪些 - 增加。看这里:

    1 1 2 2 -2
    1 0 1 1 +1
    0 0 1 1 +2
    1 1 1 2 -1
    +1+2-1-2
    Expected sum of a row: 4
    Expected sum of a column: 4
    

    所以现在我们生成两个数组:行中的位移数组:-2,+1,+2,-1 和列中的位移数:+1,+2,-1,-2。对于这两个数组,我们解决了上述更简单的任务。很明显,我们无法以比简单任务所需的步骤更少的步骤解决初始问题(否则列或行中的余额不会为 0)。

    但是我将证明初始任务可以通过与解决列和行任务所需的最大步骤数完全相同的步骤来解决:

    更简单任务中的每一步都会生成两个索引i 和j:从中减去的索引和要添加的索引。假设在列任务的一个步骤中,我们有索引ci 和cj,在行任务中我们有索引ri 和rj。然后我们在初始任务中分配一个对应关系:从(ci, ri) 中取 1 并为(cj, rj) 添加一个。在某些时候,我们将遇到这样一种情况,即在列任务中可能还有更多步骤,而在行任务中没有更多步骤。所以我们得到了ci 和cj,但是我们为ri 和rj 做什么呢?我们只选择ri=rj,这样我们就不会搞砸行计算。

    在这个解决方案中,我利用了允许在矩阵中获得负数这一事实。

    现在让我们演示一下:

    Solution for columns:
    4->1;3->2;4->2
    Solution for rows:
    1->3;1->3;2->4
    
    Total solution:
    (4,1)->(1,3);(3,1)->(2,3);(4,2)->(2,4)
    

    【讨论】:

    • 如果所有行都是“+”并且所有列都是中性或“-”怎么办?
    • @boris 也许它会更好地区分每个单元格的行状态和列状态。
    • @boris,建议(可能的)改进作为答案是否礼貌?
    • 好的,好的。现在我有了新的改进解决方案
    • @Eugeny89,当然会。其实你应该已经有了,因为现在我发布了我自己的改进版
    【解决方案3】:

    假设r1 是总和最大的行的索引,而r2 是总和最小的行。 c1 列的和最大,c2 列的最小。

    你需要重复以下操作:

    1. 如果Matrix[r1][c1] == Matrix[r2][c2] 我们完成了!
    2. 否则,Matrix[r1][c1] -= 1 和 Matrix[r2][c2] += 1

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-08
      • 1970-01-01
      • 1970-01-01
      • 2017-02-12
      • 1970-01-01
      • 2021-12-30
      相关资源
      最近更新 更多