• ベストアンサー

乱数と確率

今、100人の人がいて、そのうちの1人が風邪をひいています。 感染率をAとして、10日間経過する間にどのくらいの人が風邪をひくのか乱数を用いてシミュレーションしたいのですが、どのようにすればいいのかわかりません。このとき各個人が風邪を引く確率をA×(前日に風邪をひいている人数)とします。 感染率は最初に打ち込むんですが、例えば0.1とうちます。 そうすると初日に風邪を引いているのは1人なので次の日に各個人が風邪を引く確率も0.1になります。 このとき、99人のうち何人が風邪を引くのかという人数の算出方法がわかりません。どうやらDeseaseという関数を使うらしいのですが^^; それと、このときまずはじめに要素を100個持つ配列を宣言し、1つの要素以外はすべて0で初期化するっぽいのですがこのやり方もわかりません^^; よければ教えてください!!

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

  • ベストアンサー
noname#119918
noname#119918
回答No.6

void diseaseを微修正しました。 こちらのBCC Developerではこれで正常にコンパイル、実行が可能です。 これでいかがでしょうか。 (再度の確認となりますが、エラーメッセージは要約せずに「そのまま」載せていただいた方がこちらとしては助言をしやすいです。) #include <stdio.h> #include <stdlib.h> #include <time.h> const int NUM = 100; // 人数 const int DATE = 10; // 実験日数 const int HEALTHY = 0; // 健常者 const int INFECTED = 1; // 感染者 /* 配列の初期化 @param people 人間配列 @param num 人数 */ void init(int* people , int num) { int i; people[0] = INFECTED; for(i=1 ; i<num ; i++) { people[i] = HEALTHY; } } /* 感染者数を数える @param people 人間配列 @param num 人数 @return 感染者数 */ int infectee_count(int* people , int num) { int i; int infected = 0; for(i=0 ; i<num ; i++) { if(people[i] == INFECTED) { infected++; } } return infected; } /* @param people 人間配列 @param num 人数 @param initial_prob 初期感染率 */ void disease(int* people , int num , double initial_prob) { int i; double p = initial_prob * infectee_count(people , num); double rand_val; for(i=0 ; i<num ; i++) { if(people[i] == INFECTED) // 既に感染している { continue; } rand_val = (double)rand() / (double)RAND_MAX; // 0~1の乱数を得る if(rand_val < p) { people[i] = INFECTED; } } } /* 感染シミュレート @param num 人数 @param date 日数 */ void simulate(int num , int date) { int i; double initial_prob; // 配列の確保 int* people = (int*)malloc(sizeof(int) * num); if(people == NULL) { perror("simulate"); exit(EXIT_FAILURE); } // 初期感染率の入力 printf("infection probability > "); scanf("%lf" , &initial_prob); srand(time(NULL)); init(people , num); // 指定の日数、実行する for(i=0 ; i<date ; i++) { disease(people , num , initial_prob); printf("%d %d\n" , i , infectee_count(people , num)); // 経過日数、感染者数を表示 } free(people); } int main(void) { simulate(NUM , DATE); return 0; }

amel10
質問者

お礼

参考になりました。ありがとうございます^^

その他の回答 (5)

noname#119918
noname#119918
回答No.5

>いろいろ試したんですが、Countのところで宣言の構文エラーと出てしまいます。 >何がいけないんでしょうか? "Count"という宣言はありませんが… エラーメッセージをそのまま載せてもらえますか? プログラムを作成している環境(OS,コンパイラ等)も合わせて 提示していただけると、早期解決に結びつくと思います。

amel10
質問者

補足

OSはWindowsで、BCC Developerというソフトを使っています。 int ~_count~のところで「宣言の構文エラー」とでました。 それと、HKBさんが書かれた、int ~_count(int* ~ , int ~)の部分で、コンパイルすると「)がありません」というエラーがでて、 int N_count)(int* Score[SIZE] , int SIZE)とすると「宣言の構文エラー」とでました。

noname#119918
noname#119918
回答No.4

あまり良くないとは思ったのですが、C言語の理解が不十分なようですので、ソースコードを載せます。 コメントを細かく書いておきましたので、読んで理解に努めてください。 (バグがあるかもしれませんが、それを取り除くのも練習です。) #include <stdio.h> #include <stdlib.h> #include <time.h> const int NUM = 100; // 人数 const int DATE = 10; // 実験日数 const int HEALTHY = 0; // 健常者 const int INFECTED = 1; // 感染者 /* 配列の初期化 @param people 人間配列 @param num 人数 */ void init(int* people , int num) { int i; people[0] = INFECTED; for(i=1 ; i<num ; i++) { people[i] = HEALTHY; } } /* 感染者数を数える @param people 人間配列 @param num 人数 @return 感染者数 */ int infectee_count(int* people , int num) { int i; int infected = 0; for(i=0 ; i<num ; i++) { if(people[i] == INFECTED) { infected++; } } return infected; } /* @param people 人間配列 @param num 人数 @param initial_prob 初期感染率 */ void disease(int* people , int num , double initial_prob) { int i; double p = initial_prob * infectee_count(people , num); for(i=0 ; i<num ; i++) { if(people[i] == INFECTED) // 既に感染している { continue; } double rand_val = (double)rand() / (double)RAND_MAX; // 0~1の乱数を得る if(rand_val < p) { people[i] = INFECTED; } } } /* 感染シミュレート @param num 人数 @param date 日数 */ void simulate(int num , int date) { int i; double initial_prob; // 配列の確保 int* people = (int*)malloc(sizeof(int) * num); if(people == NULL) { perror("simulate"); exit(EXIT_FAILURE); } // 初期感染率の入力 printf("infection probability > "); scanf("%lf" , &initial_prob); srand(time(NULL)); init(people , num); // 指定の日数、実行する for(i=0 ; i<date ; i++) { disease(people , num , initial_prob); printf("%d %d\n" , i , infectee_count(people , num)); // 経過日数、感染者数を表示 } free(people); } int main(void) { simulate(NUM , DATE); return 0; }

amel10
質問者

補足

いろいろ試したんですが、Countのところで宣言の構文エラーと出てしまいます。 何がいけないんでしょうか?

回答No.3

> 2のところですが、Count関数を使うんですよね? Count関数を"あなたが作る"のでしたらYES. C/C++にはCountなんて標準関数は"ありません" > Nの設定の仕方とかがよくわからないんです・・・ 1. N = 0 2. i = 0 .. 99 に対し、data[i] == 1 なら Nに1を加える これだけのこと。なにがわからんのかさっぱりわからん。

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

>Desease disease の間違いでない? で、この関数を適当な引数で呼び出すと感染するかしないかを判定してくれるつくりになってるとか。 あと、 >このとき各個人が風邪を引く確率をA×(前日に風邪をひいている人数)とします。 仮にAを0.1とすると、10人以上風邪引きさんがいたら以降の感染率は 1(必ず感染)ぢゃないの? これだと。

回答No.1

> 99人のうち何人が風邪を引くのかという人数の算出方法がわかりません。 0. Aを入力する 1. 配列 data[100] を用意し、data[0] = 1, data[1..99] = 0 とする 2. data[0..99] のうち、1であるものの数Nを数える。 3. 風邪をひく確率 p = N×A 4. i = 0 .. 99 に対し、 4.1 data[i] = 1 なら何もしない 4.2 data[i] = 0 かつ 0~1の乱数 < p なら data[i] = 1 とする 5 2,3,4を10回繰り返す > このときまずはじめに要素を100個持つ配列を宣言し、1つの要素以外はすべて0で初期化するっぽいのですがこのやり方もわかりません そのくらい調べなさい。

amel10
質問者

補足

2のところですが、Count関数を使うんですよね? そこがちょっとわからなくて^^;Nの設定の仕方とかがよくわからないんです・・・