一定範囲内の数字をランダムでなるべく偏らず、複数取得したい

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
もうぞう

一定範囲内の数字をランダムでなるべく偏らず、複数取得したい

#1

投稿記事 by もうぞう » 9年前

これはC言語というより数学的な質問なんですが、
現在3Dゲームを制作しておりまして、
よくある「ダメージ値の数字が該当キャラの頭上に出てくる」モノを作りました。
現在は、「該当キャラの頭上の3次元座標+一定の振り幅( 例)-0.5~0.5 )の中でのランダム値」で座標を決め、ビルボードで表示しています。
しかし、これですと偶に重なり続けたりして見づらくなってしまいます。
商用ゲームだと極力重ならず、かつランダム性を持っているかの表示なのですが
どのようにすれば実現できるのでしょうか...
よろしくお願いします。


アバター
usao
記事: 1889
登録日時: 11年前

Re: 一定範囲内の数字をランダムでなるべく偏らず、複数取得したい

#3

投稿記事 by usao » 9年前

えっと,要するに,

ある領域内のN点をランダムで決める んだけど,
そのN点の配置は,なるべくなら近接しないでほしい(互いにある程度離れていてほしい)

みたいな話ですか?


なんかそんな感じの話として
「ポアソンディスクサンプリング」 とかいうのを聞いたことがあります.具体的な中身まで知りませんが.

簡単に誤魔化すなら,Nの最大数が決まっているなら
「前もって乱数で生成しまくってうまい感じのパターンを複数個見つけておいてそれを使う」
とかでもいいのかも?

TroughTheMorning

Re: 一定範囲内の数字をランダムでなるべく偏らず、複数取得したい

#4

投稿記事 by TroughTheMorning » 9年前

Dxライブラリを使っている場合を前提として、GetRand()で乱数を生成している場合、ちゃんとバラけていい感じの乱数を取得していると思いますけれど・・・。



乱数ジェネレータを使って、1~10の範囲で、1単位で10種類の乱数を生成すると仮定して、

1. 乱数の生成範囲を広げる。
  (一例:1000~10999の乱数を生成して、1000で割った商を使う。←特に差異は認められないと思う。)

2. 段階生成する。最終的に取得したい乱数範囲を均等に分割できる約数がない時には、使えません。
  但し、この方法で生成した乱数は、感覚的に偏りやすい気がする。←個人的な感想です。鵜呑みにしないでください。
  (一例:0~4の乱数Aと1~2の乱数Bの2種類を生成して、(2 * A + B)を取得した乱数として使う。)

3. 他の乱数生成法(計算法・ジェネレータ)でも試してみる。


1は、範囲を広げるほど精度が上がりそうですが、ジェネレータが元々広範囲の整数を使って乱数を生成している場合はほぼ無意味です。

2は、約数がたくさんあれば、一例の2段階生成だけでなく3段階・4段階と乱数生成ブロックを増やせますが、1から10の各数値の取得率は理論上は10%に収束しますので、普通に1段階で生成する場合と同じと考えてもよいと思います。

3は、根本的な部分を変える訳ですが、乱数自体が不確定な要素ですので、1→2→3→4→5→6→7→8→9→10→1→2→3...みたいに生成してくれる物でないとキレイにバラけないです。しかし、それではもはや乱数ではありませんね。



結果、確定的な要素がないと『極力重ならず』の部分は、実現はできそうにありませんね。

ご質問の意味は大筋では分かりますが、細かい事は文章からはちょっと読み取れません。
更に具体的に書いていただけると、ありがたいです。

hide

Re: 一定範囲内の数字をランダムでなるべく偏らず、複数取得したい

#5

投稿記事 by hide » 9年前

”いい感じ”の固定値の配列を数パターンほど手動で作ってしまうのもひとつの手だと思います。
必ずしもすべてアルゴリズム考えてやらなくても
楽につくって他のところに力を入れるのは間違いではないはずです。

ThroughTheMorning

Re: 一定範囲内の数字をランダムでなるべく偏らず、複数取得したい

#6

投稿記事 by ThroughTheMorning » 9年前

hide さんが書きました:”いい感じ”の固定値の配列を数パターンほど手動で作ってしまうのもひとつの手だと思います。
必ずしもすべてアルゴリズム考えてやらなくても
楽につくって他のところに力を入れるのは間違いではないはずです。
そうですね。イメージと言うか簡単なサンプルから入って慣れ親しんで、理論を考えるのはそれからでも遅くはないと思います。

私的には質問者さんの疑問が読み取り難しいのですが、

単純に重なるのを避けたいのであれば、重なった時に重ならない位置に移動してあげれば良いだけの話ですし・・・。

閉鎖

“C言語何でも質問掲示板” へ戻る