45

[母集団の数をさまざまな行列に分割していて、今のところ乱数を使用してコードをテストしたいと思います。]

簡単な質問の人と事前にあなたの助けに感謝します-

私が使用する場合;

 100*rand(9,1)

これらの9つの数字を100に追加するための最良の方法は何ですか?

合計100になる0から100までの9つの乱数が欲しいのですが。

私はそれを見つけることができないように見えるので、これを行う組み込みコマンドはありますか?

4

4 に答える 4

89

私はよく間違いを目にします。与えられた合計で乱数を生成するには、均一なランダムセットを使用し、それらをスケーリングするという提案です。しかし、そのようにすると、結果は本当に均一にランダムになりますか?

この簡単なテストを2次元で試してください。巨大なランダムサンプルを生成し、それらをスケーリングして合計を1にします。スケーリングにはbsxfunを使用します。

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

それらが本当に均一にランダムである場合、y座標と同様に、x座標も均一になります。どのような値でも同じように発生する可能性があります。実際、2つのポイントの合計が1になるには、(x、y)平面の2つのポイント(0,1)、(1,0)を結ぶ線に沿って配置する必要があります。ポイントが均一であるためには、その線に沿ったどのポイントも同じように可能性が高い必要があります。

xyヒストグラム

スケーリングソリューションを使用すると、明らかに均一性が失われます。その線上のどの点も同じように起こりそうにありません。同じことが3次元でも起こっているのを見ることができます。ここの3次元図では、三角形の領域の中心にあるポイントがより密集していることがわかります。これは不均一性を反映しています。

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

繰り返しますが、単純なスケーリングソリューションは失敗します。対象のドメイン全体で真に均一な結果が得られるわけではありません。

もっと上手くできますか?はい、そうです。2次元の簡単な解決策は、点(0,1)と1,0)を結ぶ線に沿った距離を指定する単一の乱数を生成することです。

t = rand(10000000,1);
xy = t*[0 1] + (1-t)*[1 0];
hist(xy(:,1),100)

均一x+y = 1

方程式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)

ソートトリック

RogerStaffordの貢献であるファイル交換から関数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

randfixedsum

于 2011-11-09T17:24:35.207 に答える
70

簡単な方法の1つは、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 =
1100-96 = 4

そして、あなたはそれを持っています、合計が100になる9つの数字:0、1、4、5、7、8、18、19、38。私が0を取得し、1がちょうど奇妙な運でした。

于 2011-11-09T12:04:31.703 に答える
6

正しい答えを出すのに遅すぎることはありません

Sum(X1、...、XN)が1に等しくなるように[0...1]の範囲でX1...XNをサンプリングすることについて話しましょう。次にそれを100に再スケーリングできます。

これはディリクレ分布と呼ばれ、以下はそこからサンプリングするコードです。最も単純なケースは、すべてのパラメーターが1に等しい場合で、X1、...、XNのすべての周辺分布はU(0,1)になります。一般に、パラメーターが1と異なる場合、周辺分布にピークが生じる可能性があります。

-----------------ここから取得---------------------

ディリクレは、それらの合計によって正規化された、単位スケールのガンマ確率変数のベクトルです。したがって、エラーチェックなしで、これにより次のことがわかります。

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);
于 2017-07-26T21:29:55.390 に答える
1

N-1の数値のリストを取得し、0と100を挿入してN + 1の数値のリストを作成し、リストを並べ替えて、合計N個の数値に差分します。

于 2016-07-18T07:54:11.193 に答える