状態遷移のプログラムの課題
状態遷移のプログラムの課題
プログラミング初心者で困ってます。課題が出たのですがどうしていいか分かりません。
問題
0を発生する状態Aと1を発生する状態Bがあり、状態遷移確率が
0→0;90% 0→1;10%
1→0;60% 1→1;40%
である。これを1000回繰り返して発生した状態をXとし、異なる乱数seedを3000回用いて、
状態Xを発生させる。この時、状態XがAである確率とBである確率を求めなさい。
どうすればいいのか教えてください。お願いします。
問題
0を発生する状態Aと1を発生する状態Bがあり、状態遷移確率が
0→0;90% 0→1;10%
1→0;60% 1→1;40%
である。これを1000回繰り返して発生した状態をXとし、異なる乱数seedを3000回用いて、
状態Xを発生させる。この時、状態XがAである確率とBである確率を求めなさい。
どうすればいいのか教えてください。お願いします。
Re: 状態遷移のプログラムの課題
どの程度プログラミングは初心者ですか?
Hello worldプログラムは書けますか?
rand()関数を使えば乱数を求められますが、使い方分かりますか?
Hello worldプログラムは書けますか?
rand()関数を使えば乱数を求められますが、使い方分かりますか?
Re: 状態遷移のプログラムの課題
ループ文、if文、一次元配列はとりあえず大丈夫です。
多次元配列、構造体についてはあまり理解できていません。
Hello worldのプログラムは大丈夫です。
rand()関数、srand()関数についてはネットで調べたのである程度なら。
多次元配列、構造体についてはあまり理解できていません。
Hello worldのプログラムは大丈夫です。
rand()関数、srand()関数についてはネットで調べたのである程度なら。
Re: 状態遷移のプログラムの課題
プログラムを書く前に、上記の1000回とか3000回とかをBlack Bird さんが書きました: である。これを1000回繰り返して発生した状態をXとし、異なる乱数seedを3000回用いて、
状態Xを発生させる。この時、状態XがAである確率とBである確率を求めなさい。
簡単のために10回とか30回とかにしたとして、
どういう操作をするのか書き下すことはできますでしょうか。
私には、1000回と3000回との関連性がよくわかりません。
たぶん、私に読解力が欠けているためだと思います。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。
プログラムは思ったとおりには動かない。書いたとおりに動く。
Re: 状態遷移のプログラムの課題
私も問題の意味が、わからないのですが、私なりに解読してみました。Black Bird さんが書きました:問題
0を発生する状態Aと1を発生する状態Bがあり、状態遷移確率が
0→0;90% 0→1;10%
1→0;60% 1→1;40%
である。これを1000回繰り返して発生した状態をXとし、異なる乱数seedを3000回用いて、
状態Xを発生させる。この時、状態XがAである確率とBである確率を求めなさい。
まず、乱数で0か1か発生させる。(確率1/2)
次を3000回行う
0だった場合は90%の割合で0を発生させ、10%の割合で1を発生させる。
1だった場合は60%の割合で0を発生させ、40%の割合で1を発生させる。
0になった回数と、1になった回数をカウントする。
最初に戻り、1000回繰り返し行う。
数学的に見ると、
最初0が出る確率は0.5、1が出る確率も0.5
0だったとき再び0になるのは0.9なので、0.45、
1だったとき0になるのは、0.6なので、0.3
従って、最終的に0になるのは、0.45+0.3=0.75
かな?
non
Re: 状態遷移のプログラムの課題
送信してから思ったのですが、状態遷移を続けて3000回行った後の最終的な値が0か1かを
求めるのかも。それを1000回行う。
たぶん、こっちの方が課題として良いと思う。
求めるのかも。それを1000回行う。
たぶん、こっちの方が課題として良いと思う。
non
Re: 状態遷移のプログラムの課題
うーん,
「0を発生する」「1を発生する」の意味が不明ですね.
単に
「状態が{A,B}二通りあって,状態遷移確率が,
A→Aが90%, A→Bが10%
B→Aが60%, B→Bが40%
であり,(初期状態がどっちなのかわからないけど,例えばAから始めるとして)
1000回の状態遷移機会を与えてみて,両状態にあった回数をカウントしてみろ」
で,これを,乱数のseedナンバーを変えて3000回ほど試行してみて,
その結果を集計して,状態がAであった率を求めてみろ
ってことなんじゃないでしょうか??
「0を発生する」「1を発生する」の意味が不明ですね.
単に
「状態が{A,B}二通りあって,状態遷移確率が,
A→Aが90%, A→Bが10%
B→Aが60%, B→Bが40%
であり,(初期状態がどっちなのかわからないけど,例えばAから始めるとして)
1000回の状態遷移機会を与えてみて,両状態にあった回数をカウントしてみろ」
で,これを,乱数のseedナンバーを変えて3000回ほど試行してみて,
その結果を集計して,状態がAであった率を求めてみろ
ってことなんじゃないでしょうか??
Re: 状態遷移のプログラムの課題
…と,いうことで とりあえず
・問題の正しい解釈
・どこまではできていて(現状コードとか)
・何がわからないのか / 何に困っているのか
・(さらに,課題であれば期限はいつごろ?とか)
あたりを具体的に示してもらえないと役に立つ回答は得られないと思います.
・問題の正しい解釈
・どこまではできていて(現状コードとか)
・何がわからないのか / 何に困っているのか
・(さらに,課題であれば期限はいつごろ?とか)
あたりを具体的に示してもらえないと役に立つ回答は得られないと思います.
Re: 状態遷移のプログラムの課題
説明がうまくできていなくてすいませんでした。
1、初期状態を乱数を使って、0か1を決定する。
2、初期状態を使って、状態遷移確率に従って1000回遷移させる。
3、1000回遷移させた結果の状態を確認する。(0か1どちらになっているか)
4、1~3を3000回繰り返す。
5、1000回遷移させた結果が3000個用意されたので、そこから0と1の数を数える。
6、0と1の個数をそれぞれ3000で割って、確率とする。
という方針でおねがいします。期限は来週の水曜日までです。
1、初期状態を乱数を使って、0か1を決定する。
2、初期状態を使って、状態遷移確率に従って1000回遷移させる。
3、1000回遷移させた結果の状態を確認する。(0か1どちらになっているか)
4、1~3を3000回繰り返す。
5、1000回遷移させた結果が3000個用意されたので、そこから0と1の数を数える。
6、0と1の個数をそれぞれ3000で割って、確率とする。
という方針でおねがいします。期限は来週の水曜日までです。
Re: 状態遷移のプログラムの課題
なるほど,1000回の遷移を経た結果の状態を集計すればいいわけですね.
>・どこまではできていて(現状コードとか)
>・何がわからないのか / 何に困っているのか
については,どんな状態でしょうか.
>1、初期状態を乱数を使って、0か1を決定する。
~
>6、0と1の個数をそれぞれ3000で割って、確率とする。
のうち,どの程度できていますか?
>・どこまではできていて(現状コードとか)
>・何がわからないのか / 何に困っているのか
については,どんな状態でしょうか.
>1、初期状態を乱数を使って、0か1を決定する。
~
>6、0と1の個数をそれぞれ3000で割って、確率とする。
のうち,どの程度できていますか?
Re: 状態遷移のプログラムの課題
> 初期状態を乱数を使って、0か1を決定する。
ここで,どの確率で0,1になるのですか。
結果は変わらないのですが,プログラムを組む上で必要になります。
ここで,どの確率で0,1になるのですか。
結果は変わらないのですが,プログラムを組む上で必要になります。
► スポイラーを表示
Re: 状態遷移のプログラムの課題
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(void){
int a,b,i,j,x;
srand((unsigned)time(NULL));
for(i=0;i<3000;i++){
x=rand()%2;
for(j=0;j<1000;j++){
if(x==0 && ) {x=0;}
else if(x==0 && ) {x=1;}
else if(x==1 && ) {x=0;}
else {x=1;}
}
}
/* aを0の個数、bを1の個数として求めたい */
/* a,bを求めて3000で割って出力する。*/
printf("状態Aである確率は%f\n 状態Bである確率は%f\n",a/3000,b/3000);
return 0;}
状態遷移をどのように行えば良いかが分かりません。
また0と1の個数をどのようにして求めるのかという点で困ってます。
>
問題中に初期状態についての言及がないためなんとも言えませんが、
結果に変動がないのであれば任意で構わないと思います。
Re: 状態遷移のプログラムの課題
「a/3000」「b/3000」だと、整数の割り算になって切り捨てられます。
「a/3000.0」「b/3000.0」としてください。
「a/3000.0」「b/3000.0」としてください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: 状態遷移のプログラムの課題
う~ん。
どこのサイトを使って、あるいはどの本を読んで勉強したら、
そういった字下げのコードを書くようになるのか、大いに興味があります。
個人的には、読みにくくて仕方がありません。
もし興味がおありでしたら、他の質問者さんへの回答として
私が示した字下げの方法をごらんになってみてください。
なお、それはあくまで私個人の流儀(だから、他の人の流儀とは異なる場合あり)であり、
かつ、私の流儀を押しつけるつもりはありません。念のため。
どこのサイトを使って、あるいはどの本を読んで勉強したら、
そういった字下げのコードを書くようになるのか、大いに興味があります。
個人的には、読みにくくて仕方がありません。
もし興味がおありでしたら、他の質問者さんへの回答として
私が示した字下げの方法をごらんになってみてください。
なお、それはあくまで私個人の流儀(だから、他の人の流儀とは異なる場合あり)であり、
かつ、私の流儀を押しつけるつもりはありません。念のため。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。
プログラムは思ったとおりには動かない。書いたとおりに動く。
Re: 状態遷移のプログラムの課題
「状態遷移」とか仰々しく言っているけど,要するに,
>A→Aが90%, A→Bが10%
とかいうのは,
「現在状態がAであるとき,(出る目の範囲が1~10の)10面さいころを振って,
1~9だったらAのまま,10が出たら現在状態をBにする」
というだけのことでしょう.
(あなたは既に2面さいころを作れているから,10面さいころを作るのは問題ないはず)
状態Bからの遷移も同様です.
とりあえず最初は「3000回やって云々」は忘れて,
・1000回さいころを振る
・各さいころで出た値によって,次の状態がAかBか決まる.そのルール(確率)は現在の状態による.
・1000回のさいころを振り終えた時点の状態はどっちになったか?
だけを実装してみてはいかがでしょうか.
仮に,いきなりコードで書くのが難しい ということであれば,↓のように日本語で書けばいいです.
日本語で書けたら 後はそれをCでの記述に変えればよいです.
>A→Aが90%, A→Bが10%
とかいうのは,
「現在状態がAであるとき,(出る目の範囲が1~10の)10面さいころを振って,
1~9だったらAのまま,10が出たら現在状態をBにする」
というだけのことでしょう.
(あなたは既に2面さいころを作れているから,10面さいころを作るのは問題ないはず)
状態Bからの遷移も同様です.
とりあえず最初は「3000回やって云々」は忘れて,
・1000回さいころを振る
・各さいころで出た値によって,次の状態がAかBか決まる.そのルール(確率)は現在の状態による.
・1000回のさいころを振り終えた時点の状態はどっちになったか?
だけを実装してみてはいかがでしょうか.
仮に,いきなりコードで書くのが難しい ということであれば,↓のように日本語で書けばいいです.
日本語で書けたら 後はそれをCでの記述に変えればよいです.
現在状態=状態A; //初期状態.※ここでは仮に状態Aとする.ランダムに決めるのならそうする.
//1000回の状態遷移機会
for( int i=0; i<1000; i++ )
{
//さいころを振る
今回のさいころの目 = 10面さいころをふった結果;
//現在状態と,さいころの出た目によって,状態を変える
if( 現在状態==状態A && 今回のさいころの目==10 )
{ //状態Aからは10%の確率で状態Bに遷移する
現在状態=状態B;
}
else if( ... )
{
....
}
}
//1000回終えた後での現在状態を表示
if( 現在状態==状態A )
{
printf( "Aだった" );
}
else
{
printf( "Bだった" );
}
Re: 状態遷移のプログラムの課題
↑ができたら,あとはこれを3000回繰り返すようにし,その繰り返しの中で
各「さいころ1000連発処理」の結果状態が
・Aだった回数
・Bだった回数
をそれぞれカウントするようにすればよいでしょう.
(実際は,総数が3000だとわかっているのだから,一方だけカウントすればいいけど)
各「さいころ1000連発処理」の結果状態が
・Aだった回数
・Bだった回数
をそれぞれカウントするようにすればよいでしょう.
(実際は,総数が3000だとわかっているのだから,一方だけカウントすればいいけど)
Re: 状態遷移のプログラムの課題
見にくいコードですいません。
コードを書いて人に見てもらう機会なかったため、
普段、字下げなどを気にして書いていませんでした。
誰が見てもわかりやすいコードを書かなければいけませんね。
コードを書く際には字下げにも気をつけるようにします。
ご指摘ありがとうございました。
コードを書いて人に見てもらう機会なかったため、
普段、字下げなどを気にして書いていませんでした。
誰が見てもわかりやすいコードを書かなければいけませんね。
コードを書く際には字下げにも気をつけるようにします。
ご指摘ありがとうございました。
Re: 状態遷移のプログラムの課題
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(void){
int x,y,i;
srand((unsigned)time(NULL));
x=rand()%2;
for (i=0; i<1000; i++){
y=rand()%10;
if(x==0 && 0<=y<=8)
{
x=0;
}
else if(x==0 && y==9)
{
x=1;
}
else if(x==1&& 0<=y<=5)
{
x=0;
}
else
{
x=1;
}
}
if(x==0)
{
printf("1000回目は状態Aです。\n");
}
else
{
printf("1000回目は状態Bです。\n");
}
return 0;}
状態Bになることがありません。どこを直せばいいでしょうか。
Re: 状態遷移のプログラムの課題
他にもまずい所は多そうですね。
× : if(x==0 && 0<=y<=8)
○ : if(x==0 && 0<=y && y<=8)
× : if(x==0 && 0<=y<=8)
○ : if(x==0 && 0<=y && y<=8)
Re: 状態遷移のプログラムの課題
たいちうさん、ありがとうございます。修正しました。
何度か実行しているうちに状態Bにもなりました。
どうも状態Bになる確率が結構低そうですね。
何度か実行しているうちに状態Bにもなりました。
どうも状態Bになる確率が結構低そうですね。
Re: 状態遷移のプログラムの課題
実行してみた
↓
結果が予想と違う
↓
掲示板で質問
ではなく、
↓
途中経過が予想通りか確認する
などのデバッグの工夫をしましょう。
上達したいならば、(筋道を立てて)できる限りの事をしてから質問です。
欲を言うと、できる限りの事+αをしてからですね。
どんな事情があるか知らないので、+αまで必須とは思いませんけど、
上達したいならば、地道な努力と閃きの両方が必要だということを、
忘れないでください。
# 半分は自分に言っているみたいなほろ酔いのたいちうでした。
↓
結果が予想と違う
↓
掲示板で質問
ではなく、
↓
途中経過が予想通りか確認する
などのデバッグの工夫をしましょう。
上達したいならば、(筋道を立てて)できる限りの事をしてから質問です。
欲を言うと、できる限りの事+αをしてからですね。
どんな事情があるか知らないので、+αまで必須とは思いませんけど、
上達したいならば、地道な努力と閃きの両方が必要だということを、
忘れないでください。
# 半分は自分に言っているみたいなほろ酔いのたいちうでした。
Re: 状態遷移のプログラムの課題
[code=c#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(void){
int a=0,b,x,y,i,j;
srand((unsigned)time(NULL));
x=rand()%2;
for(j=0;j<3000;j++){
for (i=0; i<1000; i++){
y=rand()%10;
if(x==0 && 0<=y && y<=8)
{
x=0;
}
else if(x==0 && y==9)
{
x=1;
}
else if(x==1&& 0<=y && y<=5)
{
x=0;
}
else
{
x=1;
}
}
if(x==0)
{
a=a+1;
}
}
b=3000-a;
printf("状態A=%f\n状態B=%f\n",a/3000.0,b/3000.0);
return 0;}][/code]
usaoさんのアドバイスに従って作ってみました。おそらく大丈夫だと思うのですが、
どこか問題点があればご指摘ください。
#include<stdlib.h>
#include<time.h>
int main(void){
int a=0,b,x,y,i,j;
srand((unsigned)time(NULL));
x=rand()%2;
for(j=0;j<3000;j++){
for (i=0; i<1000; i++){
y=rand()%10;
if(x==0 && 0<=y && y<=8)
{
x=0;
}
else if(x==0 && y==9)
{
x=1;
}
else if(x==1&& 0<=y && y<=5)
{
x=0;
}
else
{
x=1;
}
}
if(x==0)
{
a=a+1;
}
}
b=3000-a;
printf("状態A=%f\n状態B=%f\n",a/3000.0,b/3000.0);
return 0;}][/code]
usaoさんのアドバイスに従って作ってみました。おそらく大丈夫だと思うのですが、
どこか問題点があればご指摘ください。
Re: 状態遷移のプログラムの課題
そうですね。これから多くのプログラムを組まなければならなくなるので、
上達するためにもしっかりとやっていきたいと思います。
たいちうさん、ありがとうございました。
上達するためにもしっかりとやっていきたいと思います。
たいちうさん、ありがとうございました。
-
- 記事: 44
- 登録日時: 11年前
Re: 状態遷移のプログラムの課題
以下が正解になります。
どんな質問にも答えますので、分からない点があれば教えてください。
課題、頑張ってくださいねヽ(*´∀`)ノ
どんな質問にも答えますので、分からない点があれば教えてください。
課題、頑張ってくださいねヽ(*´∀`)ノ
#include <stdio.h>
#include <stdlib.h>
#include<time.h>
void main(void){
// 最終状態A,Bを数えます
int A=0,B=0;
// seedを3000回用いります
for( int i = 0; i < 3000; i++){
srand(i); // ←seedが3000回変化します
int n=rand()%2; // 状態Aか状態Bをランダムに設定します
// 1000回状態を変化させてみます
for( int j=0; j<1000; j++ ){
int r=rand()%100;
// 0→1になる確率は10%
if(n==0){if(r<10){n=1;}}
// 1→0になる確率は60%
else if(n==1){if(r<60){n=0;}}
}
// 1000回繰り返したあと、
// 状態Aか状態Bかを調べて加算します。
if(n==0)A++;
else B++;
}
printf("状態XがAである確率は%.2f%です\n",A/3000.0f*100.0f);
printf("状態XがBである確率は%.2f%です\n",B/3000.0f*100.0f);
// 何か入力があると終了します
rewind(stdin);
getchar();
}
ただの超絶右留斗羅天才プログラマーです。同人ゲーム制作進捗度:7%
Re: 状態遷移のプログラムの課題
>どこか問題点があればご指摘ください。
問題文を見た感じだと 超絶右留斗羅天才プログラマーさんが示したコードにあるように,
「3000回のループの中でsrand()を毎回つかう」ことが求められているようにも見えますね.
最初の投稿時の問題文が出された課題文そのものなのだとすれば,
直しておいてもよいのではないでしょうか.
もしコードを提出するのであれば,わたしだったら
とか,コメントを添えてしまうかもしれませんw
その他の点では,コードをざっと眺めた感じだと,特に問題無いように見えます.
(本当は,理論値と同程度の結果が出てくるかどうか見ればいいんだろうけど,
理屈の上でどの程度の値が出てくることになるのかが,私にはわからんですw)
>どうも状態Bになる確率が結構低そうですね。
状態遷移確率から見て,Bにはかなりなりにくいと思います.
一度状態AになったらなかなかBに変わらないのに,Bになっても結構な確率ですぐAに戻ってしまう ので.
問題文を見た感じだと 超絶右留斗羅天才プログラマーさんが示したコードにあるように,
「3000回のループの中でsrand()を毎回つかう」ことが求められているようにも見えますね.
最初の投稿時の問題文が出された課題文そのものなのだとすれば,
直しておいてもよいのではないでしょうか.
もしコードを提出するのであれば,わたしだったら
for( int j=0; j<3000; j+++ )
{
//意義はいまいち不明であるが,問題文を読むかぎりだと
//3000回の試行では,異なるseed numberを用いることが指定されているようなので,
//ここでsrand()する.
srand( j );
...
その他の点では,コードをざっと眺めた感じだと,特に問題無いように見えます.
(本当は,理論値と同程度の結果が出てくるかどうか見ればいいんだろうけど,
理屈の上でどの程度の値が出てくることになるのかが,私にはわからんですw)
>どうも状態Bになる確率が結構低そうですね。
状態遷移確率から見て,Bにはかなりなりにくいと思います.
一度状態AになったらなかなかBに変わらないのに,Bになっても結構な確率ですぐAに戻ってしまう ので.
Re: 状態遷移のプログラムの課題
みなさん、ありがとうございました( ´ ▽ ` )
おかげで無事に完成しました。
また困ったことがあれば質問させてもらいます(^-^)
おかげで無事に完成しました。
また困ったことがあれば質問させてもらいます(^-^)
Re: 状態遷移のプログラムの課題
みなさん、ありがとうございました( ´ ▽ ` )
おかげで無事に完成しました。
また困ったことがあれば質問させてもらいます(^-^)
おかげで無事に完成しました。
また困ったことがあれば質問させてもらいます(^-^)