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

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

新規登録して質問してみよう
ただいま回答率
85.48%
強化学習

強化学習とは、ある環境下のエージェントが現状を推測し行動を決定することで報酬を獲得するという見解から、その報酬を最大限に得る方策を学ぶ機械学習のことを指します。問題解決時に得る報酬が選択結果によって変化することで、より良い行動を選択しようと学習する点が特徴です。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

1回答

1779閲覧

undefined method `+' for nil:NilClass (NoMethodError)の原因がわからない。

nori0519

総合スコア16

強化学習

強化学習とは、ある環境下のエージェントが現状を推測し行動を決定することで報酬を獲得するという見解から、その報酬を最大限に得る方策を学ぶ機械学習のことを指します。問題解決時に得る報酬が選択結果によって変化することで、より良い行動を選択しようと学習する点が特徴です。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2019/12/04 08:52

前提・実現したいこと

Rubyでグリッドワールドにおけるエージェントの強化学習システムを作っています。
矢印の長さ(u[][]上方向,d[][]下方向,l[][]左方向.r[][]右方向)の値をもとにしてエージェントの次のグリッドに確率的に移動するという機能を実装するために、ra(0~999の範囲の乱数値を最大値(999)で割ったもの)とu[][]/sum,(u[][]+d[][])/sum,(u[][]+d[][]+r[][])/sumあるいは、1の値と比較することで上記の確率で移動する機能を実装中に以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ

Traceback (most recent call last): 4: from learning.rb:155:in `<main>' 3: from learning.rb:155:in `each' 2: from learning.rb:167:in `block in <main>' 1: from learning.rb:167:in `each' learning.rb:168:in `block (2 levels) in <main>': undefined method `+' for nil:NilClass (NoMethodError)

該当のソースコード

ruby

1sum = u[ey][ex] + d[ey][ex] + r[ey][ex] + l[ey][ex] 2 ra =rand(0..999)/999.to_f 3 puts"移動前のエージェントの座補(x,y)=(#{ex},#{ey})" 4 puts"sum:#{sum}" 5 puts"ra:#{ra}" 6 puts"u:#{u[ey][ex]}" 7 puts"d:#{d[ey][ex]}" 8 puts"l:#{l[ey][ex]}" 9 puts"r:#{r[ey][ex]}" 10 11 if ex==gx && ey==gy#スタート地点とゴール地点が同じ場合、終了する。(そのエージェントはゴールする。ただし、報酬なし) 12 e_g+=1#ゴールしたエージェントのカウント 13 14 break 15 puts"_________________________________エージェント#{enum}人目ゴール" 16 end 17=begin 18 u_c =u[ey][ex] / sum 19 puts "u_c:#{u_c}" 20=end 21 if ra<u[ey][ex]/sum 22 history_x[h] =ex 23 history_y[h] =ey #エージェントの経路記録 24 25 #u_h[h]=1#エージェントがどちらに行ったのかの軌跡の記録 26 27 ey =ey-1 28 elsif ra < (u[ey][ex]+d[ey][ex]) / sum 29 history_x[h] =ex 30 history_y[h] =ey 31 32 #d_h[h]=1 33 ey =ey+1 34 elsif ra < (u[ey][ex]+d[ey][ex]+r[ey][ex]) / sum 35 history_x[h] =ex 36 history_y[h] =ey 37 38 #r_h[h]=1 39 40 ex =ex-1 41 else 42 history_x[h] =ex 43 history_y[h] =ey 44 45 #l_h[h]=1 46 47 ex =ex+1 48 end 49 50

###全体のソースコード

Ruby

1#1.環境の設計 2 3puts"グリッドワールドの大きさを教えてください。(n×n)" 4n = gets.to_i 5puts"n:#{n}" 6#グリッドワールドの大きさを取得する。 7puts"エージェントの人数を教えてください。" 8enum =gets.to_i 9#エージェントがスタートに設置されて、矢印の長さを更新されるまでの過程を何回くりかえすか。(エージェントの個数) 10puts"エージェントの寿命は何ステップですか。" 11elife =gets.to_i 12#エージェントの寿命の指定 13x =0 14y =0 15#現在座標 16gx_h =[] 17gy_h =[] 18#ゴールの座標の記録 19arrow =Array.new(n).map {Array.new(n,0)} 20#グリッドワー ルド作成 21gx =rand(0..n-1) 22gy =rand(0..n-1) 23puts"goal(x,y):(#{gx},#{gy})" 24#グリッドワールドの任意の位置にゴールを設置 25#gx_h[k]=gx 26#gy_h[k]=gy 27#ゴールの座標を記録 28u =Array.new(n).map{Array.new(n,0)} 29d =Array.new(n).map{Array.new(n,0)} 30r =Array.new(n).map{Array.new(n,0)} 31l =Array.new(n).map{Array.new(n,0)} 32#上下左右の矢印の長さを格納 33history_x =[] 34history_y =[] 35=begin 36u_h =[] 37d_h =[] 38r_h =[] 39l_h =[] 40=end 41#エージェントの過去の移動履歴 42p =1 43#エージェントがゴールに到達した際の総報酬 44t =1 45#ゴールからさかのぼったエージェントのステップ数(ゴールからtステップ前) 46e_g =0 47#ゴールしたエージェントの数 48puts"n-1:#{n-1}" 49 50u[0][0]=0 #(0,0) 51l[0][0]=0 52d[0][0]=0.5 53r[0][0]=0.5 54puts"四つ角" 55puts"u[0][0]:#{u[0][0]}" 56puts"d[0][0]:#{d[0][0]}" 57puts"r[0][0]:#{r[0][0]}" 58puts"l[0][0]:#{l[0][0]}" 59 60d[n-1][0]=0 #(0,n-1) 61l[n-1][0]=0 62u[n-1][0]=0.5 63r[n-1][0]=0.5 64puts"u[#{n-1}][0]:#{u[n-1][0]}" 65puts"d[n-1][0]:#{d[n-1][0]}" 66puts"r[n-1][0]:#{r[n-1][0]}" 67puts"l[n-1][0]:#{l[n-1][0]}" 68 69u[0][n-1]=0 #(n-1,0) 70r[0][n-1]=0 71d[0][n-1]=0.5 72l[0][n-1]=0.5 73puts"u[0][#{n-1}]:#{u[0][n-1]}" 74puts"d[0][n-1]:#{d[0][n-1]}" 75puts"r[0][n-1]:#{r[0][n-1]}" 76puts"l[0][n-1]:#{l[0][n-1]}" 77 78d[n-1][n-1]=0 #(n-1,n-1) 79r[n-1][n-1]=0 80u[n-1][n-1]=0.5 81l[n-1][n-1]=0.5 82puts "u[#{n-1}][#{n-1}]:#{u[n-1][n-1]}" 83puts "d[n-1][n-1]:#{d[n-1][n-1]}" 84puts "r[n-1][n-1]:#{r[n-1][n-1]}" 85puts "l[n-1][n-1]:#{l[n-1][n-1]}" 86puts"__________________________________" 87#四つ角 88for i in 1..n-2 do 89 u[0][i] =0 #上側 90 d[0][i] =0.3 91 r[0][i] =0.3 92 l[0][i] =0.4 93 puts"上側" 94 puts"u(#{i},0):#{u[0][i]}" 95 puts"d(#{i},0):#{d[0][i]}" 96 puts"r(#{i},0):#{r[0][i]}" 97 puts"l(#{i},0):#{l[0][i]}" 98 puts"__________________________________" 99 100 d[n-1][i] =0 #下側 101 u[n-1][i] =0.3 102 r[n-1][i] =0.3 103 l[n-1][i] =0.4 104 puts"下側" 105 puts"u(#{i},#{n-1}):#{u[n-1][i]}" 106 puts"d(#{i},#{n-1}):#{d[n-1][i]}" 107 puts"r(#{i},#{n-1}):#{r[n-1][i]}" 108 puts"l(#{i},#{n-1}):#{l[n-1][i]}" 109 puts"__________________________________" 110 111 l[i][0]=0 #左側 112 u[i][0]=0.3 113 d[i][0]=0.3 114 r[i][0]=0.4 115 puts"左側" 116 puts"u(0,#{i}):#{u[i][0]}" 117 puts"d(0,#{i}):#{d[i][0]}" 118 puts"r(0,#{i}):#{r[i][0]}" 119 puts"l(0,#{i}):#{l[i][0]}" 120 puts"__________________________________" 121 122 r[i][n-1]=0 #右側 123 u[i][n-1]=0.3 124 d[i][n-1]=0.3 125 l[i][n-1]=0.4 126 puts"右側" 127 puts"u(#{n-1},#{i}):#{u[i][n-1]}" 128 puts"d(#{n-1},#{i}):#{d[i][n-1]}" 129 puts"r(#{n-1},#{i}):#{r[i][n-1]}" 130 puts"l(#{n-1},#{i}):#{l[i][n-1]}" 131 puts"__________________________________" 132end 133#残りの壁 134#境界線の作成(確率を0にする。)ついでに他の方向の矢印にも確立を格納する。(環境の初期化) 135 136for i in 1..n-2 do 137 for j in 1..n-2 do 138 u[i][j]=0.25 139 d[i][j]=0.25 140 r[i][j]=0.25 141 l[i][j]=0.25 142 puts"他のグリッド" 143 puts"u(#{j},#{i}):#{u[i][j]}" 144 puts"d(#{j},#{i}):#{d[i][j]}" 145 puts"r(#{j},#{i}):#{r[i][j]}" 146 puts"l(#{j},#{i}):#{l[i][j]}" 147 puts"__________________________________" 148 end 149end 150#他のグリッドに確率を格納(等確立の0.25) 151 152#_________________________________________________________________________________________________________________________ 153 154#2.学習 155for k in 1..enum do #エージェントの個数分繰り返す。 156 157 sx =rand(0..n-1) 158 sy =rand(0..n-1) 159 puts"start(x,y):(#{sx},#{sy})" 160 #startを,グリッドワールドにランダムに格納 161 162 ex =sx 163 ey =sy 164 puts"エージェントの座標(ex,ey):(#{ex},#{ey})" 165 #エージェントの作成(スタート地点に設置) 166 167 for h in 0..elife-1 do #hはエージェント寿命である。四つの矢印の長さを使って確率的に移動する。もしゴールについたらforから脱出する。 168 sum = u[ey][ex] + d[ey][ex] + r[ey][ex] + l[ey][ex] 169 ra =rand(0..999)/999.to_f 170 puts"移動前のエージェントの座補(x,y)=(#{ex},#{ey})" 171 puts"sum:#{sum}" 172 puts"ra:#{ra}" 173 puts"u:#{u[ey][ex]}" 174 puts"d:#{d[ey][ex]}" 175 puts"l:#{l[ey][ex]}" 176 puts"r:#{r[ey][ex]}" 177 178 if ex==gx && ey==gy#スタート地点とゴール地点が同じ場合、終了する。(そのエージェントはゴールする。ただし、報酬なし) 179 e_g+=1#ゴールしたエージェントのカウント 180 181 break 182 puts"_________________________________エージェント#{enum}人目ゴール" 183 end 184=begin 185 u_c =u[ey][ex] / sum 186 puts "u_c:#{u_c}" 187=end 188 if ra<u[ey][ex]/sum 189 history_x[h] =ex 190 history_y[h] =ey #エージェントの経路記録 191 192 #u_h[h]=1#エージェントがどちらに行ったのかの軌跡の記録 193 194 ey =ey-1 195 elsif ra < (u[ey][ex]+d[ey][ex]) / sum 196 history_x[h] =ex 197 history_y[h] =ey 198 199 #d_h[h]=1 200 ey =ey+1 201 elsif ra < (u[ey][ex]+d[ey][ex]+r[ey][ex]) / sum 202 history_x[h] =ex 203 history_y[h] =ey 204 205 #r_h[h]=1 206 207 ex =ex-1 208 else 209 history_x[h] =ex 210 history_y[h] =ey 211 212 #l_h[h]=1 213 214 ex =ex+1 215 end 216 217 puts"移動前のエージェントの座標(x,y):(#{history_x[h]},#{history_y[h]})(履歴から引用)" 218 puts"移動後のエージェントの座標(x,y):(#{ex},#{ey})" 219 puts"________*________*____________*_______________*__________" 220 221 if ex==gx && ey==gy 222 T =h#エージェントの移動距離(エージェントの寿命) 223 puts"逆順前"#配列を逆順にする(先入先出法の実現) 224 p history_x 225 p history_y 226 227 history_x.reverse 228 history_y.reverse 229 230 puts"逆順後" 231 p history_x 232 p history_y 233 234 for rb in 0..h do #rollback(ここで報酬を分配する。) 235 e_g+=1#ゴールしたエージェントのカウント 236 237 if history_x[h] ==history_x[h-1]&&history_y[h]>history_y[h-1] 238 u[history_x[h-1]][history_y[h-1]] = u[history_x[h-1]][history_y[h-1]]+p*(T-t+1/T) 239 elsif history_x[h]==history_x[h-1]&&history_y[h]<history_y[h-1] 240 d[history_x[h-1]][history_y[h-1]] = d[history_x[h-1]][history_y[h-1]]+p*(T-t+1/T) 241 elsif history_x[h]>history_x[h-1]&&history_y[h]==history_y[h-1] 242 r[history_x[h-1]][history_y[h-1]] = r[history_x[h-1]][history_y[h-1]]+p*(T-t+1/T) 243 else 244 l[history_x[h-1]][history_y[h-1]] = l[history_x[h-1]][history_y[h-1]]+p*(T-t+1/T) 245 end 246 t+=1#エージェントのtステップ前の更新 247=begin 248 u_h[h]=nil 249 d_h[h]=nil 250 r_h[h]=nil 251 l_h[h]=nil 252=end 253 end 254 history_x.clear #エージェントの履歴をリセットする。 255 history_y.clear 256 break 257 end 258 end 259end 260 261puts"ゴールしたエージェントの数:#{e_g}" 262 263 264 265 266

試したこと

恐らく、sum以下の部分が原因だと思いましたので、+の前後に空白など入れてみましたが結果は変わりませんでした。

補足情報(FW/ツールのバージョンなど)

version

1ruby 2.6.3p62 (2019-04-16 revision 67580) [x64-mingw32]

よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

nilクラスには '+' という名前のメソッドはありませんよというエラーです。

恐らく、コードのどこかで、意図せずnilに数値を加算しているか、文字列を結合しています。

それをやめれば、エラーは解決されると思います。

コードの解析はしていません。

投稿2019/12/04 13:17

編集2019/12/04 13:18
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

nori0519

2019/12/04 13:19

エージェントが壁の外に行っていたようで、u[ey][ex],d[ey][ex],l[ey][ex],r[ey][ex]がnilになっておりました。 こちらを行かないように修正したところ直りました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問