乱数の検定

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

乱数の検定

#1

投稿記事 by minami » 18年前

はじめましてminamiと申します。
C言語を始めてまだ1ヶ月弱という初心者です。

初心者ということで課題については徐々にステップアップしながらの勉強なのですが
「乱数の連検定」ぽいプログラムでつまづいてしまいました。

今やってるプログラムは「”rand()%10”で作った一桁の擬似乱数の連検定」です。
たとえば乱数が[1.4.6.5.3.7.9.6.5.4.3.7.4.2.3.4.0.9.0.5.4.2.4.5.6.・・・・(一万個の乱数)]という具合にあるとしたら
[1.4][4.6][6.5]・・・・という並びがいくつずつあるのか?を検定するものです。
つまり[00]が何個、[01]が何個、[02]が何個・・・[98]が何個、[99]が何個、というように数えていくものです。
とりあえず下記のプログラムを作ったのですが、一応はちゃんとした結果は出ます。
ただ、for文でグルグルまわして無駄な処理を10000×10000回やってるので、自分でもいまいちなものになってます。
#include<stdio.h>

int main (void)
{
        int i,j,k,m,n;
        int ransu[15000][10];
        int count;
        FILE*fp;

        //rand1.txtに擬似乱数を書き込む
        fp = fopen("rand1.txt", "w");
        for(i=0;i<10000;i++){
                fprintf(fp,"%d\n",rand()%10);
        }
        fclose(fp);

        //rand1.txtから擬似乱数をransu配列に書き込む
        fp = fopen("rand1.txt","r");
        for(i=0; i<10000; i++){
                fscanf(fp, "%d",&ransu[0]);
        }
        fclose(fp);

 
        //擬似乱数の連検定
        for(k=0; k<10; k++){
            for(m=0; m<10; m++){
                count=0;
                for(n=0; n<10000; n++){
                    if(ransu[n][0]==k && ransu[n+1][0]==m)
                        count++;
                }
             printf("%d\t",count);
            if(m!=0 && m%9==0)printf("\n");
            }
        }
 }


配列[00]~[99]までをあらかじめ用意しておいて、rand()関数で乱数を発生させると同時に
[1.4.6.5.3.7.9.6.5.4.3.7.4.2.3.4.0.9.0.5.4.2.4.5.6.・・・・(一万個の乱数)]という乱数なら
1.4が出た時点で配列[14]に入れる、4.6が出たら配列[46]に入れるというようなプログラムって出来るものなんですか?

わかりにくい説明でスンマセン m(__)m
ヘルプお願いします。

バグ

Re:乱数の検定

#2

投稿記事 by バグ » 18年前

[1, 2, 3, 4, 5, 6, 7, 8, 9, 0 … (10000個の乱数)]

の場合は、[12][23][34][45][56][67][78][89][90]という感じで検出されるという事でしょうか?

minami

Re:乱数の検定

#3

投稿記事 by minami » 18年前

TO バグさん
FM minami

バグさんの言うとおりです。

バグ

Re:乱数の検定

#4

投稿記事 by バグ » 18年前

こんな感じでいかがでしょうか?
分からない部分があったら、また聞いて下さいね(^-^)
#include	<stdio.h>
#include	<stdlib.h>
#include	<time.h>
#include	<memory.h>

int main(void)
{
	int	i, nIndex, nVal[10000], nCnt[100];

	/* 乱数発生用の前準備 */
	srand((unsigned)time(NULL));

	/* カウント用配列を0で初期化する */
	memset(nCnt, 0, sizeof(int) * 100);

	/* 10000個の乱数を準備する */
	for (i = 0; i < 10000; i++)
	{
		nVal = rand() % 10;

		/* 2回目のループ以降に毎回組み合わせを調べる */
		if (i > 0)
		{
			/* 1つ前の乱数値を10倍した数値と、今回の乱数値を足す事でIndexを作成する */
			nIndex = nVal * 10 + nVal;

			/* 求められたIndex場所のカウントを1つ足す */
			nCnt[nIndex]++;
		}
	}

	/* カウント用配列の中身を表示する */
	for (i = 0; i < 100; i++)
	{
		printf("%d = %d\n", i, nCnt);
	}

	return 0;
}

フリオ

Re:乱数の検定

#5

投稿記事 by フリオ » 18年前

 
 これでできると思います。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
	int array[100] = {0,};
	int num0, num1, i;
	
	srand((unsigned)time(NULL));
	num0 = rand() % 10;
	for(i = 1; i < 10000; i ++){
		num1 = rand() % 10;
		array[num0 * 10 + num1] ++;
		num0 = num1;
	}
	for(i = 0; i < 100; i ++) printf("%02d %d\n", i, array);
	return 0;
}

 

バグ

Re:乱数の検定

#6

投稿記事 by バグ » 18年前

minamiさんのソースにファイルからの読み書きがあったので、一度は配列に格納しておいた方が改造しやすいかと思ったのですが、確かにフリオさんの方がスマートですね(^-^)

minami

Re:乱数の検定

#7

投稿記事 by minami » 18年前

バグさん、フリオさん回答ありがとうございます。
お二人のソースコードを見ると、自分の書いたプログラムがいかに無駄が多いか分かりました。
参考にさせてもらいます。

これからもお二人のようなプログラムが書けるように精進します。

本当にありがとうございました。

閉鎖

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