如何使用随机条目生成矩阵并对行和列进行约束?

时间:2015-10-07 22:01:14

标签: python matlab matrix julia

如何生成矩阵,其条目是0到1之间的随机实数,包括附加约束:每行的总和必须小于或等于1,每列的总和必须小于或等于一个。

示例:

matrix = [0.3, 0.4, 0.2;
          0.7, 0.0, 0.3; 
          0.0, 0.5, 0.1]

3 个答案:

答案 0 :(得分:7)

如果您希望矩阵均匀分布并满足这些约束,则可能需要拒绝方法。在Matlab中它将是:

n = 3;
done = false;
while ~done
    matrix = rand(n);
    done = all(sum(matrix,1)<=1) & all(sum(matrix,2)<=1);
end

请注意,对于较大的n,这会很慢。

答案 1 :(得分:5)

如果您正在寻找Python方式,这只是Luis Mendo的拒绝方法的转录。为简单起见,我将使用NumPy:

import numpy as np
n = 3
done = False

while not done:
    matrix = np.random.rand(n,n)
    done = np.all(np.logical_and(matrix.sum(axis=0) <= 1, matrix.sum(axis=1) <= 1))

如果您没有NumPy,那么您可以生成2D矩阵作为列表列表:

import random 
n = 3
done = False

while not done:

    # Create matrix as a list of lists
    matrix = [[random.random() for _ in range(n)] for _ in range(n)]

    # Compute the row sums and check for each to be <= 1
    row_sums = [sum(matrix[i]) <= 1 for i in range(n)]

    # Compute the column sums and check for each to be <= 1
    col_sums = [sum([matrix[j][i] for j in range(n)]) <= 1 for i in range(n)]

    # Only quit of all row and column sums are less than 1
    done = all(row_sums) and all(col_sums)

答案 2 :(得分:3)

拒绝方法肯定会给你一个统一的解决方案,但生成一个好的矩阵可能需要很长时间,特别是如果你的矩阵很大。因此,另一种但更繁琐的方法是生成每个元素,使得每个方向的总和只能为1。为此,您始终在0 和余数之间生成一个新元素,直到1

n = 3

matrix = zeros(n+1); %dummy line in first row/column
for k1=2:n+1
for k2=2:n+1
   matrix(k1,k2)=rand()*(1-max(sum(matrix(k1,1:k2-1)),sum(matrix(1:k1-1,k2))));
end
end

matrix = matrix(2:end,2:end)

这有点棘手,因为对于每个元素,你检查行和和列之和直到该点,并使用两者中较大的一个来生成一个新元素(为了在两个方向上保持低于1的总和) )。出于实际原因,我在开头用零行和列填充矩阵,以避免使用k1-1k2-1编制索引问题。

请注意,正如@LuisMendo指出的那样,这将作为拒绝方法具有不同的分布。但是如果你的约束不考虑分布,那么这也可以做到(这将为你提供一次运行的矩阵)。