VC#2010で強化学習のプログラムを作る際に発生するエラーについて

このQ&Aのポイント
  • VC#2010で強化学習のプログラムを実行する際に「NullReferenceExceptionはハンドルされませんでした。オブジェクト参照がオブジェクト インスタンスに設定されていません。」というエラーが発生し、プログラムが動作しない問題があります。
  • ソースコードにはQテーブルの初期化や試行回数の設定などが含まれており、行動の選択や実行、報酬の計算などが行われます。
  • 具体的なエラーの原因や修正方法について詳細を教えていただける方がいれば、お知らせください。
回答を見る
  • ベストアンサー

VC# 強化学習

VC#2010で強化学習のプログラムを作ろうと考えているのですが、 実行すると「NullReferenceExceptionはハンドルされませんでした。 オブジェクト参照がオブジェクト インスタンスに設定されていません。」 というエラーが出てプログラムが動きません。 ソースは static public Random rnd; static void Main(string[] args) { double[][] Qtable; //Qtable double Q_max = 0;//Q値の最大値 double reward = 0; //報酬 double alpha = 0.5;//学習係数 double gamma = 0.9;//減衰係数 int epsilon = 10;//行動を無作為に選ぶ確率[%] int trial_max = 100;//試行回数 int num_a = 2;//行動の数 int num_s = 2;//状態の数 int a = 0;//行動 int s = 0;//状態 int sd = 0;//行動の実行によって遷移する状態 int i, j; //メモリー空間の確保 Qtable = new double [num_s][]; for (i = 0; i < num_s; i++) { Qtable[i] = new double[num_a]; } //Q値の初期化 for (i = 0; i < num_s; i++) { for (j = 0; j < num_a; j++) { Qtable[i][j] = 0; Console.WriteLine("Q[{0}][{1}]={2}\n", i, j, Qtable[i][j]); } } //試行開始 for (i = 0; i < trial_max; i++) { //行動の選択 a = epsilon_greedy(epsilon, s, num_a, Qtable); a = 1; //行動の実行 reward = vending_machine(s, a, sd); //sdにおけるQ値の最大値を求める Q_max = max_Qval(sd, num_a, Qtable); //Q値の更新 Qtable[s][a] = (1 - alpha) * Qtable[s][a] + alpha * (reward + gamma * Q_max); s = sd; Console.WriteLine("i={0}\n", i); if (reward > 0) { Console.WriteLine("成功\n", a); } if (reward == 0) { Console.WriteLine("失敗\n", a); } } //Qtableの表示 for (i = 0; i < num_s; i++) { for (j = 0; j < num_a; j++) { Console.WriteLine("{0} ", Qtable[i][j]); } Console.Write("\n"); } return; } static double vending_machine(int s, int a, int sd) { double reward; if (a == 0) { if (s == 0) sd = 1; if (s == 1) sd = 0; reward = 0; } else { if (s == 1) { sd = s; reward = 10; } else { sd = s; reward = 0; } } return reward; } static double max_Qval(int s, int num_a, double [][] Qtable) { double max; int i = 0; max = Qtable[s][0]; for (i = 1; i < num_a; i++) { if (Qtable[s][i] > max) { max = Qtable[s][i]; } } return max; } static int select_action(int s, int num_a, double [][] Qtable) { double max; int i = 0; int[] i_max; i_max = new int[num_a]; int num_i_max = 1; int a; i_max[0] = 0; max = Qtable[s][0]; for (i = 1; i < num_a; i++) { if (Qtable[s][i] > max) { max = Qtable[s][i]; num_i_max=1; i_max[0]=i; } else if (Qtable[s][i] == max) { num_i_max++; i_max[num_i_max - 1] = i; } } int seed = Environment.TickCount; rnd = new Random(seed++); a = i_max[rnd.Next(num_i_max)]; return a; } static int epsilon_greedy(int epsilon, int s, int num_a, double [][] Qtable) { int a; if (epsilon > rnd.Next(100)) { //無作為に行動を選択 a = rnd.Next(num_a); } else { //最大のQ値を持つ行動を選択 a = select_action(s, num_a, Qtable); } return a; } のような感じです。 どなたか分かる方がいれば、教えていただけるとありがたいです。 よろしくお願いします。

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

  • ベストアンサー
回答No.2

rndは、select_actionの終わりの方で作られるみたいだけど、 select_actionは、epsilon_greedyからしか呼ばれてないよね? epsilon_greedyで、select_actionを呼ぶ前に、 if (epsilon > rnd.Next(100)) でrndのメソッド呼んでるけど、 初めてこれが呼ばれる時は、まだrndのインスタンスが無いよ。 じゃぁどこで生成すりゃ良いの?って聞かれそうだけど、 どこで生成すれば良いのかは、仕様を知っているはずの 貴方しか分からないので、聞かれても困るからね。

prism3980
質問者

お礼

回答ありがとうございました。 丁寧な解説をいただいたおかげで、無事に解決いたしました。

その他の回答 (1)

回答No.1

エラーと一緒に、どこで発生したのか、 ソースファイル名と行番号が出力されていると思うのですが。 そこで、インスタンスが生成されていないオブジェクトを参照するような事をしているはずです 例: Foo foo; //foo = new Foo(); //インスタンスを生成していないと foo.bar(); // ここでエラー

prism3980
質問者

補足

回答ありがとうございます。 エラーが発生したのは 34行目 for(i=0;i<trial_max;i++) と 145行目 If(epsilon>rnd.Next(100)) だったのですが、この場合ですと何がエラーの原因になっているのでしょうか?

関連するQ&A

  • 最大値と最小値を表示したいのですが・・・

    double numに入っている数字から最大値と最小値を求めたいのですが、このままだと両方とも1.000になってしまうんです・・・ どうやったらちゃんと最大値と最小値が表示されるのでしょうか?? 初心者なものでスイマセンが教えてください!! #include<stdio.h> int main(void) { int i,j; double num[]={4.5,3.1,7.0,9.2,1.0,5.7,9.3,2.3,0.3,1.0}; double max,min; for(i=0; i<10; i++) { for(j=0; j<10; j++) { if(num[i]>num[j]) max=num[i]; } } for(i=0; i<10; i++) { for(j=0; j<10; j++) { if(num[i]<num[j]) min=num[i]; } } printf("最大値は%fです。",max); printf("最小値は%fです。",min); return 0; }

  • 最大値を求める

    3つの整数を入力して、最大値を求めるプログラムを作りたいのですが、整数を入力するところまでは うまくいくのですが、結果が、255、と出てしまいます。どこがおかしいのかが解かりません。 どなたか教えていただけませんか? 宜しくお願いします。 #include <stdio.h> int main(void) { int num[3]; int max, i, j; puts("三つの整数を入力してください"); for(i = 0; i < 3; ++i) { printf("整数%d:", (i + 1)); scanf("%d", &num[i]); } max = num[0]; for(j = 0; j < 3; ++j) { if(max < num[j]) { max = num[j]; } } printf("最大値は%dです。\n", max); return 0; }

  • フローチャート 

    このプログラムのフローチャートを教えてください 1class QNode{ 2 private int min; 3 private int max; 4 private int mid; 5 private int key; 6 private int max2[]; 7 private int[] q; 8 static int k; 9 10 public QNode(int[] c){ 11 q=c; 12 max2=new int[10000]; 13 k=0; 14 } 15 16 public void narabikae(int a,int b){ 17 int tmp=q[a]; 18 q[a]=q[b]; 19 q[b]=tmp; 20 } 21 22 public void quick(int mi,int mx){ 23 24 min=mi; 25 max=mx; 26 max2[k]=mx; 27 28 if(min<max){ 29 mid=(min+max)/2; 30 key=q[mid]; 31 int i=min; 32 int j=max; 33 34 while(true){ 35 while(q[i]<key){ 36 i++; 37 } 38 while(key<q[j]){ 39 j--; 40 } 41 if(j<i) 42 break; 43 44 narabikae(i,j); 45 i++; 46 j--; 47 48 if(j<i) 49 break; 50 } 51 k++; 52 quick(min,j); 53 max=max2[--k]; 54 quick(i,max); 55 } 56 } 57} 58 59public class A1 { 60 61 /** 62 * @param args 63 */ 64 public static void main(String[] args) { 65 66 int[] q={2,8,4,11,15,9,1,13,19}; 67 68 QNode qn=new QNode(q); 69 qn.quick(0,8); 70 71 for(int i=0;i<9;i++){ 72 System.out.print(q[i]+" "); 73 } 74 } 75}

  • 正規分布するプログラムを教えてください。

    正規分布する乱数プログラムを作りたいのですが、うまく作れません・・。 プログラムソースは長くなりますので見ていただかなくても結構なのですが、下記のようなプログラムを実行したところ、実行結果下記になり、正規分布にはなりませんでした・・。 色々ネットで調べたものの理解できないのでどなたか教えていただけないでしょうか>< 正規分布を利用して、例えば50~100位の間に分布する乱数を生成したりしたいのです。。。 #include <math.h> #include <time.h> #include <stdlib.h> #include <stdio.h> #define PI 3.14159265358979323846264 double p_nor(){ double rnd,t,u,r1,r2; rnd=rand()%10000/10000.0; t=sqrt(-2.0 * log(1-rnd)); u=2*PI*rnd; r1=t*sin(u); return r1; } int main(){ int i,bunpu[30]={}; double p,min=0,max=0,total=0; srand((unsigned)time(NULL)); for(i=0;i<100000;i++){ p=p_nor(); for(int j=0;j<30;j++){ if(p>-2.0+0.1*j && p<=-1.9+0.1*j) bunpu[j]++; } if(min>p)min=p; if(max<p)max=p; total+=p; } printf("min:%f max%f 平均%f\n",min,max,total/100000); for(int j=0;j<30;j++){ for(i=0;i<bunpu[j]/200;i++){ printf("*"); } printf("\n"); } return 0; } 実行結果 min:-1.711381 max0.803275 平均-0.247841 **************** ************************************ ******************** **************** ************** ************ *********** ********** ********** ********* ********* ******** ******** ******** ******** ******** ******** ******** ************************************* ************************* *********************** *********************** ************************ **************************** ******************************** **************************************************************** ***********

  • 最頻度のプログラム

    以下のような最頻度のプログラムを作成しました.最頻度が1つしか存在しないような場合はうまく動くと思います.しかし最頻度の数字が2つ以上存在すると,一番はじめに書い最頻度の数字しか表示しないと思います.どう改良すれば,すべての最頻度の数字を拾ってくれますかね. /*最頻値を求めるプログラム*/ #include<stdio.h> int main(void) { int i,j; int count=0,COUNT=0; double num[20]; double max; printf("最頻値を求めます.数字を20個入力してください.\n"); for(i=0;i<20;i++) { printf("%d\t",i+1); scanf("%lf",&num[i]); } for(i=0;i<20;i++) { count=0; for(j=i+1;j<20;j++) { if(num[i]==num[j]) { count++; } if(COUNT<count-1) { COUNT=count; max=num[i]; } } } printf("%lfが最頻値です.\n",max); return 0; }

  • GUI~ボタン処理~

    このプログラムはファイル操作を使ったプログラムです。 import java.io.*; class k203 { public static void main(String args[]) throws IOException { int num,max,test[][]; double sum[]; String name[]; String Subj[] = {"国語","数学","社会","理科","英語"}; num = Read.readInt("人数"); test = new int[num][Subj.length]; sum = new double[Subj.length]; name = new String[num]; for(int i=0; i<num; i++) { System.out.print( (i+1)+"人目の名前:"); name[i] = Read.readString(); } System.out.print("\n"); for(int i=0; i<num; i++) { System.out.println(name[i]+"さんの点数"); for(int j=0; j<Subj.length; j++) { test[i][j] = Read.readInt(Subj[j]); sum[j] += test[i][j]; } } System.out.print("\n"); for(int j=0; j<Subj.length; j++) { max = 0; for(int i=0; i<num; i++) { if(test[i][j]>test[max][j]) { max = i; } } System.out.println(Subj[j]); System.out.println("最高点:"+test[max][j]+" "+name[max]+"さん"); System.out.println("平均点:"+sum[j]/num); System.out.print("\n"); } } } このプログラムをGUIをつかってボタンをクリックすると実行できるように したいのですがどんな感じにすればよいか教えてください!

    • ベストアンサー
    • Java
  • おみくじの出現数とそのビジュアル化

    おみくじを引いて大吉のでる回数と少しビジュアル的に10個毎に*を1個表示し、*を5個表示する毎にスペース(" ")を表示させようと思ってます。 以下のようなコードを書いたのですが、2つ問題があります。 大吉(141): ***** ***** ****とならないで、 大吉(141): ***** ***** **と2行になります。 スペースを入れた分、*の数が減ってしまうのか*の数が合いません。 解決策がお分かりの方、お教え願います。 public class Omikuzi { public static void main(String[] args) // 変数maxを宣言し7で初期化する⇒求める数字の最大値!? // 出現率収納用の変数を指定する int max = 7; int sum0 = 0; // カウンタ変数iに0を代入し、iを1000繰り返す。繰り返したあと インクリメント(1加算)する for (int i = 0; i < 1000; i++) { // Mathクラスのrandomメソッドを利用して変数randomNum に0~1未満の少数を代入する double randomNum = (Math.random()); // randomNumをmax倍し(0~max未満の小数にする)それを int型にキャストして変数numに代入する int num = (int) (randomNum * max) // if文でnumのそれぞれの値が現れたときの場合1をたし て全体の数をカウントする if (0 == num) { sum0 += 1; } } System.out.println("大吉:"+"("+sum0+")"); for (int j = 1; j <= (sum0 / 10); j++) if (j % 6 != 0) { System.out.print("*"); } else { System.out.print(" "); } } }

  • このプログラムの問題点を教えてください。

    //数独 #include <iostream.h> const int num_Max = 100; //一辺のマス最高値 void input_data( int a, int [num_Max][num_Max] ); //入力関数 void yoko_data( int a, const int [100][100], int & ); //判定 void tate_data( int a, const int [100][100], int & ); void block_data( int a, int b, const int [100][100], int & ); main() { int num; //一辺のマスの数 int m; //一ブロックの一辺にあるマスの数 int okey; //numが正常か判別 int dx, dy, dz; int masu[num_Max][num_Max]; //全部のマス cout << "\n埋められた数独が正しいかどうか判断するプログラムです。\n"; while(1){ cout << "横何マスありますか? (4-100)>>" ; cin >> num ; if( num > num_Max || num < 4){ cout <<"範囲外です。再入力して下さい。" ; }else{ m = sqrt( num ); okey = num - m * m; if(okey != 0) cout << "その数字は数独として成り立ちません。再入力して下さい。"; } } //マスの入力 input_data( num, masu ); //横判定 yoko_data( num, masu, dx ); if(dx = 0){ //縦判定 tate_data( num, masu, dy ); if(dy = 0){ //マス判定 block_data( num, m, masu, dz ); } } if(dx == dy == dz == 0) cout <<"\n大正解♪ おめでっとー。\n"; return 0; } //入力 void input_data( int kazu, const int matrix[num_Max][num_Max]) { cout <<"\nマスの数字の入力を左上から順に、右へと行って下さい。"; for(int i = 0; i < kazu; i++){ for(int j = 0; j < kazu; j++){ cout << i+1 << "行目の" << j+1 << "列目 >>"; cin >> matrix[i][j] ; } } } //横列(行)を順に判定 void yoko_hantei( int kazu, int matrix[num_Max][num_Max]) { int kaburi; //かぶっているか判定する用 int vx = 0; //かぶっていたと判定されたかどうかを見る用 for(int i = 0; i < kazu; i++){ //横一列取り出しました。 for(int j = 0; j < kazu; j++){ for( int k = 1; j+k < kazu; k++){ kaburi = matrix[i][j] - matrix[i][j+k]; if(kaburi == 0){ //かぶってたらループから抜け出す vx++; break; } } } } if(vx > 0) cout << "\n横列(行)検索時に不適切な部分を発見しました。\n"; return vx; } //縦列(列)を順に判定 void tate_hantei( int kazu, int matrix[num_Max][num_Max]) { int kaburi; //かぶっているか判定する用 int vy = 0; //かぶっていたと判定されたかどうかを見る用 for(int j = 0; j < kazu; j++){ //縦一列取り出しました。 for(int i = 0; i < kazu; i++){ for( int k = 1; k < kazu-1; k++){ kaburi = matrix[i][j] - matrix[i+k][j]; if(kaburi == 0){ //かぶってたらループから抜け出す vy++; break; } } } } if(vy > 0) cout << "\n縦列(列)検索時に不適切な部分を発見しました。\n"; return vy; } //1ブロックごとに判定 void block_data( int kazu, int ruto, int matrix[num_Max][num_Max]) { int hantei[num_Max][num_Max] ; //判定する部分を切り出す用 int kaburi; int vz; //まずブロックごとに切り出してみる for(int i = 0; i < ruto-1; i++){ for(int j = 0; j < ruto-1; j++){ int h = 0; //何ブロック目か int g = 0; //そのブロックの何個目か (h-1)++; for(int l = 0; l < ruto-1; l++){ for(int k = 0; k < ruto-1; k++){ hantei[h][g++] = matrix[i * m + k][j * m + l]; } } } } //かぶっているか判定する for(int x = 0; x < kazu; x++){ for(int y = 0; y < kazu; y++){ for( int z = 1; z < kazu-1; z++){ kaburi = hantei[x][y] - matrix[x+z][y]; if(kaburi == 0){ //かぶってたらループから抜け出す vz++; break; } } } } return vz; } C++で作成したものです。 コンパイルエラーが出てしまうのですが、原因を教えていただけませんか?

  • C言語 関数の問題

    C言語(関数の問題)で読み込んだ4つの整数の最大値を求めプログラムで 整数を2つペア比較し、関数の入れ子を用いて最大値を見つけて、表示する。 というプログラムを作成したいのですが #include<stdio.h> int maxof(int a, int b) { if(a > b) return (a); else return (b); } int max4(int a, int b, int c, int d) { max(max(a, b), max(c, d)); } int main(void) { int num1,num2, num3, num4; ------ 整数の読み込み printf("最大値は%dです。", max4(num1, num2, num3, num4)); return(0); } と記述すると、上手くいったのですが これを max関数だけを用いて作成できますでしょうか? 整数の比較は全てmax関数で行いたいです。

  • エンキューとデキューの操作関数

    エンキューとデキューの操作関数なのですが、 どのような考え方なのかがいまいちわからず困っています。 どなたか解説お願いします。 int QueueEnque(Queue *q, int x) { if(q->num >= q->max){ return (-1); }else{ q->num++; q->que[q->front++] = x; if(q->front == q->max){ q->front =0; } if(q->num ==1){ q->rear--; if(q->rear == -1){ q->rear = q->max-1; } } return (0); } } int QueueDeque(Queue *q, int *x) { if(q->num <= 0){ return (-1); }else{ q->num--; q->rear++; if(q->rear == q->max){ q->rear =0; } *x = q->que[q->rear]; if(q->num ==0){ q->front =q->rear; } return (0); } } キューを実現する構造体がこのようになっています。 typedef struct { int max; /* キューのサイズ */ int num; /* 現在の要素数 */ int front; /* 先頭要素カーソル */ int rear; /* 末尾要素カーソル */ int *que; /* キュー(の先頭要素へのポインタ) */ } Queue;

専門家に質問してみよう