[英]Random numbers that add to 100: Matlab
[我將人口數分成不同的矩陣,現在想使用隨機數測試我的代碼。]
快速提問伙計們,提前感謝您的幫助-
如果我使用;
100*rand(9,1)
使這 9 個數字加起來等於 100 的最佳方法是什么?
我想要 0 到 100 之間的 9 個隨機數,它們加起來等於 100。
是否有執行此操作的內置命令,因為我似乎找不到它。
我經常看到這個錯誤,有人建議要生成一個給定總和的隨機數,即只使用一個統一的隨機集,然后對其進行縮放。 但是,如果這樣做的話,結果是否真的是均勻隨機的?
嘗試在二維中進行此簡單測試。 生成一個巨大的隨機樣本,然后將其縮放為1。我將使用bsxfun進行縮放。
xy = rand(10000000,2);
xy = bsxfun(@times,xy,1./sum(xy,2));
hist(xy(:,1),100)
如果它們確實是完全均勻的隨機變量,則x坐標和y坐標都將是均勻的。 任何價值均可能發生。 實際上,要使兩個點的總和等於1,它們必須沿着在(x,y)平面上連接兩個點(0,1),(1,0)的線上。 為了使點統一,沿該線的任何點都必須具有相同的可能性。
當我使用縮放解決方案時,均勻性顯然會失敗。 那條線上的任何一點都不太可能。 我們可以看到3維中發生了同樣的事情。 請參見此處的3-d圖,三角形區域中心的點更密集。 這反映了不均勻性。
xyz = rand(10000,3);
xyz = bsxfun(@times,xyz,1./sum(xyz,2));
plot3(xyz(:,1),xyz(:,2),xyz(:,3),'.')
view(70,35)
box on
grid on
同樣,簡單的縮放解決方案也會失敗。 它根本不會在關注領域產生真正統一的結果。
我們可以做得更好嗎? 嗯,是。 2-d中的一個簡單解決方案是生成一個隨機數,該隨機數指定沿連接點(0,1)和1,0)的線的距離。
t = rand(10000000,1);
xy = t*[0 1] + (1-t)*[1 0];
hist(xy(:,1),100)
可以證明,現在已經很可能選擇了沿方程x + y = 1定義的線的任何點(單位平方)。 好的直方圖反映了這一點。
大衛·施瓦茨(David Schwartz)建議的排序技巧是否可以在n維上起作用? 顯然,它是在2維中進行的,下圖表明它是在3維中進行的。 如果不對此問題進行深思熟慮,我相信它將對n個維度的基本問題起作用。
n = 10000;
uv = [zeros(n,1),sort(rand(n,2),2),ones(n,1)];
xyz = diff(uv,[],2);
plot3(xyz(:,1),xyz(:,2),xyz(:,3),'.')
box on
grid on
view(70,35)
您還可以從文件交換(Roger Stafford的貢獻)中下載randfixedsum函數。 這是一種更通用的解決方案,可以在任何給定的固定總和下,在單位超立方體中生成真正統一的隨機集。 因此,要生成位於單元3多維數據集中的隨機點集,在約束下它們的總和為1.25 ...
xyz = randfixedsum(3,10000,1.25,0,1)';
plot3(xyz(:,1),xyz(:,2),xyz(:,3),'.')
view(70,35)
box on
grid on
一種簡單的方法是從0到100之間選擇8個隨機數。將0和100添加到列表中可得到10個數字。 對它們進行排序。 然后輸出每個連續數字對之間的差。 例如,這是0到100之間的8個隨機數:
96、38、95、5、13、57、13、20
因此,將0和100相加並排序。
0、5、13、13、20、38、57、95、96、100
現在減去:
5-0 = 5
13-5 = 8
13-13 = 0
20-13 = 7
38-20 = 18
57-38 = 19
95-57 = 38
96-95 = 1
100-96 = 4
在那里,您得到了九個數字,它們總計為100:0、1、4、5、7、8、18、19、38。我得到了零,而一個只有一個運氣。
給出正確答案還為時不晚
讓我們談談在[0 ... 1]范圍內對X1 ... XN進行采樣,以使Sum(X1,...,XN)等於1。然后可以將其縮放為100
這稱為Dirichlet分布 ,下面是從中采樣的代碼。 最簡單的情況是,當所有參數都等於1時,則X1,...,XN的所有邊際分布將為U(0,1)。 一般情況下,如果參數不同於1s,則邊際分布可能會出現峰值。
-----------------從這里取走---------------------
Dirichlet是單位標度的伽瑪隨機變量的矢量,通過它們的和進行歸一化。 因此,無需進行錯誤檢查,您將獲得:
a = [1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0]; // 9 numbers to sample
n = 10000;
r = drchrnd(a,n)
function r = drchrnd(a,n)
p = length(a);
r = gamrnd(repmat(a,n,1),1,n,p);
r = r ./ repmat(sum(r,2),1,p);
取一個N-1個數字的列表,通過插入0和100來創建N + 1個數字的列表,對列表進行排序,然后將它們相減到總共N個數字。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.