- ベストアンサー
三角分布に従う乱数
三角分布に従う乱数を発生させるプログラム 最頻値gで、0.8g~2.5gの範囲の三角分布(当然面積は1です)に従う乱数を発生させるプログラムを 書きたいと思っています。 この三角分布の確率密度関数をP(x)とすると、三角分布であるので最頻値gの左側である、傾きが正の直線h(x)と 最頻値gの右側である、傾きが負の直線f(x)で表せますよね 分布に従う乱数を発生させるためには、これら直線の関数を積分したものの逆関数x=P^-1(u) (Pのインバースです) (uは区間[0, 1]の一様乱数)とすればいいというところまでわかったんですが、 とりあえずh(x)とf(x)をそれぞれ積分して逆関数H^-1(u)、F^-1(u)を求めたところまではいいんですが x=H^-1(u)+F^-1(u)としてプログラムを実行すると、最頻値gの2倍あたりの値(例えば20に対して39など) しか出ず、最頻値gより小さい値が出ません。 H^-1(u)+F^-1(u)としているのがダメだと思うのですが、逆関数が2つある場合、ここからどうすればいいですか? また、初歩的な質問なのですが、区間[0, 1]の一様乱数というのはどう記述すればよいですか? ぜひ多くの方の回答お待ちしています。 よろしくお願いします。 (最頻値gは入力で与えるものとします)
- ou_gakusei
- お礼率66% (6/9)
- 数学・算数
- 回答数4
- ありがとう数5
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
最頻値がgで[a, b]の範囲で三角分布に従う乱数を発生させたいとします。 まず、確率密度関数を求めると、 (-∞, 0] : 0 (a, g] : 2(x-a)/{(g-a)(b-a)} (g, b] : 2(x-b)/{(g-b)(b-a)} (b, ∞) : 0 分布関数は確率密度関数を積分して、 (-∞, 0] : 0 (a, g] : (x-a)^2/{(g-a)(b-a)} (g, b] : (g-a)/(b-a)+(x^2-2bx-g^2+2bg)/{(g-b)(b-a)} (b, ∞) : 1 分布関数の逆関数を求めると、 (-∞, 0] : a (0, (g-a)/(b-a)] : a+sqrt((g-a)(b-a)x) ((g-a)/(b-a), 1] : b-sqrt((b-g)^2-(b-g)(b-a)(x-(g-a)/(b-a))) (1, ∞) : b となりますので、xは0以上1以下の値が入っているとすれば、 if (x <= (g-a)/(b-a)) return a+sqrt((g-a)(b-a)x); else return b-sqrt((b-g)^2-(b-g)(b-a)(x-(g-a)/(b-a))); とでも書けばいいでしょう。 (実際に書く場合は、もう少し計算量が少なくなるように書くとは思いますが) 計算があっているかどうかは確認しておいてください。
その他の回答 (3)
- Ishiwara
- ベストアンサー率24% (462/1914)
ふつうの長方形分布の乱数を発生させ、条件に合わなければ捨ててしまう、というやり方が一番簡単です。
ANo.2 思いっきり間違いました。 こちらが正しいです。 if (x <= (g-a)/(b-a)) return a+sqrt((g-a)*(b-a)*x); else return b-sqrt((b-g)*(b-g)-(b-g)*(b-a)*(x-(g-a)/(b-a)));
言語は何を使われているのかわかりませんが、if文等で条件分岐をするのは駄目なのでしょうか? > また、初歩的な質問なのですが、区間[0, 1]の一様乱数というのはどう記述すればよいですか? rand関数というような関数がありませんか? 名前は違うかもしれませんが、必ず乱数を発生させる関数があるはずです。 ひょっとして、0からnまでの整数の乱数は得られるけど、[0, 1]の一様乱数をどうやって得るのかわからないということでしょうか? (C言語なら(double)rand() / RAND_MAXとでもすればいいですが)
お礼
回答ありがとうございます。 言語はC++です。乱数わかりました。 if文等で条件分岐をするというのは どういう条件のときにどういう動作をすればよいのかが難しいです・・
関連するQ&A
- 三角関数の乱数について
シミュレーションで用いる為に、 cos^2(θ) (コサイン2乗θです、θは0~90度の範囲) に従う乱数を作成しなければいけません。 (具体的な内容としましては、θを地表と鉛直方向の角度とすると、入射するN(粒子数)が、cos^2(θ)に比例し、それに沿った粒子を大量に発生させる必要がある為) プログラムはC++で書いています。 自分なりに調べて、 確率密度関数をf(x)としたとき、その累積分布関数g(x)の逆関数、 G(x)=g^-1(x)を求め、G(rand())として得られる、という所まではわかったのですが、 昔から数学が苦手な為、 f(θ)=cos^2(θ) g(θ)=(sin2θ)/4 + θ/2 で、これからG(θ)を求める方法がわかりません。 (これは非線型の逆関数でしょうか?) これだけなら数学の方に書くべきかもしれませんが、 このような三角関数の乱数の求めかたはプログラミングの分野で既に周知かなと思いこちらで質問しました。 どうすればいいかご助言を頂きたいです。 求められるのであれば上記の方法の続きでなくともなんでも構いません。 私はプログラム初心者で、まだ知らない便利な関数があり見落としているかもしれないです。 よろしくお願い致します。
- ベストアンサー
- C・C++・C#
- 標準正規分布の乱数
RAND()関数は ((double)rand() / (1.0 + RAND_MAX))と定義します。 中心極限定理により、一様乱数を足し合わせると正規分布に近づくことから、 x = 分散 * (Σ[1~12]RAND() - 6) + 平均 で正規乱数が作れる。標準正規分布は分散1、平均0なのでその乱数は x = Σ[1~12]RAND() - 6 ですよね。この乱数を例えば100個羅列するにはどうしたらいいのでしょうか? もし間違ってたら指摘してください。 参考文献「Cによるシミュレーションプログラム 石川宏」 #include <stdio.h> #include <stdlib.h> #define RAND() ((double)rand() / (1.0 + RAND_MAX)) #define NUMBER 10000 /* 発生させる乱数の数 */ main(void) { int j; double u, x; srand(5); for (j = 0; j <= 11; j++) { u = u + RAND(); } x = u - 6.0; }
- ベストアンサー
- C・C++・C#
- 正規分布に従う乱数を発生させるには?
0以上1未満の実数のうちから均一な確率で乱数を発生できるものがあるとします。 (頭にあるのはプログラムのrnd関数です)。 この乱数をxとしたとき、このxを適当な変換式f=f(x)に代入して 正規分布に従うような数yを得たいと思います。 どうすればよいでしょうか?
- ベストアンサー
- 数学・算数
- 乱数発生の関数。
確率分布関数が次の表で与えられているとき,この分布に従う乱数を線形補間を使った逆変換によって生成する関数をどうやって作成したらいいか、全くわかりません。線形補間はなんとなくわかるんですが…。どなたか教えてください。 x F(x) 0 0.0024788 1 0.0173513 2 0.0619688 3 0.1512039 4 0.2850565 5 0.4456796 6 0.6063028 7 0.7439798 8 0.8472375 9 0.9160760 10 0.9573791 11 0.9799080 12 0.9911725 13 0.9963715 14 0.9985996 15 0.9994909 16 0.9998251 17 0.9999431 18 0.9999824 19 0.9999948 20 0.9999985 21 0.9999996 22 0.9999999 23 1.0000000
- ベストアンサー
- C・C++・C#
- Yの分布関数
r.v.Xの分布関数F(x)が F(x)=1 (2≦x) =(1/4)x^2 (0≦x<2) =0 (x<0) であるとき (1)P(1≦X≦3)の値を求めよ。 (2)Y=2X+1とするとき、Yの分布関数G(x)を求めよ。 この問題についてお聞きしたいです。 (1)は自分で解いてみたところ、表記が難しいので計算の過程は略しますが、答えが19/12となりました。 (2)はG(x)=P(Y≦x)=P(2X+1≦x)=P(X≦(x-1)/2)_(ⅰ)とした時点で行き詰ってしまいました。 Y=~となるとXの分布関数を求めるときとどのように解法の仕方を変えればよいのでしょうか。 (ⅰ)をどのように適用したらよいのかわからないのでどなたか教えてください。 よろしくお願いします。
- ベストアンサー
- 数学・算数
- 分布関数と一様分布の関係について
Xを連続型の確率変数として、その分布関数をF(X)としたとき、F(X)は一様分布U[0,1]に従うみたいなのですが、理解できません。初歩的な質問ですがよろしくお願いします。
- ベストアンサー
- 数学・算数
- 正規分布の分布関数について
G(x)…標準正規分布の分布関数 f(x)…標準正規分布の密度関数 x…標準正規分布に従う確率変数 とするとき G[(C-ρx)/√(1-ρ)] の xに関する期待値が G(C) になるようなのですが、どうしてでしょうか? (G[(C-ρx)/√(1-ρ)] の 期待値)=∫[-∞~∞]G[(C-ρx)/√(1-ρ)]*f(x)dx となると思いますが、これをどう変形したらG(C)に等しくなるのでしょうか。 教えてください。
- 締切済み
- 数学・算数
お礼
分かりやすい回答をどうもありがとうございました。 おかげでちゃんと実行することができました。 私のはそもそも積分が間違っていたようです。 詳しい解説、本当にありがとうございました。