1時間ごとに更新!Amazon.co.jpで今売れている本トップ100   掲示板ランキング



掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板1

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧

No.6096

正規乱数の度数分布。
投稿者---紗月(2006/07/08 13:33:35)


正規乱数のヒストグラムを作りたいのですが、どう作っていけばいいかまったくわかりません。実行結果は下記の通りです。
どなたかわかるかたがいらっしゃいましたら教えていただけませんか?
よろしくお願いします。


0: 
1:
2: *
3: **
4: ***
5: *******
6: ************
7: ******************
8: ************************
9: ********************************
10:***********************************
11:***************************
12:*********************
13:*************
14:******
15:****
16:**
17:*
18:*
19:
20:



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:正規乱数の度数分布。 6097 ruby 2006/07/08 14:27:56


No.6097

Re:正規乱数の度数分布。
投稿者---ruby(2006/07/08 14:27:56)


>正規乱数のヒストグラムを作りたいのですが、どう作っていけばいいかまったくわかりません。実行結果は下記の通りです。

現状の知識レベルはどういったものでしょうか。

1)正規乱数の求め方がわからない。
2)正規乱数の求め方はわかっているけれど、どのようにプログラムを作ればいいかがわからない。
3)その他。


この投稿にコメントする

削除パスワード

No.6098

Re:正規乱数の度数分布。
投稿者---紗月(2006/07/08 14:36:17)


正規乱数の求め方もよくわからなくて、どのようにプログラムを作っていけばいいのかわかりません。

(double)rand()/(double)(RAND_MAX)-0.5;
というのだけ教えてもらいましたが、それでもよくわかりません。



この投稿にコメントする

削除パスワード

No.6099

Re:正規乱数の度数分布。
投稿者---ruby(2006/07/08 15:09:15)


>(double)rand()/(double)(RAND_MAX)-0.5;

これだと、-0.5から+0.5までの擬似的な一様乱数を発生することになり、
当初の目的である正規乱数を発生することにはならないと思うのですが…。

正規乱数の求め方についてはここの掲示板の範囲を超えると思います。
ググってみるとか数学の本をお読みになるとかして、
まずはご自分でお調べになってみてください。

0から20までの正規乱数を全部で100個求めたとすると、
例えばransuu[0]=1, ..., ransuu[10]=30, ..., ransuu[20]=2
(ただし、1+...+30+...+2=100)
という風に各々の度数が求まります。
求めた度数を、No.6096の図のとおり'*'を使って出力すれば、完成です。
がんばってみましょう。


この投稿にコメントする

削除パスワード

No.6100

Re:正規乱数の度数分布。
投稿者---Hermit(2006/07/08 15:11:45)


正規分布は、ボックスミューラ法が楽でいいと思うけど。


この投稿にコメントする

削除パスワード

No.6101

Re:正規乱数の度数分布。
投稿者---紗月(2006/07/08 15:29:07)


rubyさん、hermitさん解答ありがとうございます。

いろいろ調べてボックスミュラー法っていうのを知ったのですが、よくわかりませんでした。
わかりやすそうなサイトがあったんですが
私の使っているBorland C++だとコンパイルできなかったんです。

そのソースはこういったものです。

#include<stdio.h>
#include<math.h>
#include<stdlib.h>

#define MAX_BUF 10000

int main( int argc, char *argv[] )
{
int n = 0;
double min = 0.0;
double max = 0.0;
int size = 0;

double d = 0.0;
double data = 0.0;
int freq[ 10 ];
int maxfreq;
double g2 = 0.0;
char Line[ MAX_BUF ];
int k;

if( argc != 4 )
{
fprintf( stderr, "Usage: generate mean sd count\n" );
exit( EXIT_FAILURE );
}
if( sscanf(argv[1], "%lf", &min) != 1 )
{
fprintf( stderr, "min is not numeric\n" );
exit( EXIT_FAILURE );
}
if( sscanf(argv[2], "%lf", &max) != 1 )
{
fprintf( stderr, "max is not numeric\n" );
exit( EXIT_FAILURE );
}
if( sscanf(argv[3], "%d", &size) != 1 )
{
fprintf( stderr, "size is not numeric\n" );
exit( EXIT_FAILURE );
}

for( k=0; k<10; k++ )
freq[k] = 0;

d = ( max - min ) / 10.0;

while( fgets(Line, MAX_BUF, stdin) )
{
if( sscanf(Line,"%lf",&data) == 1 )
{
if( data < min ) continue;
if( data > max ) continue;
for( k=1; k<=10; k++ )
if( data < min + k*d )
{
freq[k-1]++;
break;
}
}
}

maxfreq = freq[0];
for( k=1; k<10; k++ )
{
if( freq[k] > maxfreq )
maxfreq = freq[k];
}

for( k=0; k<10; k++ )
{
int t, c = (int)(size * ( (double)freq[k] )/maxfreq );
printf( "%5.1f - %5.1f (%5d) : ", min+k*d, min+(k+1)*d, freq[k] );
for( t = 0; t<c; t++ )
putchar( '*' );
putchar( '\n' );
}

return EXIT_SUCCESS;
}





この投稿にコメントする

削除パスワード

No.6102

Re:正規乱数の度数分布。
投稿者---Hermit(2006/07/08 15:48:53)


昔作ったやつがあるから、そのままコピペします。
ちょっと仕様が違うのと、駄目な例も入っているので注意。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define PI 3.1415926535
double Rand_stdevp0(void)
{                            /* 一応セオリーどうり */
    static int alpha;
    static int beta;
    double ret;
    if (alpha == 0) {
        alpha = rand(), beta = rand();
        ret =
            sqrt(-2.0 * log((alpha + 1) / (double) (RAND_MAX + 1))) *
            sin(2.0 * PI * (beta / (double) RAND_MAX + 1));
    } else {
        ret =
            sqrt(-2.0 * log((beta + 1) / (double) (RAND_MAX + 1))) *
            sin(2.0 * PI * (alpha / (double) RAND_MAX + 1));
        alpha = 0;
    }
    return ret;
}

double Rand_stdevp1(void)
{                            /* rand() の呼び出しをふんだんに使ってます。これで十分 */
    return sqrt(-2.0 * log((rand() + 1) / (double) (RAND_MAX + 1))) *
        sin(2.0 * PI * (rand() / (double) RAND_MAX + 1));
}

double Rand_stdevp2(void)
{                            /* rand() ひとつだけ たぶん不十分 */
    int tmp = rand();
    return sqrt(-2.0 * log((tmp + 1) / (double) (RAND_MAX + 1))) *
        sin(2.0 * PI * (tmp / (double) RAND_MAX + 1));
}

int main()
{
    int i;
    double sum = 0.0, level = 0.0;
    static int buff[50];

    srand(time(NULL));

    for (i = 0; i < 10000000; i++) {
        double no = Rand_stdevp0();
        buff[(int) ((no + 5.0) * 5.0)] += 1;
        sum += no;
        level += no<0.0 ? no : -no;
    }
    for (i = 0; i < 50; i++)
        printf("%3d:%*c\n", i, buff[i] / 20000, 'o');

    sum = 0.0, level = 0.0;
    memset(buff, 0, sizeof(buff));
    for (i = 0; i < 10000000; i++) {
        double no = Rand_stdevp1();
        buff[(int) ((no + 5.0) * 5.0)] += 1;
        sum += no;
        level += no < 0.0 ? no : -no;
    }
    for (i = 0; i < 50; i++)
        printf("%3d:%*c\n", i, buff[i] / 20000, 'o');

    sum = 0.0, level = 0.0;
    memset(buff, 0, sizeof(buff));
    for (i = 0; i < 10000000; i++) {
        double no = Rand_stdevp2();
        buff[(int) ((no + 5.0) * 5.0)] += 1;
        sum += no;
        level += no<0.0 ? no : -no;
    }
    for (i = 0; i < 50; i++)
        printf("%3d:%*c\n", i, buff[i] / 20000, 'o');

    return 0;
}





この投稿にコメントする

削除パスワード

No.6103

Re:正規乱数の度数分布。
投稿者---紗月(2006/07/08 20:59:31)


ありがとうございます。
質問なんですが

memset(buff, 0, sizeof(buff));

の意味がよくわからないんですが、教えていただけますか?


この投稿にコメントする

削除パスワード

No.6104

Re:正規乱数の度数分布。
投稿者---ruby(2006/07/08 21:25:59)


>memset(buff, 0, sizeof(buff));

C言語の標準関数ですので、インターネットや書籍など、
ご自分で調べる方法はいくらでもあります。


この投稿にコメントする

削除パスワード

No.6105

Re:正規乱数の度数分布。
投稿者---Hermit(2006/07/09 00:27:55)


>質問なんですが
>memset(buff, 0, sizeof(buff));
>の意味がよくわからないんですが、教えていただけますか?
各値の数を初期化してるだけです。
数えた個数を全て0個に戻しているだけ。
似た計算を3回やっているので、各処理が終わった後始末です。
正規分布には特に関係が無いですが、表示の為だけです。

いらない処理が多すぎたので、もうちょっとコンパクトに書き直してみました。
やってることは、前のとほぼ一緒です。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define PI 3.1415926535
#define COUNT 1000000
double Rand_stdevp(void) { /* 簡単な方にしました */
    return sqrt(-2.0 * log((rand() + 1) / (double) (RAND_MAX + 1))) *
    sin(2.0 * PI * (rand() / (double) RAND_MAX + 1));
}
int main()
{
    int i;
    double average = 0.0,average2 = 0.0;
    static int buff[50];
    srand(time(NULL));
    for (i = 0; i < COUNT; i++) {
        double no = Rand_stdevp();
        buff[(int) ((no + 5.0) * 5.0)] += 1;
        average += no; /* 平均と標準偏差用 */
        average2 += no * no; /* 標準偏差用 */
    }
    for (i = 0; i < 50; i++)
        printf("%5.2f:%*c\n", (double)i/5.0-4.9, buff[i] / (COUNT/500), 'o');
    average /= COUNT; /* これで平均 */
    average2 /= COUNT;/* 2乗の平均 */
    printf("平均 = %f\n",average);
    printf("σ = %f",sqrt(average2-average*average));
    return 0;
}


一応普通の標準偏差なので、平均はほぼ 0.0、σがほぼ 1.0 みたいですね。
使っている値が整数値なので、無限値は出来そうに無いので、
最初の設計時、+-5σくらいの範囲だったからこの値にした気がします。


この投稿にコメントする

削除パスワード

No.6111

Re:正規乱数の度数分布。
投稿者---紗月(2006/07/10 23:56:24)


返信ありがとうございました!!
助かりました。




この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧





掲示板提供:(有)リアル・インテグリティ