迷宫路径规划是机器人导航领域的经典问题,传统方法如A*算法在静态环境中表现良好,但在未知或动态环境中适应性较差。Q-learning作为一种无模型强化学习算法,通过试错机制自主学习最优策略,特别适合解决这类问题。我在工业机器人项目中多次应用该算法,发现其最大优势在于不需要预先构建环境模型,机器人可以在探索过程中逐步优化决策。
Q-learning的核心是Q表,它记录了每个状态-动作对的预期累积奖励。在迷宫环境中,状态通常对应机器人所在位置,动作则是移动方向(上、下、左、右)。算法通过贝尔曼方程迭代更新Q值:
code复制Q(s,a) ← Q(s,a) + α[r + γ·max(Q(s',a')) - Q(s,a)]
其中α(学习率)控制新知识的吸收速度,γ(折扣因子)平衡当前与未来奖励。实际应用中,我发现α=0.2-0.5、γ=0.8-0.95的组合在大多数迷宫场景下表现稳定。
在Matlab中实现时,我通常用二维矩阵表示迷宫:
matlab复制function [maze2D,row,col] = Read_Maze(fileName)
data = importdata(fileName);
maze2D = double(data);
[row,col] = find(maze2D == 50); % 定位起点
end
注意:迷宫文件建议使用.txt格式,每行代表一行栅格,数字间用空格分隔。我遇到过UTF-8编码导致读取错误的情况,建议保存为ANSI编码。
Q表是三维矩阵,维度为[行数, 列数, 动作数]:
matlab复制Q = zeros(size(maze2D,1), size(maze2D,2), 4); % 4个动作
实践中发现,用微小随机数初始化(如0.01*randn())比全零初始化收敛更快。这是因为初始差异可以促进早期探索,避免算法陷入对称性困境。
平衡探索与利用的关键参数ε通常设置为:
matlab复制epsilon = 0.7; % 初始探索概率
epsilon_decay = 0.995; % 每轮衰减系数
在动作选择时:
matlab复制if rand() < epsilon
action = randi(4); % 随机探索
else
[~, action] = max(Q(row,col,:)); % 选择最优动作
end
epsilon = epsilon * epsilon_decay; % 衰减探索率
经过多个项目验证,以下奖励结构效果较好:
matlab复制function reward = get_reward(new_row, new_col, goalX, goalY, status)
if status == 3 % 到达终点
reward = 100;
elseif status == 2 % 撞墙
reward = -10;
else
dist = abs(new_row-goalX) + abs(new_col-goalY);
reward = -0.1 + 1/dist;
end
end
固定学习率可能导致后期震荡。我采用指数衰减:
matlab复制alpha_init = 0.8;
alpha_decay = 0.999;
alpha = alpha_init * (alpha_decay^episode);
除了固定迭代次数,建议添加:
现象:机器人反复在同一区域徘徊
解决方法:
对于30×30以上的迷宫:
当检测到环境变化时:
matlab复制for episode = 1:NUM_ITERATIONS
% 重置环境
[row, col] = start_pos;
status = -1;
steps = 0;
while status ~= 3 && steps < MAX_STEPS
% 选择动作
action = select_action(Q, row, col, epsilon);
% 执行动作
[new_row, new_col, status] = move_robot(row, col, action);
% 计算奖励
reward = get_reward(new_row, new_col, goalX, goalY, status);
% 更新Q值
Q = update_Q(Q, row, col, new_row, new_col, action, reward, alpha, gamma);
% 更新状态
row = new_row; col = new_col;
steps = steps + 1;
end
% 衰减参数
epsilon = epsilon * epsilon_decay;
alpha = alpha * alpha_decay;
end
动作选择函数:
matlab复制function action = select_action(Q, row, col, epsilon)
if rand() < epsilon
action = randi(4);
else
[~, action] = max(squeeze(Q(row,col,:)));
end
end
Q值更新函数:
matlab复制function Q = update_Q(Q, row, col, new_row, new_col, action, reward, alpha, gamma)
current_Q = Q(row,col,action);
max_next_Q = max(Q(new_row,new_col,:));
Q(row,col,action) = current_Q + alpha*(reward + gamma*max_next_Q - current_Q);
end
记录每轮步数并绘制学习曲线:
matlab复制figure;
plot(1:NUM_ITERATIONS, step_history);
xlabel('训练轮次');
ylabel('步数');
title('学习曲线');
grid on;
训练后提取最优路径:
matlab复制path = [];
[row, col] = start_pos;
while ~(row == goalX && col == goalY)
[~, action] = max(Q(row,col,:));
path = [path; [row, col]];
[row, col] = move_robot(row, col, action);
end
在9×9迷宫中:
对于超大迷宫(100×100+),可用DQN:
matlab复制layers = [
imageInputLayer([size(maze2D) 1])
convolution2dLayer(3,32,'Padding','same')
reluLayer
fullyConnectedLayer(4)
regressionLayer];
共享经验池设计:
使用MATLAB Coder生成C代码:
matlab复制cfg = coder.config('lib');
codegen train_qlearning -config cfg -args {coder.Constant('maze.txt'), 1000}
在嵌入式平台(如Raspberry Pi)上可实现10倍速度提升。我在一个AGV项目中实测,路径规划耗时从120ms降至15ms。