Losowe liczby, które dodają się do 100: Matlab

[dzielę liczbę populacji na różne macierze i chcę przetestować mój kod za pomocą liczb losowych na razie.]

Szybkie pytanie chłopaki i z góry dzięki za pomoc-

Jeśli używam;

 100*rand(9,1)

jaki jest najlepszy sposób, aby te 9 liczb dodać do 100?

Chciałbym 9 losowych liczb od 0 do 100, które sumują się do 100.

Czy istnieje wbudowane polecenie, które robi to, ponieważ nie mogę go znaleźć.

Author: Luis Mendo, 2011-11-09

4 answers

Widzę błąd tak często, sugestię, że aby wygenerować liczby losowe o danej sumie, wystarczy użyć jednolitego zbioru losowego i po prostu przeskalować je. Ale czy wynik jest naprawdę jednolicie Przypadkowy, jeśli robisz to w ten sposób?

Wypróbuj ten prosty test w dwóch wymiarach. Wygeneruj ogromną próbkę losową, a następnie przeskaluj ją do 1. Użyję bsxfun do skalowania.

xy = rand(10000000,2);
xy = bsxfun(@times,xy,1./sum(xy,2));
hist(xy(:,1),100)

Gdyby były rzeczywiście równomiernie losowe, wtedy współrzędna x byłaby jednolita, podobnie jak współrzędna y. Dowolna wartość równie prawdopodobne by się stało. W efekcie, aby dwa punkty sumowały się do 1, muszą leżeć wzdłuż linii łączącej dwa punkty (0,1), (1,0) w płaszczyźnie (X,y). Aby punkty były jednolite, każdy punkt wzdłuż tej linii musi być jednakowo prawdopodobny.

histogram xy

Wyraźnie jednorodność zawodzi, gdy używam rozwiązania skalowania. Jakikolwiek punkt na tej linii nie jest równie prawdopodobny. To samo dzieje się w trzech wymiarach. Zobacz, że na rysunku 3d tutaj, punkty w środku trójkątny region jest gęsto upakowany. Jest to odbicie niejednorodności.

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

xyzplot

Ponownie, proste rozwiązanie skalowania zawodzi. Po prostu nie daje naprawdę jednolitych wyników w dziedzinie zainteresowania.

Czy możemy stać się lepsi? Tak. Prostym rozwiązaniem w 2-d jest wygenerowanie pojedynczej liczby losowej wyznaczającej odległość wzdłuż linii łączącej punkty (0,1) i 1,0).
t = rand(10000000,1);
xy = t*[0 1] + (1-t)*[1 0];
hist(xy(:,1),100)

Jednolita X + y = 1

Można wykazać, że dowolny punkt wzdłuż linia określona równaniem x + y = 1, w kwadracie jednostkowym, jest teraz równie prawdopodobna. Odzwierciedla to ładny, płaski histogram.

Czy trick zaproponowany przez Davida Schwartza działa w n-wymiarach? Oczywiście robi to w 2-d, A poniższy rysunek sugeruje, że robi to w 3-wymiarach. Bez głębokiego namysłu na ten temat, wierzę, że to zadziała w tym podstawowym przypadku, o którym mowa, w n-wymiarach.

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)

Sort trick

Można również pobrać funkcja randfixedsum z wymiany plików, wkład Rogera Stafforda. Jest to bardziej ogólne rozwiązanie do generowania prawdziwie jednolitych zbiorów losowych w hiper-sześcianie jednostkowym, z dowolną określoną sumą stałą. Tak więc, aby wygenerować losowe zbiory punktów, które leżą w jednostce 3-sześcian, z zastrzeżeniem ograniczenia ich sumują się do 1,25...

xyz = randfixedsum(3,10000,1.25,0,1)';
plot3(xyz(:,1),xyz(:,2),xyz(:,3),'.')
view(70,35)
box on
grid on

randfixedsum

 72
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-09 17:24:35

Jednym z prostych sposobów jest wybranie 8 losowych liczb od 0 do 100. Dodaj 0 i 100 do listy, aby dać 10 liczb. Posortuj je. Następnie wyprowadź różnicę między każdą kolejną parą liczb. Na przykład, oto 8 losowych liczb z zakresu od 0 do 100:

96, 38, 95, 5, 13, 57, 13, 20

Więc dodaj 0 i 100 i sortuj.

0, 5, 13, 13, 20, 38, 57, 95, 96, 100

Teraz odejmij:

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

I masz to, dziewięć liczb, które sumują się do 100: 0, 1, 4, 5, 7, 8, 18, 19, 38. To, że mam zero i jedynkę, było po prostu dziwnym szczęściem.

 55
Author: David Schwartz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-19 14:37:34

Nie jest za późno, aby udzielić właściwej odpowiedzi]} Porozmawiajmy o próbkowaniu X1...XN w zakresie [0...1] taka, że suma (X1, ..., XN) jest równa 1. Następnie możesz przeskalować go do 100

Nazywa się to rozkładem Dirichleta , a poniżej znajduje się kod do pobrania z niego. Najprostszym przypadkiem jest, gdy wszystkie parametry są równe 1, to wszystkie rozkłady krańcowe dla X1, ..., XN byłoby U (0,1). W ogólnym przypadku, przy parametrach innych niż 1s, rozkład krańcowy może mieć szczyty.

----------------- zaczerpnięte z tutaj ---------------------

Dirichlet jest wektorem zmiennych losowych gamma w skali jednostkowej, znormalizowanym przez ich sumę. Tak więc, bez sprawdzania błędów, dostaniesz to:
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);
 2
Author: Severin Pappadeux,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-01 14:10:54

Weź listę N-1 liczb, Utwórz listę N + 1 liczb, wstawiając 0 i 100, posortuj listę i oddziel je do sumy n liczb.

 0
Author: user2392848,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-18 07:54:11