我试图将(长度为N)的向量V乘以(a,b)范围内随机生成的数字,同时保持向量的总和等于总量E.我想要在MATLAB中这样做,但我不知道如何。获取某个范围之间的随机数我知道该怎么做:
minrand = 0;
maxrand = 1;
randfac = (maxrand-minrand).*rand(1,N) + minrand;
但是,除此之外,我很无能为力。我猜这些随机数不能真正生成,因为如果我们将随机数称为向量R,那么我想要那样 R_1 * V1 + R_2 * V2 .... + R_N * V_N = E.所以我猜这是一个很大的等式。有没有办法解决它,同时对R?
的最大值和最小值设置约束答案 0 :(得分:2)
您可以选择两个元素对(在所有组合中)并添加和减去相等的随机数。
% Make up a random vector
N=10;
randfac = 10*rand(1,N);
%OP Answer here: Given randfac with sum E re-randomize it
E = sum(randfac);
minrand = 0;
maxrand = 2;
disp(randfac)
% v = [6.4685 2.9652 6.6567 1.6153 7.3581 0.0237 7.1025
% 3.2381 1.9176 1.3561]
disp(sum(randfac))
% E = 38.7019
r = minrand + (maxrand-minrand)*rand(N*N,1);
k = 1;
for i=1:N
for j=1:N
randfac(i) = randfac(i)-r(k);
randfac(j) = randfac(j)+r(k);
k = k + 1;
end
end
disp(randfac)
% v = [5.4905 0.7051 4.7646 1.3479 9.3722 -1.4222 7.9275
% 7.5777 1.7549 1.1836]
disp(sum(randfac))
% E = 38.7019
答案 1 :(得分:1)
只需将矢量除以总和并乘以目标E
。
randfac = (maxrand-minrand).*rand(1,N) + minrand;
randfac = E*randfac/sum(randfac);
只要算子是线性的,结果就是保持它的随机性。以下是一些示例代码:
minrand = 0;
maxrand = 1;
N = 1000; %size
v = (maxrand-minrand).*rand(1,N) + minrand;
E = 100; %Target sum
A = sum(v);
randfac = (E/A)*v;
disp(sum(randfac))
% 100.0000
答案 2 :(得分:1)
首先,在[a b]
的区间内使用随机数,您不能保证您将获得相同的求和(相同E
)。例如,如果[a b]=[1 2]
当然E
会增加。
这是一个想法,我不知道这有多随意!
对于even N
我随机化V
然后将其分成两行,并将其中一个与[a b]
中的随机数相乘,但第二列将乘以一个向量来保持求和固定的。
N = 10;
V = randi(100,[1 N]);
E = sum(V);
idx = randperm(N);
Vr = V(idx);
[~,ridx] = sort(idx);
Vr = reshape(Vr,[2 N/2]);
a = 1;
b = 3;
r1 = (b - a).*rand(1,N/2) + a;
r2 = (sum(Vr) - r1.*Vr(1,:))./Vr(2,:);
r = reshape([r1;r2],1,[]);
r = r(ridx);
Enew = sum(V.*r);
示例结果是,
V = [12 82 25 51 81 51 31 87 6 74];
r = [2.8018 0.7363 1.9281 0.5451 1.9387 -0.4909 1.3076 0.8904 2.9236 0.8440];
E = 500
以及Enew
。
我只是将一个随机数分配给一对(它可以被视为半随机!)。
答案 3 :(得分:0)
好的,我已经找到了一种方法可以做到这一点,但它并不优雅,可能有更好的解决方案。从初始向量e开始,其中sum(e)= E,我可以随机化其值并以e结束,其中sum(e)在[(1-threshold) E的范围内,(1 +阈值 E)]。它计算量很大,而且不漂亮。
这个想法是首先将e乘以某个范围内的随机数。然后,我将检查总和是多少。如果它太大,我会减小小于范围一半的随机数的值,直到总和不再太大。如果它太小,我会进行相反的操作,并进行迭代,直到总和在所需的范围内。
e = somepredefinedvector
minrand = 0;
maxrand = 2;
randfac = (maxrand-minrand).*rand(1,N) + minrand;
e = randfac.*e;
threshold = 0.001;
while sum(e) < (1-threshold)*E || sum(e) > (1+threshold)*E
if sum(e) > (1+threshold)*E
for j = 1:N
if randfac(j) > (maxrand-minrand)/2
e(j) = e(j)/randfac(j);
randfac(j) = ((maxrand-minrand)/2-minrand).*rand(1,1) + minrand;
e(j) = randfac(j)*e(j);
end
if sum(e) > (1-threshold)*E && sum(e) < (1+threshold)*E
break
end
end
elseif sum(e) < (1-threshold)*E
for j = 1:N
if randfac(j) < (maxrand-minrand)/2
e(j) = e(j)/randfac(j);
randfac(j) = (maxrand-(maxrand-minrand)/2).*rand(1,1) + (maxrand-minrand)/2;
e(j) = randfac(j)*e(j);
end
if sum(e) > (1-threshold)*E && sum(e) < (1+threshold)*E
break
end
end
end
end