質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

1回答

5270閲覧

Q学習の問題とC言語の問題

pure_storm

総合スコア16

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

1グッド

1クリップ

投稿2017/07/28 14:35

編集2017/08/05 10:51

###前提・実現したいこと
C言語とQ学習のプログラミング問題です。
プログラミングが苦手で手詰まり状態です。ヒントでもいいので教えてください。
###発生している問題・エラーメッセージ
穴埋め部分がわかりません
#####わからない部分
どうしたらいいかわからない状態です
######その1
ルールの価値の初期化

Qvalue[s][a] : 状態sにおいて行動aを取ることの価値 ****************************************************************/ void init_Q(double Qvalue[StateNum][ActNum]) { int s,a; /* すべての状態と行動の価値を0にする */ /* この部分を自分で書く */ }

######その2

/* 温度パラメータを設定 */ T=T-t; if(T<=1) T=1; /* ルールの価値の合計を計算 その状態で取れない行動(env[state][a]=-1) の価値は合計には含まない */ /*** この部分を自分で書く ***/

######その3

/******************************************************************** ルールの価値の更新 Qvalue[s][a] : 状態sにおいて行動aを取ることの価値 p_state : 直前の状態 act : 行動 state : 状態 (行動後の状態) r : 報酬 ********************************************************************/ void update_Q(double Qvalue[StateNum][ActNum], int p_state, int act, int state, int r) { int a; double max; // 行動後の状態から取ることのできる行動の中での価値の最大値 /* 取ることのできる行動に関する価値の中で最大値を求める */ /*** この部分を自分で書く ***/ /* 状態p_stateにおいて行動actをとることの価値を更新 */ /*** この部分を自分で書く ***/ }

###該当のソースコード

/************************************************************************** Q学習 **************************************************************************/ #include<stdio.h> #include<stdlib.h> #include<math.h> // 状態 #define START 0 // 入口 (スタート) #define WOOD 1 // 森 #define LAKE 2 // 湖 #define POND 3 // 池 #define FIELD 4 // 草原 #define GOAL 5 // 宝 (ゴール) // 行動 #define EAST 0 // 東 #define WEST 1 // 西 #define SOUTH 2 // 南 #define NORTH 4 // 北 #define TrialNo 50 // 試行回数 #define StateNum 6 // 状態数 #define ActNum 4 // 行動数 #define Alpha 0.1 // 学習率 #define Gamma 0.9 // 減衰率 #define Reward 10 // 報酬 /********************************************************************* 乱数のシードの生成 **********************************************************************/ void init_rnd() { srand((unsigned int)time(NULL)); } /******************************************************************** 乱数の発生 (0〜1の乱数) ********************************************************************/ double Random() { return((double)rand()/RAND_MAX); } /******************************************************************** ルールの価値の初期化 Qvalue[s][a] : 状態sにおいて行動aを取ることの価値 ********************************************************************/ void init_Q(double Qvalue[StateNum][ActNum]) { int s,a; /* すべての状態と行動の価値を0にする */ /*** この部分を自分で書く ***/ } /******************************************************************** 行動の選択 (ボルツマン選択) state : 状態 Qvalue[s][a] : 状態sにおいて行動aを取ることの価値 env[s][a] : 状態sにおいて行動aを取ったときに遷移する状態 t : 試行回数 ********************************************************************/ int select_action(int state, double Qvalue[StateNum][ActNum], int env[StateNum-1][ActNum],int t) { double sum; // ルールの価値の合計 int a; // 行動 double r; // 乱数 (0~sumの間の乱数) double border; // 境界線 double T=10; // 温度パラメータ /* 温度パラメータを設定 */ T=T-t; if(T<=1) T=1; /* ルールの価値の合計を計算 その状態で取れない行動(env[state][a]=-1) の価値は合計には含まない */ /*** この部分を自分で書く ***/ /* 0~sumの乱数を生成 */ r = Random()*sum; border=0; for(a=0;a<ActNum;a++){ /* 取ることのできる行動の中から行動を選択 */ if(env[state][a]!=-1){ border += exp(Qvalue[state][a]/T); } /* 選択された行動を返す */ if(r<=border){ return a; } } } /******************************************************************** ルールの価値の更新 Qvalue[s][a] : 状態sにおいて行動aを取ることの価値 p_state : 直前の状態 act : 行動 state : 状態 (行動後の状態) r : 報酬 ********************************************************************/ void update_Q(double Qvalue[StateNum][ActNum], int p_state, int act, int state, int r) { int a; double max; // 行動後の状態から取ることのできる行動の中での価値の最大値 /* 取ることのできる行動に関する価値の中で最大値を求める */ /*** この部分を自分で書く ***/ /* 状態p_stateにおいて行動actをとることの価値を更新 */ /*** この部分を自分で書く ***/ } /************************************************************************** メインプログラム **************************************************************************/ int main() { int t; int s,a; int act; // 行動 int p_state; // 直前の状態 int state; // 状態 double Qvalue[StateNum][ActNum]; // ルールの価値 // 環境 (状態の遷移) 東 西 南 北 int env[StateNum-1][ActNum]={{WOOD, -1, POND, -1}, // 入口 {LAKE, START, FIELD,-1}, // 森 {-1, WOOD, GOAL, -1}, // 湖 {FIELD,-1, -1, START}, // 池 {-1 ,POND, -1, WOOD}}; // 草原 int count; // エピソードの長さ char *states[StateNum]={"入口","森","湖","池","草原","宝"}; // 状態(表示用) char *acts[ActNum]={"東","西","南","北"}; // 行動(表示用) FILE *fp; // ファイルポインタ /* 結果保存用のファイル(result.dat)をオープン */ if((fp=fopen("result.dat","w"))==NULL){ printf("main() : Cannot open \"result.dat\"\n"); exit(1); } init_rnd(); /* 乱数の初期化 */ init_Q(Qvalue); /* ルールの価値の初期化 */ /* TrialNo回の試行を繰り返す */ for(t=0;t<TrialNo;t++){ printf("[%d]",t); state = START; /* 状態を初期化(STARTに設定) */ count=0; /* エピソードの長さを0で初期化 */ /* ゴールに到達するまで繰り返す */ while(state!=GOAL){ act=select_action(state,Qvalue,env,t); /* 行動を選択 */ p_state=state; /* 状態を保存 */ state=env[p_state][act]; /* 行動することにより状態が遷移 */ /* ゴールに到達したら報酬を取得し、ルールの価値を更新 */ if(state==GOAL){ update_Q(Qvalue,p_state,act,state,Reward); } /* ルールの価値を更新(ゴール以外では報酬は0) */ else{ update_Q(Qvalue,p_state,act,state,0); } /* 状態と行動を画面に表示 */ printf("%s==>(%s)==>",states[p_state],acts[act]); /* エピソードの長さを1増やす */ count++; } /* 最終的な状態を画面に表示 */ printf("%s\n",states[state]); /* 試行回数とエピソードの長さをファイルに出力 */ fprintf(fp,"%d %d\n",t,count); } /* ファイルをクローズ */ fclose(fp); /* 最終的なルールの価値保存用のファイルをオープン */ if((fp=fopen("Q.dat","w"))==NULL){ printf("main() : Cannot open \"Q.dat\"\n"); exit(1); } /* ルールの価値をファイルに書き出す */ fprintf(fp," 東 西 南 北\n"); for(s=0;s<StateNum;s++){ fprintf(fp,"%s\t",states[s]); for(a=0;a<ActNum;a++){ fprintf(fp,"%6.3lf\t",Qvalue[s][a]); } fprintf(fp,"\n"); } /* ファイルをクローズ */ fclose(fp); }

###試したこと
理解できないところが多くて、手が付けられない状態です
###補足情報(言語/FW/ツール等のバージョンなど)
Linax
VMware player
Ubuntu
C言語
理想的な実行結果
[0] 入口==>(南)==>池==>(東)==>草原==>(北)==>森==>(南)==>草原==>(西)==>池==>(北)==

入口==>(南)==>池==>(北)==>入口==>(東)==>森==>(東)==>湖==>(南)==>宝

[1] 入口==>(南)==>池==>(北)==>入口==>(南)==>池==>(東)==>草原==>(西)==>池==>(東)==

草原==>(北)==>森==>(西)==>入口==>(東)==>森==>(西)==>入口==>(南)==>池==>(東)==>

草原==>(北)==>森==>(東)==>湖==>(南)==>宝
[2] 入口==>(東)==>森==>(東)==>湖==>(南)==>宝

[99] 入口==>(東)==>森==>(東)==>湖==>(南)==>宝

mhashi👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tanat

2017/07/28 14:49

どこがどう理解出来ないかを全て記述してください。完全に手が付けられないということであれば、この問題より前の問題を一つづつさかのぼって、「どこがわからないかわかる」という問題まで戻ってその問題についてわからない部分を質問されることをお勧めします。
_Victorique__

2017/07/28 15:17

これもはや何が分からないのかすら分かってないね。あなたはQ学習で何がしたいんですか?
WoodenHamlet

2017/07/31 06:28

インデントのついてないソース(しかもスクロールが必要なレベル)を見ると拒否反応出ちゃう……。質問者さんはこれ読めるの?
hige0119

2017/08/01 00:21

そもそも問題の意味が分からないのであれば穴埋めは無理かと思います。ここで質問をする前に問題の意味を理解するべきかと。
guest

回答1

0

ベストアンサー

強化学習に関しては素人ですが。。

  1. c言語の問題
  2. 強化学習の問題

と分けて考えることをおすすめします。

その1

c

1void init_Q(double Qvalue[StateNum][ActNum]) 2{ 3int s,a; 4 5/* すべての状態と行動の価値を0にする */ 6 7 ここは、c言語の問題です。 8 「状態と行動の価値」を表す変数を0にしましょう。 9 forループなどで実現できそうです。 10 11/* この部分を自分で書く */ 12 13}

その2

c

1int select_action(int state, 2double Qvalue[StateNum][ActNum], 3int env[StateNum-1][ActNum],int t) 4{ 5 double sum; // ルールの価値の合計 6 int a; // 行動 7 double r; // 乱数 (0~sumの間の乱数) 8 double border; // 境界線 9 double T=10; // 温度パラメータ 10 11 /* 温度パラメータを設定 */ 12 T=T-t; 13 if(T<=1) T=1; 14 15 /* ルールの価値の合計を計算 16 その状態で取れない行動(env[state][a]=-1) 17 の価値は合計には含まない */ 18 /* この部分を自分で書く */ 19 20 これは、強化学習の問題です。 21 env[state][a]の変数を判断しながら、「ルールの価値」を表す変数を合計します。 22 ただし、「ボルツマン選択」をするということなので、その式に従います。 23 (温度定数Tが低いほどエージェントは値の高いQ値を選択する可能性が上がり、 24 逆にTが高いほどランダムに近い行動選択をするようになります。) 25 このプログラムは試行回数が高くなるほどT値を低くする実装になっていますが、 26 その理由は、身近な先生などにヒントをもらったほうが良いかもしれません。 27 28 /* 0~sumの乱数を生成 */ 29 r = Random()*sum; 30 border=0; 31 for(a=0;a<ActNum;a++){ 32 /* 取ることのできる行動の中から行動を選択 */ 33 if(env[state][a]!=-1){ 34 border += exp(Qvalue[state][a]/T); 35 } 36 /* 選択された行動を返す */ 37 if(r<=border){ 38 return a; 39 } 40 } 41}

その3

c

1void update_Q(double Qvalue[StateNum][ActNum], 2int p_state, int act, int state, int r) 3{ 4 int a; 5 double max; // 行動後の状態から取ることのできる行動の中での価値の最大値 6 7 この部分は、強化学習の問題です。 8 強化学習で一番キモになる部分です。 9 10 /* 取ることのできる行動に関する価値の中で最大値を求める */ 11 /* この部分を自分で書く */ 12 「取ることのできる行動に関する価値」を表す変数の中から最大値を求めます。 13 forループで最大値を検索するのが良いかもしれません。 14 ここでのポイントは、「行動後の状態」から検索することになります。 15 16 /* 状態p_stateにおいて行動actをとることの価値を更新 */ 17 /* この部分を自分で書く */ 18 ここで、強化学習の方法のひとつの「Q学習」を使用します。 19 Q学習の式は、下記になります。 20 Q値(現在) = Q値(現在) + Alpha * (報酬 + Gamma * 最大値 - Q値(現在)); 21 22}

こんな感じでしょうか。

強化学習は、AIブームで今流行っていますので、しっかり基本を勉強しておくと後で良いかもしれません。
(私も勉強中ですが。。)

プログラミングが苦手だと、c言語の問題と、強化学習の理論の2つを同時にこなす課題は大変だとは思いますが、まずはc言語をある程度覚えてから取り掛かったほうが良いかと思います。

勉強頑張ってください!

投稿2017/08/02 05:26

編集2017/08/02 06:45
soma62jp

総合スコア141

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pure_storm

2017/08/02 06:50

ご助言ありがとうございます。もう少し考えて頑張ってみようと思っています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問