我正在寻找一种快速创建具有以下属性的随机矩阵A
的方法:
A = transpose(A)
A(i,i) = 0
A(i,j) >= 0
所有我,j sum(A) =~ degree
;行的总和由我想指定的分布随机分布(这里=~
表示近似相等)。分发degree
来自矩阵orig
,特别是degree=sum(orig)
,因此我知道存在具有此分布的矩阵。
例如:orig=[0 12 7 5; 12 0 1 9; 7 1 0 3; 5 9 3 0]
orig =
0 12 7 5
12 0 1 9
7 1 0 3
5 9 3 0
sum(orig)=[24 22 11 17];
现在一个可能的矩阵A=[0 11 5 8, 11 0 4 7, 5 4 0 2, 8 7 2 0]
是
A =
0 11 5 8
11 0 4 7
5 4 0 2
8 7 2 0
sum(A)=[24 22 11 17]
。
我正在尝试这段时间,但遗憾的是我的两个想法并不奏效:
版本1:
我将Nswitch
次切换为两个随机元素:A(k1,k3)--; A(k1,k4)++; A(k2,k3)++; A(k2,k4)--;
(转置元素也是如此)。
不幸的是,Nswitch = log(E)*E
(与E=sum(sum(nn))
)以使矩阵非常不相关。作为我的E > 5.000.000
,这是不可行的(特别是,因为我需要至少10个这样的矩阵)。
第2版:
我根据分布从头开始创建矩阵。我们的想法是,根据i
的分布,用degree(i)
个数字填充degree
的每一行:
nn=orig;
nnR=zeros(size(nn));
for i=1:length(nn)
degree=sum(nn);
howmany=degree(i);
degree(i)=0;
full=rld_cumsum(degree,1:length(degree));
rr=randi(length(full),[1,howmany]);
ff=full(rr);
xx=i*ones([1,length(ff)]);
nnR = nnR + accumarray([xx(:),ff(:)],1,size(nnR));
end
A=nnR;
但是,虽然sum(A')=degree
,sum(A)
系统地偏离了degree
,但我无法找到原因。
当然,与degree
的小偏差很好,但是在某些地方大量的矩阵中,似乎存在系统偏差。
如果某人可以向我显示版本1的快速方法,或者版本2中分布的系统偏差的原因,或者以不同方式创建此类矩阵的方法,我将非常高兴。谢谢!
修改
这是 matsmath 提出的解决方案中的问题: 想象一下你有矩阵:
orig =
0 12 3 1
12 0 1 9
3 1 0 3
1 9 3 0
r(i)=[16 22 7 13]
。
我的随机矩阵开始看起来像
A =
0 7 3 6
7 0 . .
3 . 0 .
6 . . 0
新行和向量rnew = [r(2)-p(2),...,r(n)-p(n)] = [15 4 7]
第二次迭代(这里出现问题):
EDIT2:
这是代表(据我所知) David Eisenstat 发布的解决方案的代码:
orig=[0 12 3 1; 12 0 1 9; 3 1 0 3; 1 9 3 0];
w=[2.2406 4.6334 0.8174 1.6902];
xfull=zeros(4);
for ii=1:1000
rndmat=[poissrnd(w(1),1,4); poissrnd(w(2),1,4); poissrnd(w(3),1,4); poissrnd(w(4),1,4)];
kkk=rndmat.*(ones(4)-eye(4)); % remove diagonal
hhh=sum(sum(orig))/sum(sum(kkk))*kkk; % normalisation
xfull=xfull+hhh;
end
xf=xfull/ii;
disp(sum(orig)); % gives [16 22 7 13]
disp(sum(xf)); % gives [14.8337 9.6171 18.0627 15.4865] (obvious systematic problem)
disp(sum(xf')) % gives [13.5230 28.8452 4.9635 10.6683] (which is also systematically different from [16, 22, 7, 13]
答案 0 :(得分:1)
让你的行和向量由矩阵orig [r(1),r(2),...,r(n)]给出。
Step 1. Take a random integer partition of the integer r(1) into exactly n-1 parts, say p(2), p(3), ..., p(n)
Step 2. Check if p(i)<=r(i) for all i=2...n. If not, go to Step 1.
Step 3. Fill out your random matrix first row and colum by the entries 0, p(2), ... , p(n), and consider the new row sum vector [r(2)-p(2),...,r(n)-p(n)].
使用n-1阶矩阵重复这些步骤。
关键是,您一次随机化一行,并将问题减少到搜索大小少一的矩阵。
正如OP在评论中指出的那样,这种天真的算法失败了。原因是所讨论的矩阵在其条目上具有进一步必要条件,如下所示:
FACT:
如果A
是行总和为[r(1), r(2), ..., r(n)]
的原始矩阵,那么每个i=1..n
的必然,它会保留r(i)<=-r(i)+sum(r(j),j=1..n)
。
也就是说,任何行总和,比如i
,r(i)
,最多必须与其他行总和(不包括r(i)
)的总和一样大。< / p>
鉴于此,可以修改算法。请注意,在步骤2b中。我们检查新的行和向量是否具有上面讨论的属性。
Step 1. Take a random integer partition of the integer r(1) into exactly n-1 parts, say p(2), p(3), ..., p(n)
Step 2a. Check if p(i)<=r(i) for all i=2...n. If not, go to Step 1.
Step 2b. Check if r(i)-p(i)<=-r(i)+p(i)+sum(r(j)-p(j),j=2..n) for all i=2..n. If not, go to Step 1.
Step 3. Fill out your random matrix first row and colum by the entries 0, p(2), ... , p(n), and consider the new row sum vector [r(2)-p(2),...,r(n)-p(n)].
我不确定这种方法是否为您提供了随机矩阵,但它肯定会为您提供不同的矩阵。
这里的想法是在本地更改orig
矩阵的某些部分,以维护其所有属性。
你应该在主对角线下面寻找一个随机的2x2子矩阵,它包含严格的正条目,例如[[a,b],[c,d]]
,并通过随机值r
到[[a+r,b-r],[c-r,d+r]]
来扰动它的内容。您也可以在主对角线上方进行相同的更改,以保持新矩阵的对称性。这里的要点是条目中的变化“相互抵消”。
当然,r
应该以{{1}}和b-r>=0
的方式选择。
你可以追求这个想法来修改更大的子矩阵。例如,您可以选择3个随机行坐标c-r>=0
,r1
,r2
和3个随机列坐标r2
,c1
和c2
然后在9个c3
位置的orig
矩阵中进行更改,如下所示:您将(ri,cj)
子矩阵3x3
更改为[[a b c],[d e f], [g h i]]
。你在转置的地方做同样的事情。同样,必须以某种方式选择随机值[[a-r b+r c] [d+r e f-r], [g h-r i+r]]
,以便r
和a-r>=0
以及f-r>=0
。此外,h-r>=0
和c1
以及r1
和c3
必须是不同的,因为您无法更改矩阵r3
的主对角线中的0条目
你可以一遍又一遍地重复这些事情,比如说orig
次,直到找到一些看似随机的东西。请注意,这个想法使用的事实是您已经拥有解决方案的知识,这是矩阵100
,而第一种方法根本不使用这些知识。
答案 1 :(得分:1)
因为它足以大致保留度序列,所以让我提出一个随机分布,其中对角线上方的每个条目都是根据Poisson distribution选择的。我的直觉是我们想要找到权重w_i
,使i,j
的{{1}}条目具有均值i != j
(所有对角线条目都为零)。这给了我们一个非线性方程组:
w_i*w_j
其中for all i, (sum_{j != i} w_i*w_j) = d_i,
是d_i
的程度。等价地,
i
后者可以通过从for all i, w_i * (sum_j w_j) - w_i^2 = d_i.
的起始解决方案应用Newton's method来解决,如下所述。
获得w_i = d_i / sqrt(sum_j d_j)
后,我们可以使用w_i
重复采样,一次生成多个泊松分布的样本。
(如果我有时间,我会尝试在numpy中实现这个。)
4乘4问题的方程组的雅可比矩阵是
poissrnd
通常,让(w_2 + w_3 + w_4) w_1 w_1 w_1
w_2 (w_1 + w_3 + w_4) w_2 w_2
w_3 w_3 (w_1 + w_2 + w_4) w_3
w_4 w_4 w_4 (w_1 + w_2 + w_3).
成为A
的对角矩阵。设A_{i,i} = sum_j w_j - 2*w_i
和u = [w_1, ..., w_n]'
。雅可比人可以写成v = [1, ..., 1]'
。逆由Sherman--Morrison公式
J = A + u*v'
对于牛顿步骤,我们需要为某些给定的 A^-1*u*v'*A^-1
J^-1 = (A + u*v')^-1 = A^-1 - -------------- .
1 + v'*A^-1*u
计算J^-1*y
。这可以使用上面的等式在y
时间内直接完成。当我有机会时,我会添加更多细节。