Описание задачи:

– Агент начинает в случайной точке лабиринта.

– Он должен найти путь к выходу, избегая стен.

– Если агент сталкивается со стеной, он получает отрицательную награду.

– Если агент достиг цели (выхода), он получает положительную награду.

Мы будем использовать Q-learning для обучения агента, где Q-значения будут обновляться в процессе взаимодействия агента с лабиринтом.

Пример кода для задачи навигации по лабиринту с использованием Q-Learning:

```python

import numpy as np

import random

# Параметры лабиринта

maze = [

[0, 0, 0, 0, 0],

[0, 1, 1, 0, 0],

[0, 0, 0, 1, 0],

[0, 1, 0, 0, 0],

[0, 0, 0, 1, 2]

]

# 0 – свободная клетка

# 1 – стена

# 2 – выход

# Размеры лабиринта

n_rows = len(maze)

n_cols = len(maze[0])

# Гиперпараметры Q-learning

learning_rate = 0.1 # Скорость обучения

discount_factor = 0.9 # Дисконтирование

epsilon = 0.2 # Эпсилон для epsilon-greedy

num_episodes = 1000 # Количество эпизодов обучения

# Инициализация Q-таблицы

q_table = np.zeros((n_rows, n_cols, 4)) # 4 действия: вверх, вниз, влево, вправо

actions = [(-1, 0), (1, 0), (0, -1), (0, 1)] # Действия: (изменение по строкам, изменение по столбцам)

# Функция выбора действия с использованием epsilon-greedy

def epsilon_greedy(state):

if random.uniform(0, 1) < epsilon:

return random.choice([0, 1, 2, 3]) # Случайное действие

else:

return np.argmax(q_table[state[0], state[1]]) # Лучшее действие по Q-таблице

# Функция проверки, находится ли клетка внутри лабиринта и является ли она свободной

def is_valid_move(state, action):

new_row = state[0] + actions[action][0]

new_col = state[1] + actions[action][1]

if 0 <= new_row < n_rows and 0 <= new_col < n_cols and maze[new_row][new_col] != 1:

return True

return False

# Обучение

for episode in range(num_episodes):

state = (0, 0) # Начальное состояние (агент стартует в верхнем левом углу)

done = False

total_reward = 0

while not done:

action = epsilon_greedy(state) # Выбор действия

if is_valid_move(state, action):

next_state = (state[0] + actions[action][0], state[1] + actions[action][1])

else:

next_state = state # Если движение невозможно, остаемся на месте

# Получение награды

if maze[next_state[0]][next_state[1]] == 2:

reward = 100 # Если агент достиг выхода, награда

done = True

elif maze[next_state[0]][next_state[1]] == 1:

reward = -10 # Если агент столкнулся со стеной, штраф

else:

reward = -1 # Пустая клетка, небольшая отрицательная награда для побуждения к поиску выхода

# Обновление Q-таблицы

q_table[state[0], state[1], action] = q_table[state[0], state[1], action] + learning_rate * (

reward + discount_factor * np.max(q_table[next_state[0], next_state[1]]) – q_table[state[0], state[1], action]

)

state = next_state # Переход к следующему состоянию

total_reward += reward

if episode % 100 == 0:

print(f"Episode {episode}/{num_episodes}, Total Reward: {total_reward}")

# Тестирование обученной модели

state = (0, 0)

done = False

total_reward = 0

steps = []

while not done:

action = np.argmax(q_table[state[0], state[1]]) # Лучшее действие по Q-таблице

if is_valid_move(state, action):

next_state = (state[0] + actions[action][0], state[1] + actions[action][1])

else:

next_state = state

# Получение награды

if maze[next_state[0]][next_state[1]] == 2:

reward = 100

done = True

elif maze[next_state[0]][next_state[1]] == 1:

reward = -10

else:

reward = -1

state = next_state

total_reward += reward

steps.append(state)

print(f"Test Total Reward: {total_reward}")

print("Optimal path to the exit:")

print(steps)

```

Объяснение шагов кода:

1. Определение лабиринта: Лабиринт задан двумерным массивом, где 0 – это свободная клетка, 1 – стена, а 2 – выход. Агент должен найти путь из верхнего левого угла к выходу, избегая стен.