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

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

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

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

Q&A

解決済

3回答

4117閲覧

c言語 強化学習のプログラムについて

canaria

総合スコア7

C

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

0グッド

0クリップ

投稿2015/11/09 07:13

編集2015/11/09 07:31

c言語で強化学習のプログラムを作りたいのですが
////報酬////の部分にゴールから履歴"T"歩分のgrid.(選択された方向)にゴールに近ければ近いほどたくさん
報酬を与えるプログラムを追加しようとするとフリーズしてしまいます。

###発生している問題・エラーメッセージ
~.exeは動作を停止しました
問題が発生したため、プログラムが正しく動作しなくなりました。

###ソースコード

C言語

1#include<stdio.h> 2#include<string.h> 3#include<time.h> 4#include<stdlib.h> 5#include<ctype.h> 6 7int N=5; //n*nのワールド 8int T=5; //履歴の長さ 9float REWARD=10; //報酬 10int Step[100]; //寿命(コンパイラの関係で定数で宣言) 11 12typedef struct{ 13 int goal;//ゴールなら1他は0 14 float UL,DL,RL,LL;//各矢印の長さ 15}GRID; 16 17GRID grid[5][5]; //nの枠(コンパイラの関係で定数で宣言) 18 19void MakeGWorld(int *GoalS,int *GoalT,int *StartS,int *StartT);//ゴール、スタート位置の決定 20void Tansaku(int *StartS,int *StartT);//探索、報酬 21 22int main(){ 23 int Goal_s,Goal_t,Start_s,Start_t; 24 int i,j; 25 26 MakeGWorld(&Goal_s,&Goal_t,&Start_s,&Start_t); 27 28 for(i=0;i<N;i++){ 29 for(j=0;j<N;j++){ 30 grid[i][j].UL=1; 31 grid[i][j].DL=1; 32 grid[i][j].RL=1; 33 grid[i][j].LL=1; 34 grid[i][j].goal=0; 35 36 if(i==0) grid[i][j].UL=0; 37 if(i==N-1) grid[i][j].DL=0; 38 if(j==0) grid[i][j].LL=0; 39 if(j==N-1) grid[i][j].RL=0; 40 41 if(i==Goal_s && j==Goal_t){ 42 grid[i][j].goal=1; 43 }; 44 }; 45 }; 46 for(i=0;i<=N-1;i++){ 47 for(j=0;j<=N;j++){ 48 if(j==N){ 49 printf("\n"); 50 break; 51 }; 52 if(i==Start_s &&j==Start_t) printf("◆"); 53 else if(i==Goal_s &&j==Goal_t) printf("◎"); 54 else printf("□"); 55 }; 56 }; 57 for(i=0;i<100;i++) Tansaku(&Start_s,&Start_t); 58} 59 60 61 62 63 64 65void MakeGWorld(int *GoalS,int *GoalT,int *StartS,int *StartT){ 66 int Gs,Gt,Ss,St; 67 68 srand((unsigned)time(NULL)); 69 Gs=rand()%N; 70 Gt=rand()%N; 71 *GoalS=Gs; 72 *GoalT=Gt; 73 while(1){ 74 Ss=rand()%N; 75 St=rand()%N; 76 if(Ss!=Gs && St!=Gt) break; 77 }; 78 *StartS=Ss; 79 *StartT=St; 80 printf("サイズ:%d*%d\nスタート:(%d,%d) ゴール:(%d,%d)\n",N,N,Ss,St,Gs,Gt); 81} 82 83void Tansaku(int *StartS,int *StartT){ 84 int Ps,Pt; 85 int uL,dL,rL,allL; 86 int a; 87 int i,j; 88 float xi,xj; 89 90 char Step[100]; 91 92 Ps=*StartS; 93 Pt=*StartT; 94 95 for(i=0;i<100;i++){ 96 uL=(grid[Ps][Pt].UL)*100; 97 dL=(grid[Ps][Pt].UL+grid[Ps][Pt].DL)*100; 98 rL=(grid[Ps][Pt].UL+grid[Ps][Pt].DL+grid[Ps][Pt].RL)*100; 99 allL=(grid[Ps][Pt].UL+grid[Ps][Pt].DL+grid[Ps][Pt].RL+grid[Ps][Pt].LL)*100; 100 101 a=rand()%allL; 102 if(a<uL){ 103 if(grid[Ps][Pt].UL==0){ 104 i--; 105 break; 106 }; 107 Step[i]='U'; 108 Ps--; 109 }else if(a<dL){ 110 if(grid[Ps][Pt].DL==0){ 111 i--; 112 break; 113 }; 114 Step[i]='D'; 115 Ps++; 116 }else if(a<rL){ 117 if(grid[Ps][Pt].RL==0){ 118 i--; 119 break; 120 }; 121 Step[i]='R'; 122 Pt++; 123 }else if(a<allL){ 124 if(grid[Ps][Pt].LL==0){ 125 i--; 126 break; 127 }; 128 Step[i]='L'; 129 Pt--; 130 }else{ 131 i--; 132 break; 133 }; 134 if(grid[Ps][Pt].goal==1){ 135 printf("%d:ゴール\n",i+1); 136////////////////報酬/////////////////////////// 137 138 for(j=0;j<T;j++){ 139 xi=i; 140 xj=j+1; 141 if(xi<xj) break; 142 else if(Step[i-j]=='U'){ 143 grid[Ps][Pt].UL=grid[Ps][Pt].UL+REWARD*(xi-xj+1)/i; 144 Ps++; 145 printf("上%.3f\n",grid[Ps][Pt].UL); 146 }else if(Step[i-j]=='D'){ 147 grid[Ps][Pt].DL=grid[Ps][Pt].DL+REWARD*(xi-xj+1)/i; 148 Ps--; 149 printf("下%.3f\n",grid[Ps][Pt].DL); 150 }else if(Step[i-j]=='R'){ 151 grid[Ps][Pt].RL=grid[Ps][Pt].RL+REWARD*(xi-xj+1)/i; 152 Pt--; 153 printf("右%.3f\n",grid[Ps][Pt].RL); 154 }else if(Step[i-j]=='L'){ 155 grid[Ps][Pt].LL=grid[Ps][Pt].LL+REWARD*(xi-xj+1)/i; 156 Pt++; 157 printf("左%.3f\n",grid[Ps][Pt].LL); 158 }; 159 }; 160/////////////////////////////////////////////////////////////// 161 break; 162 }; 163 if(i==99) printf("探索失敗\n"); 164 }; 165 return 0; 166}

###補足情報(言語/FW/ツール等のバージョンなど)
os:windows8
コンパイラ:MMGames EasyIDEC(Ver0.0.9.0)

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

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

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

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

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

guest

回答3

0

ベストアンサー

Tansaku関数内の

allL=(grid[Ps][Pt].UL+grid[Ps][Pt].DL+grid[Ps][Pt].RL+grid[Ps][Pt].LL)*100;

この式を計算する際にPsに5が格納されていて配列の範囲外を参照し、たまたまそこが0だったため、結果的にallLが0になり、次の

a=rand()%allL;

この式でゼロ除算となって落ちていますね。

具体的な処理内容までは追いかけていませんが、配列の添え字となるPsおよびPtを上げ下げするところで、配列の範囲を超えないようにif文に条件を追加するなどの処理をすれば良いのではないかと思います。

C言語は配列の範囲を超えたことを教えてくれたりしないので、そうならないようにコーディングする必要があります。

投稿2015/11/09 08:40

catsforepaw

総合スコア5938

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

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

canaria

2015/11/11 04:49

回答ありがとうございます。 動作確認はしたつもりだったんですが配列からはみでてたんですね。
guest

0

アクセス違反も起きているようです。Ps, Ptが負になるケースもありました。
//報酬//のロジックで設定しているUL, DL, RL, LLをTansaku処理でアクセスし、想定外の動作になっている様子です。

ところで、デバッグ中は下記の行をコメントアウトしておいた方が良いですよ。
毎回動作が異なるとデバッグたいへんですから。

srand((unsigned)time(NULL));

投稿2015/11/09 09:54

Chironian

総合スコア23272

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

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

canaria

2015/11/11 04:50

回答ありがとうございます 初心者なものでアクセス違反というのがわからないのですが再現性の方についてはりかいしました。
Chironian

2015/11/11 05:02

アクセス違反は、メモリが割り当てられてないアドレスをアクセスすることです。 最も良くやらかしてしまうのが、NULLポインタ・アクセスです。 ↓で発生するやつです。 int* p=nullptr; *p=10; 次に良くやるのが配列の範囲外アクセスです。 +方向への範囲がの時は他のメモリが割り当てられていて無関係なメモリをアクセスすることが多いです。-方向への範囲外は他のメモリがある時もありますが、メモリが割り当てられてないことも良くあります。
guest

0

おそらく

a=rand()%allL;

で、0割が起こっているのだと思います。

投稿2015/11/09 09:11

T.Kanno

総合スコア915

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

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

canaria

2015/11/11 04:51

回答ありがとうございます。 その辺りをもう一度見直してみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問