我需要生成一个矩阵,其中对角线为零,每一列和每一行的总和为零。
例如第一行0、4,-2,-1、1 =总和为0
或第一列0,-4、2、1、1 =总和为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)镜像
答案 0 :(得分:2)
对于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