• ベストアンサー

(初心者)乱数のことで

使っているソフトはVisual c++です C言語で乱数を使うときにrandom関数を使ったんですが 帰ってくる値が一定なのでネットで検索したら 「メルセンヌ・ツイスタ」 を進めているサイトが多かったので ヘッダーファイルをダウンロードしてみたのですが メルセンヌ・ツイスタを プログラムに組み込む時どのように記述すればいいのか いろいろ試したのですがわかりませんでした メルセンヌ・ツイスタを組み込む構文の仕方を教えてください

  • ilice
  • お礼率27% (13/48)

質問者が選んだベストアンサー

  • ベストアンサー
  • sha-girl
  • ベストアンサー率52% (430/816)
回答No.3

>きわめて近い値になるんじゃないんですか? まったく同じ値になるんじゃないですか? 理由は(unsigned)time(NULL)が両方とも同じ、つまり ランダムシードが同じ値で、その10番目なので同じ数値になっているのです。 2番目のランダムシードをsrand((unsigned)time(NULL)+1);とすればまた全く違う値になるでしょう。 これはrandの精度の問題ではありません。 #include <stdlib.h> #include <stdio.h> int main() { int i,r1,r2; r1=r2=0; srand((unsigned)time(NULL)); for(i=0;i<10;i++)r1 = rand(); printf("%d\n",r1); srand((unsigned)time(NULL)+1); for(i=0;i<10;i++)r2 = rand(); printf("%d\n",r2); return 0; } 実行結果 1回目 25389 3267 2回目 779 11425 3回目 11425 22072 ちなみにrand自体は0からRAND_MAX(VCだと32767)の値までしか返しませんから、その範囲以外の値にしたいのなら 例えばrand() * (RAND_MAX+1) + rand()等の工夫が必要になります。 ただ乱数の精度を要求するにはrandで不足する場合ももちろんあります。 より厳密な乱数を使いたいなら、ネットを上に乱数生成のソース が転がっています。 boost等にもrandより精度の高い乱数生成の機能が用意されています。

その他の回答 (4)

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.5

srandやsrandomで初期化をきちんとしていたのなら それも書いていただけると良かったのですが。 順を追っていくと、MTにしても丸っきりの乱数を生成するものではない (ただし線形合同法などに比べれると格段に質よい擬似乱数が得られる)です。 ですので、ごく短時間に時間を種にするということをやるのなら MTを使っても同じ結果になるだけだと思います。 まず一つ目の質問として、擬似乱数の系列を変える必要はあるのでしょうか? もちろん簡単にした例だとは思いますが、#1の補足にある ものをみると、別に系列を新たにしなくてもいいような気がします。 もしどうしても複数の系列で行いたいというのであれば、 ごく短時間でもデータが変わるものを種にしてはどうでしょうか。 UNIXなら /dev/random を読むとかできますが、デバッグのことを考えると、たとえば 一段めとして時間で初期化して、適当に二個数値を取り出して、 それぞれを新たな乱数列の種に使うとか。 cmd.exeのコマンドラインなら %RANDOM% で 0~32767の乱数が得られるのですが これをプログラムからでは取るの画面度でしょう。 二つ目の質問ですが、MTを使おうとしてヘッダーファイルを ダウンロードしたとありますが、具体的にどのサイトの どのファイルでしょうか? わたしが検索したところ、1番目に引っかかったところにあったのは Cでのソースとドキュメントと出力例のもので ヘッダーファイルはなかったのですが?

ilice
質問者

補足

失礼しました ソースファイルですね

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.4

srand()は、rand()を使う前に1度だけ実行すれば十分です。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

MT云々の前に、 > 帰ってくる値が一定なのでネットで検索したら 乱数を生成する前にsrand 呼んでますか?

ilice
質問者

補足

呼んでいます。 でもそれだとsrandに使った種に対して一定の値しか帰ってこないし 時間を利用してsrandを使っても今度は狭い時間の範囲内しか乱数として取れませんでした

回答No.1

メルセンヌ・ツイスタのことはよく知らないのですが、 srandom関数で初期値を変えたりしましたか? 使っていないのであれば、乱数を生成するための初期値は毎起動時に一定なので、 何回起動しても、同じ乱数が同じように生成されます。 一般的には、 srandom((unsigned)time(NULL)); などをrandom関数を使う前に一度記述して、毎回違う乱数を生成するようにします。

ilice
質問者

補足

でもその記述方法で記述すると短い間隔で呼び出したときに きわめて近い値しかかえってこない気がするのですが たとえば int i,r1,r2; r1=r2=0; srandom((unsigned)time(NULL)); for(i=0;i<100;i++)r = rand(); printf("%d",r); srandom((unsigned)time(NULL)); for(i=0;i<100;i++)r = rand(); printf("%d",r); (前後略) という構文したとして このときのr1とr2の値は きわめて近い値になるんじゃないんですか? 質問ばかりですいません

関連するQ&A

  • 乱数 メルセンヌツイスターについて

    メルセンヌツイスター法(MT法)について少し調べることになったのですが、メルセンヌツイスターのサイトにC言語のソースがあったので動かしてみました。 確かに乱数が発生するのですが、ソースをみてもどういう動きで乱数を生成してるのかがわかりません。 メルセンヌツイスターはどうやって乱数をつくりだしているのでしょうか? わかる方がいらっしゃいましたら、教えてください。

  • 乱数を発生させるプログラムを教えてください。

    タイトルのままなのですが、1から100までの乱数を発生させるプログラムを知りたいです。 乱数をxとおくと、xの値は、0<x<1の範囲内でお願いします。 C言語で、rand関数を用いて、どうかお願いします。

  • 乱数をC言語で

    乱数をC言語でプログラムしたいのですが、 rand関数を使わずに作らなきゃいけないという事なんですが 一度作ってはみたもののうまく乱数にできずに困っています できれば教えていただきたいです

  • 乱数発生関数randomなど

    random, srandom, initstate, setstate で乱数を生成できることを知りましたが、運用方法がよくわかりません。c言語に詳しい方、for文を使って乱数を5個ほど表示させるプログラムを示してください。

  • C言語 乱数

    C言語 乱数 プログラミングの宿題なのですが、よく分かりません。教えていただける方、よろしくお願いします。 ・表示する文字数の長さは12とする。 ・表示する文字は毎回ランダムで表示すること。 ・文字は英字のうち、小文字のみとする。 ・プログラムにrandom()を使うこと。 ・プログラムにsrandom()を使うこと。 よろしくお願いします。

  • 乱数を扱いたい

    Active Basicでプログラムの練習をしています。 今回、乱数を扱いたいのですが、どうしても分かりません。 例えば、1~100までの整数を用意して、その中から数字をランダムで1つ取り出すっと言ったことをしたいのですが・・・・ ((例:58 など)) Rnd( )と言う関数があるようなのですが、いまいち使い方がよく分かりません。 他の関数を使用するのかも分かりません。 すみませんが、どなたか知っていましたら、ご教授願います。

  • 乱数について

    こんばんは。 何度も申し訳ありませんが、今回は乱数について教えてください。 LinuxでCを勉強しているんですが、 randで乱数を発生させることはできたんですが、 そのプログラムを何度実行させても 出てきた乱数は同じ値なんです。 プログラム内で例えば10こ乱数を発生させたとすると 違うものが出ます。 しかし、もう一度そのプログラムをはしらせると 前回と全く同じ並びで同じ数が出るのはどうしてでしょうか? 言ってる意味わかっていただけましたでしょうか? 宜しくお願いします。

  • メルセンヌツイスターによる乱数の使い方

    メルセンヌツイスターによる乱数を生成したいのですが、下記コードにすると、mt_rand関数を呼ぶたびにシードが初期化され他乱数が生成されます。 やりたいことは、main関数で一度シード101で初期化した後は、mt_rand関数内では、初期化することなく継続した乱数を生成したいのです。 そのためa_mt_rand関数のようにすると、mtが定義されていないとなるエラーとなります。 namespaceの問題と思うのですが、色々試してみましたが、できませんでした。 どのようにすればできるでしょうか。 vc++11、windows11 使用 参考サイト C++ 乱数ライブラリ std::random の使い方 リンクはうまく貼れませんでした。 #pragma hdrstop #include <iostream> #include <stdio.h> #include <random> using namespace std; void mt_rand(void); int main(int argc, char *argv[]) { int ptr; std::mt19937 mt(101); // メルセンヌツイスターの32ビット版、引数は初期シード std::uniform_int_distribution <> rand100(0, 100); // [0, 99] 範囲の一様乱数 ptr = rand100(mt); printf("ptr=%d\n",ptr); mt_rand(); } void mt_rand(void) { int ptr=0; std::mt19937 mt(101); // メルセンヌツイスターの32ビット版、引数は初期シード std::uniform_int_distribution <> rand100(0, 100); // [0, 99] 範囲の一様乱数 ptr = rand100(mt); printf("%d\n",ptr); } void a_mt_rand(void) { int ptr=0; ptr = rand100(mt); printf("%d\n",ptr); }

  • プログラミングの乱数

    c言語、c++の乱数rand()の使い方がよくわかりません。わかりやすい説明をお願いします。 あと、プログラミングが得意な方にお願いです。 [0,1]乱数で平均と分散を求めるプログラムを配列なしで作ってください。

  • C++ 初心者です

    C++ 初心者です visual C++ 2010をつかって作業しているのですが 作業が進まなくなってしまい困っています・・・・ 今は「二乗する」や「半分にする」といった関数を作って 目標の値にこれをランダムで何回か実行していきその値を出したいと思ってるのですが、 ランダムに実行していく過程が難しいです どなたか助けてはいただけないでしょうか? また、なにかいたらない点がありましたらご指摘お願いします。

専門家に質問してみよう