【问题标题】:How do I generate Matrix with sum of every individual row and column being zero如何生成每个行和列的总和为零的矩阵
【发布时间】:2021-01-31 19:46:00
【问题描述】:

我需要生成一个矩阵,其中对角线为零,每一列和每一行的和都为零。

例如第一行 0, 4, -2, -1, 1 = sum 为 0
或第一列 0, -4, 2, 1, 1 = sum 为 0

这当然适用于每一列和每一行

0, 4, -2, -1, -1
-4, 0, 3, 3, -2
2, -3, 0, -1, 2 
1, -3, 1, 0, 1 
1, 2, -2, -1, 0

对角线总是用零填充。 我试图创建一个加权图,它对它所做的每个连接都是平衡的。

编辑:我也忘记了矩阵是通过对角线镜像的 * (-1)

【问题讨论】:

    标签: matrix random generate


    【解决方案1】:

    对于 1×1、2×2 和 3×3 矩阵,唯一有效的矩阵如下(其中 r 是任意随机数):

    [ 0 ]    [ 0 0 ]    [  0  r -r ]
             [ 0 0 ]    [ -r  0  r ]
                        [  r -r  0 ]
    

    对于 4×4 矩阵,您可以从零矩阵开始,并通过重复执行不影响零和属性的操作来添加随机性。选择四边形角上的任意四个单元格(只要它们不在主对角线上)。将此四边形的角视为 2×2 矩阵,您可以添加以下矩阵的任意倍数,而不会影响行和列和:

    [  1  -1 ]
    [ -1   1 ]
    

    例如,一个 5×5 的零矩阵可以分四步转化为:

    [   0    W+X  -X    0   -W  ]
    [   Y     0    0   -Y    0  ]
    [ -Y+Z   -Z    0    Y    0  ]
    [  -Z   -W+Z   0    0    W  ]
    [   0    -X    X    0    0  ]
    

    以下是一些实现此算法的 Python 代码:

    def zero_sum_matrix(n):
        #
        # Generate a random matrix with a zero leading diagonal where
        # every row and every column has a sum value of zero.
        # (n = size of matrix)
        from random import randint
        #
        # Handle trivial cases
        assert n > 0
        if n == 1:
            return [[0]]
        if n == 2:
            return [[0,0],[0,0]]
        if n == 3:
            r = randint(-10,11)
            return [[0,r,-r], [-r,0,r], [r,-r,0]]
        #
        # Start with a zero matrix
        m = [[0]*n for i in range(n)]
        #
        # Add randomness without affecting the row and column sums
        for i in range(n*n):
            while True:
                # Choose two different rows
                r1, r2 = randint(0,n-1), randint(0,n-1)
                if r1 != r2:
                    break
            while True:
                # Choose two columns, making sure we aren't affecting
                # any cells on the main diagonal
                c1, c2 = randint(0,n-1), randint(0,n-1)
                if c1 != c2 and c1 not in (r1, r2) and c2 not in (r1, r2):
                    break
            # Add random perturbations at the intersections of these
            # rows and columns
            x = randint(-10,11)
            m[r1][c1] += x
            m[r1][c2] -= x
            m[r2][c1] -= x
            m[r2][c2] += x
        return m
    
    def mprint(m):
        # Formatted matrix print routine
        for row in m:
            o = '  '.join([("%4d" % x) for x in row])
            print(o)
    

    样本输出:

    >>> mprint(zero_sum_matrix(8))
       0     5     2     3    17   -13   -16     2
      -5     0   -10   -11    -2    16    17    -5
      -4    -3     0    -6    -7     9    25   -14
      18     4     0     0   -22     1     6    -7
       1   -27     2    12     0    -8    16     4
     -24    28     0    -7    15     0   -36    24
      14   -11    13   -17    17   -12     0    -4
       0     4    -7    26   -18     7   -12     0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多