質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Q&A

解決済

1回答

3338閲覧

ランダム値の重み付けに指数分布を使いつつ範囲を指定したい

argius

総合スコア9388

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

0グッド

0クリップ

投稿2016/08/26 07:33

言語は問いませんが、コード例としてJavaScriptのものを記載します。

ランダムに0~9の範囲の整数を求めるには、
擬似乱数生成関数の結果(0以上1未満) * (最大値 + 1) ※小数点以下切り捨て
で求めます。

一般的にはこのようなコードになると思います。

lang

1var max = 9; // 最大値 2var rn = Math.random() * (max + 1); // ランダム値(浮動小数点数) 3var result = Math.floor(rn); // 整数(切り捨て)

このランダム値に重みをつけたいです。

試しに、以下のように指数分布を使って求めました。

lang

1var lambda = 0.8; // 平均(必ず小数点以下をつける) 2var rn = -Math.log(Math.random()) / lambda; 3var result = Math.floor(rn);

この場合、指定できるパラメーターは平均で、範囲を決めることができません。
まれに大きな値が返されることがあります。
この結果を、0以上1未満で返すか、または範囲内の整数で返すようにするにはどうしたら良いでしょうか。

そもそも指数分布を使うのが間違いでしょうか?
単純に二次関数などを使って重み付けを行うべきでしょうか?
(二次関数で上手く行くことは確認済みです。)

よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

この場合、指定できるパラメーターは平均で

正確には,「指定できるパラメータは平均の逆数」だと思います.
なので,平均を0.8にしたければ,lambda = 1.0/0.8を指定する必要があります.

ちなみに,平均を0.25くらいにすると,だいたい0 <= P <= 1の範囲に収まります.
が,指数分布を使う限りMath.random()の値が1.0に近いと,結局無限大に近い値になります.

内部で使用する一様分布の範囲を調整して,平均を調整すれば不可能ではありませんが…
(例えば 0 から 0.9 までの一様分布で,平均を 0.43 くらいにする,とか)

投稿2016/08/26 10:16

編集2016/08/26 10:21
tamy

総合スコア442

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

argius

2016/08/26 11:33

回答ありがとうございます! ご説明いただいたとおりに、逆数を計算したうえで平均を0.25くらいにすることで 0 <= P <= 1の範囲が取れるようになりました。 > 指数分布を使う限りMath.random()の値が1.0に近いと,結局無限大に近い値になります. これは一応理解できています。 検査に使うわけではなく、厳密さはほとんど気にしていません。 大きい目が出やすいサイコロが欲しい程度のものです。 そうなると範囲外を捨ててしまうという実装にしてしまっても良いものでしょうか?
tamy

2016/08/26 12:52

> 指数分布を使う限りMath.random()の値が1.0に近いと すみません,この場合「0.0 に近いと」ですね. > そうなると範囲外を捨ててしまうという実装にしてしまっても良いものでしょうか? どうせ範囲外だとサイコロの目に変換しようがないと思うので,いいんじゃないですかね? どちらかというと,「計算結果から範囲外の値を捨てる」というより,「一様乱数の範囲を調整して,指数分布として範囲外の値が出ないようにする」方がスマートな気はしますが.
ozwk

2016/08/26 13:06

横からですが、 > 大きい目が出やすいサイコロが欲しい程度のもの ならば指数分布に拘る必要もないのでは?
argius

2016/08/26 13:32 編集

> この場合「0.0 に近いと」ですね そうですね。実際、JavaScriptでは乱数が0.0の時はInfinityになりました。 > 「一様乱数の範囲を調整して,指数分布として範囲外の値が出ないようにする」 それならできそうです。 このパラメータでは下限をおよそ0.01832に調整することで、 0 ≦ P < 1 の範囲で値が出せそうです。 ありがとうございました!
argius

2016/08/26 13:32

ozwkさん はい、特にこだわってはいません。 なにぶん知識不足で、このようなケースではどのような生成関数を使えば良いのか判断が付かなかったので、 「重み付けでランダム」で調べたところ、指数分布の例(で自分が理解できそうなもの)が比較的多く見つかったんですね。 それ以外には特に指数分布にする理由はありません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問