Python(強化学習の試し12_迷路07_迷路サンプル3)
■経路選択を調べるためのサンプル。
最適なルートがぱっとみ分からないような、少し複雑な迷路サンプルを使って強化学習を見ようとしたけど、処理に時間がかかりすぎる。そのため、迷路のサンプルをCUIにする。
とりあえず正常に動くか下の迷路で試す。

CUI用のコードは下のもの。初期のデータに上の 0, 1, 2, 3 のリストを入れる(灰色部分は除く)。
import numpy as np
import copy
maze = []
mazeinitdata = [[1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 1, 0, 0, 0, 1], [1, 0, 1, 0, 1, 0, 1, 2, 1],
[1, 0, 1, 0, 0, 0, 1, 0, 1], [1, 0, 1, 1, 1, 0, 1, 0, 1], [1, 0, 2, 0, 1, 2, 1, 0, 1],
[1, 0, 1, 0, 1, 1, 1, 0, 1], [1, 0, 1, 0, 0, 0, 0, 3, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1]]
Qtable = np.zeros((9, 9, 4))
option = 2
def get_action(py, px, epsilon):
if epsilon > np.random.uniform(0, 1):
next_action = np.random.choice([0, 1, 2, 3])
else:
a = np.where(Qtable[py - 1][px - 1] == Qtable[py - 1][px - 1].max())[0]
next_action = np.random.choice(a)
return next_action
def update_Qtable(py, px, action, reward, next_py, next_px):
gamma = 0.5
alpha = 0.1
next_maxQ = max(Qtable[next_py - 1][next_px - 1])
Qtable[py - 1, px - 1, action] = (1 - alpha) * Qtable[py - 1, px - 1, action] + alpha * (reward + gamma * next_maxQ)
return Qtable
def main():
point = 0
step = 0
px = 1
py = 1
tryCount = 0
maze = copy.deepcopy(mazeinitdata)
masterMazeRecord = [[1,1]]
epsilon = np.linspace(start=1.0, stop=0.0, num=100)
while True:
if option == 1:
old_x, old_y = px, py
step = step + 1
rndInt = np.random.choice([0, 1, 2, 3])
if rndInt == 0:
px -= 1
elif rndInt == 1:
px += 1
elif rndInt == 2:
py -= 1
elif rndInt == 3:
py += 1
if maze[py][px] == 1:
px, py = old_x, old_y
step = step - 1
elif maze[py][px] == 2:
maze[py][px] = 0
point = point + 10
elif maze[py][px] == 3:
masterMazeRecord.append([py, px])
tryCount += 1
print(tryCount, ":", masterMazeRecord)
if tryCount % 1 == 0:
print("終り", "Result:" + str(point) + " Step: " + str(step) + " Try:" + str(
tryCount) + " RecordPos" + str(len(masterMazeRecord)))
point = 0
step = 0
maze.clear()
masterMazeRecord.clear()
maze = copy.deepcopy(mazeinitdata)
px = 1
py = 1
exit()
masterMazeRecord.append([py, px])
elif option == 2:
old_x, old_y = px, py
step = step + 1
reward = 1
action = get_action(py, px, epsilon[tryCount])
pre_py = py
pre_px = px
if action == 0:
px -= 1
elif action == 1:
px += 1
elif action == 2:
py -= 1
elif action == 3:
py += 1
if maze[py][px] == 1:
reward = 0
px, py = old_x, old_y
step = step - 1
elif maze[py][px] == 2:
maze[py][px] = 0
point = point + 10
reward = 10
elif maze[py][px] == 3:
reward = 20
update_Qtable(pre_py, pre_px, action, reward, py, px)
masterMazeRecord.append([py, px])
tryCount += 1
print(tryCount, ":", masterMazeRecord)
if tryCount == 1 or tryCount % 50 == 0:
print("Q", Qtable)
if tryCount % 100 == 0:
print("終り", "Result:" + str(point) + " Step: " + str(step) + " Try:" + str(
tryCount) + " RecordPos" + str(len(masterMazeRecord)))
point = 0
step = 0
maze.clear()
masterMazeRecord.clear()
maze = copy.deepcopy(mazeinitdata)
px = 1
py = 1
if tryCount == 100:
exit()
update_Qtable(pre_py, pre_px, action, reward, py, px)
masterMazeRecord.append([py, px])
if __name__ == '__main__':
main()
出てきた結果に対して、通った場所をカウントすると下の結果となった。壁の部分はカウント0となっており、正しく動作しているよう。
[37, 41, 40, 0, 5, 2, 2]
[35, 0, 74, 0, 18, 0, 0]
[34, 0, 68, 55, 41, 0, 0]
[46, 0, 0, 0, 35, 0, 0]
[47, 78, 42, 0, 59, 0, 0]
[57, 0, 22, 0, 0, 0, 0]
[34, 0, 29, 30, 10, 3, 0]
このコードを使って下のようにいろいろな経路でゴールに行けるような迷路サンプルを使って、報酬部分や学習率などを変えて動作を確認してみたい。

ちなみに上のコードをChatGPTで、同じ機能を維持して短くしてもらうように入力すると、行数が半分くらいになった。