我有一些技术问题,但我觉得应该可以使用MATLAB强大的工具集。
我所拥有的是一个随机的n×n矩阵0' s,用
生成A=w*(rand(n,n)<p);
w的典型值为3000,但这并不重要。
现在,这个矩阵有两个重要的量,即矢量
c = sum(A,1);
r = sum(A,2)';
这是两个行向量,第一个表示每列的总和,第二个表示每行的总和。
我接下来要做的是随机化w的每个值,例如在0.5和2之间。我会这样做
rand_M = (0.5-2).*rand(n,n) + 0.5
A_rand = rand_M.*A;
但是,我不想只选择这些随机数:我希望它们对于每一列和每一行,总和仍然等于c和r的元素。所以要稍微清理一下符号,比如我们定义
A_rand_c = sum(A_rand,1);
A_rand_r = sum(A_rand,2)';
我想要所有j = 1:n, A_rand_c(j) = c(j)
和A_rand_r(j) = r(j)
。
我想要的是一种以某种算法方式重绘rand_M元素的方法,以便最终满足这些要求。
当然,除非我有无限的时间,否则这可能不会发生。因此,我接受这些数量属于特定范围:A_rand_c(j)
必须是[(1-e)*c(j),(1+e)*c(j)]
和A_rand_r(j)
[(1-e)*r(j),(1+e)*r(j)]
的元素。这个我事先定义,比如说0.001或者其他什么。
有没有人能够帮助我找到一种方法来做到这一点?我尝试过一种方法,我只是随意地重新编写数字,但这真的不能让我到任何地方。它也不一定是疯狂有效的,我只需要在有限的时间内为大小的网络工作,比如,n = 50。
要清楚,最终输出是满足这些约束的矩阵A_rand
。
编辑:
好吧,所以在思考了一下之后,我认为它可能对某些while语句有用,它会遍历矩阵的每个元素。困难的部分是存在四种可能性:如果您处于特定元素A_rand(i,j)
中,则可能A_rand_c(j)
和A_rand_r(i)
太小,太大或相反。前两种情况很好,因为那样你就可以重新绘制随机数,直到它小于当前值并改善情况。但另外两个案例是有问题的,因为你会改善一种情况而不是另一种情况。我想它必须看看哪个标准不太满意,所以它试图修复那个更糟糕的标准。但这不是一件轻而易举的事情。
答案 0 :(得分:1)
您可以利用A
中包含单个非零条目的行/列自动为A_rand
中的相同条目提供结果的事实。如果A(2,5) = w
并且它是其列中唯一的非零条目,那么A_rand(2,5) = w
也是如此。还有什么呢?
您可以在查找这些单项行/列之间切换,并将随机数分配给值不重要的条目。
这是该过程的骨架:
A_rand=zeros(size(A))
是您要填写的矩阵entries_left = A>0
是一个二进制矩阵,显示A_rand
中您仍需填写哪些条目col_totals=sum(A,1)
是您仍需要在A_rand
row_totals=sum(A,2)
是您需要在A_rand
while sum( entries_left(:) ) > 0
% STEP 1:
% function to fill entries in A_rand if entries_left has rows/cols with one nonzero entry
% you will need to keep looping over this function until nothing changes
% update() A_rand, entries_left, row_totals, col_totals every time you loop
% STEP 2:
% let (i,j) be the indeces of the next non-zero entry in entries_left
% assign a random number to A_rand(i,j) <= col_totals(j) and <= row_totals(i)
% update() A_rand, entries_left, row_totals, col_totals
end
update()
A_rand(i,j) = random_value;
entries_left(i,j) = 0;
col_totals(j) = col_totals(j) - random_value;
row_totals(i) = row_totals(i) - random_value;
end
挑选random_value
的范围可能有点棘手。我能想到的最好的方法是从以N*w*p
为中心的相对较窄的分布中绘制它,其中p
是A
中非零的条目的概率(这将是行/列总计)。
这不能很好地扩展到大型矩阵,因为它将以n^2
复杂度增长。我测试了200×200矩阵,它在大约20秒内工作。