基于Q-learning的栅格地图路径规划MATLAB仿真程序
MATLAB程序:Q-learning路径规划
%% ============================================================
% 基于Q-learning的路径规划MATLAB仿真程序
% 功能:在栅格地图中训练智能体从起点到终点找到最优路径
% ============================================================
clear; clc; close all;
%% 1. 创建栅格地图环境
fprintf('================== Q-learning路径规划 ==================\n');
% 地图参数设置
map_size = [10, 10]; % 10x10的栅格地图
start_pos = [1, 1]; % 起点 (行, 列)
goal_pos = [10, 10]; % 终点
obstacle_density = 0.2; % 障碍物密度 (20%)
% 生成随机障碍物地图
rng(42); % 固定随机种子,确保可重复性
map = ones(map_size); % 1=自由空间,0=障碍物
num_obstacles = round(prod(map_size) * obstacle_density);
for i = 1:num_obstacles
while true
obstacle_pos = [randi(map_size(1)), randi(map_size(2))];
% 确保障碍物不在起点和终点
if ~isequal(obstacle_pos, start_pos) && ~isequal(obstacle_pos, goal_pos)
map(obstacle_pos(1), obstacle_pos(2)) = 0;
break;
end
end
end
% 显示地图
figure('Position', [100, 100, 800, 600]);
subplot(2, 3, [1, 2, 4, 5]);
imagesc(map);
colormap([0.3, 0.3, 0.3; 0.9, 0.9, 0.9]); % 障碍物深灰,自由区域浅灰
hold on;
plot(start_pos(2), start_pos(1), 'go', 'MarkerSize', 15, 'LineWidth', 2);
plot(goal_pos(2), goal_pos(1), 'r*', 'MarkerSize', 15, 'LineWidth', 2);
grid on;
set(gca, 'XTick', 1:map_size(2), 'YTick', 1:map_size(1));
xlabel('列坐标'); ylabel('行坐标');
title('栅格地图环境 (绿色:起点, 红色:终点)');
legend('起点', '终点', 'Location', 'northeastoutside');
%% 2. Q-learning参数设置
fprintf('设置Q-learning参数...\n');
% 学习参数
alpha = 0.1; % 学习率 - 控制新信息的影响程度
gamma = 0.9; % 折扣因子 - 控制未来奖励的重要性
epsilon = 0.3; % 探索率 - 随机探索的概率
max_episodes = 500; % 最大训练回合数
max_steps = 100; % 每个回合最大步数
% 动作空间: 上(1), 右(2), 下(3), 左(4)
actions = 4;
action_names = {'上', '右', '下', '左'};
action_vectors = [-1, 0; 0, 1; 1, 0; 0, -1];
% 初始化Q表 (状态数 x 动作数)
state_count = prod(map_size);
Q = zeros(state_count, actions);
% 奖励函数设置
R_goal = 100; % 到达终点的奖励
R_obstacle = -100; % 撞到障碍物的惩罚
R_step = -1; % 每步的惩罚(鼓励最短路径)
R_boundary = -50; % 撞到边界的惩罚
%% 3. 辅助函数:状态编码与解码
% 将二维位置编码为一维状态索引
state_to_index = @(pos) (pos(1)-1)*map_size(2) + pos(2);
% 将一维状态索引解码为二维位置
index_to_state = @(idx) [floor((idx-1)/map_size(2))+1, mod(idx-1, map_size(2))+1];
%% 4. Q-learning训练过程
fprintf('开始Q-learning训练...\n');
% 存储训练数据用于分析
rewards_history = zeros(max_episodes, 1);
steps_history = zeros(max_episodes, 1);
success_history = false(max_episodes, 1);
for episode = 1:max_episodes
% 初始化状态(起点)
current_state = start_pos;
current_state_idx = state_to_index(current_state);
episode_reward = 0;
done = false;
% 动态调整探索率(随时间衰减)
epsilon_decayed = epsilon * (1 - episode/max_episodes);
for step = 1:max_steps
% ε-贪婪策略选择动作
if rand() < epsilon_decayed
% 探索:随机选择动作
action = randi(actions);
else
% 利用:选择Q值最大的动作
[~, action] = max(Q(current_state_idx, :));
end
% 执行动作,计算新状态
next_state = current_state + action_vectors(action, :);
% 检查边界
if next_state(1) < 1 || next_state(1) > map_size(1) || ...
next_state(2) < 1 || next_state(2) > map_size(2)
reward = R_boundary;
next_state = current_state; % 保持原地
done = true;
% 检查障碍物
elseif map(next_state(1), next_state(2)) == 0
reward = R_obstacle;
done = true;
% 检查是否到达终点
elseif isequal(next_state, goal_pos)
reward = R_goal;
done = true;
else
reward = R_step;
end
% 计算下一个状态索引
next_state_idx = state_to_index(next_state);
% Q-learning更新公式
Q_current = Q(current_state_idx, action);
Q_max_next = max(Q(next_state_idx, :));
Q(current_state_idx, action) = Q_current + alpha * (reward + gamma * Q_max_next - Q_current);
% 更新累计奖励和状态
episode_reward = episode_reward + reward;
current_state = next_state;
current_state_idx = next_state_idx;
% 检查回合是否结束
if done
steps_history(episode) = step;
success_history(episode) = isequal(current_state, goal_pos);
break;
end
if step == max_steps
steps_history(episode) = max_steps;
success_history(episode) = false;
end
end
rewards_history(episode) = episode_reward;
% 每50回合显示进度
if mod(episode, 50) == 0
success_rate = mean(success_history(1:episode)) * 100;
fprintf(' 回合 %d/%d | 平均奖励: %.2f | 成功率: %.1f%%\n', ...
episode, max_episodes, mean(rewards_history(1:episode)), success_rate);
end
end
%% 5. 训练结果可视化
fprintf('训练完成!可视化结果...\n');
% 绘制训练曲线
subplot(2, 3, 3);
plot(1:max_episodes, rewards_history, 'b-', 'LineWidth', 1);
xlabel('训练回合');
ylabel('回合奖励');
title('奖励收敛曲线');
grid on;
subplot(2, 3, 6);
success_rate_moving = movmean(success_history, 50) * 100;
plot(1:max_episodes, success_rate_moving, 'r-', 'LineWidth', 2);
xlabel('训练回合');
ylabel('成功率 (%)');
title('学习成功率(50回合移动平均)');
ylim([0, 100]);
grid on;
%% 6. 使用训练好的Q表规划最优路径
fprintf('使用训练好的策略规划路径...\n');
% 从起点开始
path = [start_pos];
current_state = start_pos;
current_state_idx = state_to_index(current_state);
path_found = true;
max_path_length = 50; % 最大路径长度
for i = 1:max_path_length
% 使用贪婪策略选择动作
[~, action] = max(Q(current_state_idx, :));
% 执行动作
next_state = current_state + action_vectors(action, :);
% 检查有效性
if next_state(1) < 1 || next_state(1) > map_size(1) || ...
next_state(2) < 1 || next_state(2) > map_size(2) || ...
map(next_state(1), next_state(2)) == 0
fprintf('警告:路径规划遇到障碍物或边界!\n');
path_found = false;
break;
end
% 添加到路径
path = [path; next_state];
% 检查是否到达终点
if isequal(next_state, goal_pos)
fprintf('成功找到路径!路径长度:%d步\n', size(path, 1)-1);
break;
end
% 更新状态
current_state = next_state;
current_state_idx = state_to_index(current_state);
if i == max_path_length
fprintf('警告:达到最大路径长度,可能未找到终点!\n');
path_found = false;
end
end
%% 7. 可视化最终路径
subplot(2, 3, [1, 2, 4, 5]);
hold on;
if path_found
% 绘制路径
path_x = path(:, 2);
path_y = path(:, 1);
plot(path_x, path_y, 'b-', 'LineWidth', 2);
plot(path_x, path_y, 'bo', 'MarkerSize', 8, 'MarkerFaceColor', 'b');
% 显示路径信息
text(1, map_size(1)+0.5, sprintf('路径长度: %d步', size(path, 1)-1), ...
'FontSize', 10, 'FontWeight', 'bold');
else
text(map_size(2)/2, map_size(1)/2, '路径未找到!', ...
'HorizontalAlignment', 'center', 'FontSize', 14, 'FontWeight', 'bold', 'Color', 'r');
end
% 添加图例
legend_items = {'起点', '终点', '路径'};
h_legend = legend(legend_items, 'Location', 'northeastoutside');
set(h_legend, 'FontSize', 10);
%% 8. 可视化策略(箭头图)
figure('Position', [950, 100, 800, 600]);
subplot(1, 2, 1);
% 创建策略矩阵
policy_map = zeros(map_size);
for r = 1:map_size(1)
for c = 1:map_size(2)
if map(r, c) == 1 && ~isequal([r, c], goal_pos)
state_idx = state_to_index([r, c]);
[~, best_action] = max(Q(state_idx, :));
policy_map(r, c) = best_action;
end
end
end
% 绘制策略热图
imagesc(policy_map);
colormap(jet(4));
colorbar('Ticks', 1:4, 'TickLabels', action_names);
hold on;
% 标记起点和终点
plot(start_pos(2), start_pos(1), 'go', 'MarkerSize', 15, 'LineWidth', 2);
plot(goal_pos(2), goal_pos(1), 'r*', 'MarkerSize', 15, 'LineWidth', 2);
% 绘制障碍物
[obs_r, obs_c] = find(map == 0);
plot(obs_c, obs_r, 'ks', 'MarkerSize', 10, 'MarkerFaceColor', 'k');
title('最优策略可视化(颜色表示动作方向)');
xlabel('列坐标'); ylabel('行坐标');
set(gca, 'XTick', 1:map_size(2), 'YTick', 1:map_size(1));
grid on;
%% 9. 绘制Q值热图
subplot(1, 2, 2);
% 计算每个状态的最高Q值
max_Q_map = zeros(map_size);
for r = 1:map_size(1)
for c = 1:map_size(2)
if map(r, c) == 1
state_idx = state_to_index([r, c]);
max_Q_map(r, c) = max(Q(state_idx, :));
end
end
end
% 将障碍物的Q值设为NaN(显示为白色)
max_Q_map(map == 0) = NaN;
imagesc(max_Q_map);
colormap(jet);
colorbar;
hold on;
% 标记起点和终点
plot(start_pos(2), start_pos(1), 'go', 'MarkerSize', 15, 'LineWidth', 2);
plot(goal_pos(2), goal_pos(1), 'r*', 'MarkerSize', 15, 'LineWidth', 2);
title('状态最大Q值热图');
xlabel('列坐标'); ylabel('行坐标');
set(gca, 'XTick', 1:map_size(2), 'YTick', 1:map_size(1));
grid on;
%% 10. 性能统计与输出
fprintf('\n=============== 训练结果统计 ===============\n');
final_success_rate = mean(success_history) * 100;
fprintf('最终成功率: %.2f%%\n', final_success_rate);
fprintf('平均回合奖励: %.2f\n', mean(rewards_history));
fprintf('平均步数: %.2f\n', mean(steps_history(success_history)));
fprintf('Q表大小: %d 状态 × %d 动作\n', size(Q, 1), size(Q, 2));
% 保存训练结果
save('q_learning_path_planning_results.mat', ...
'Q', 'map', 'start_pos', 'goal_pos', ...
'rewards_history', 'success_history', 'steps_history', ...
'alpha', 'gamma', 'epsilon', 'max_episodes');
fprintf('\n结果已保存到 q_learning_path_planning_results.mat\n');
参考代码 基于增强学习Q-learning方法的路径规划matlab仿真程序 www.3dddown.com/cna/45533.html
关键模块详解
1. 环境建模
- 使用栅格地图表示环境(1=自由,0=障碍)
- 状态编码:将二维位置
(row, col)编码为一维索引 - 动作空间:4个方向(上、下、左、右)
2. Q-learning核心算法
-
Q值更新公式:
Q(s,a) = Q(s,a) + α * [r + γ * max(Q(s',a')) - Q(s,a)]其中:
- α:学习率(控制新信息的影响)
- γ:折扣因子(权衡即时/未来奖励)
- ε:探索率(平衡探索与利用)
-
ε-贪婪策略:以ε概率随机探索,否则选择当前最优动作
3. 奖励函数设计
% 奖励函数是关键,它引导智能体学习:
% 到达终点: +100 (鼓励完成任务)
% 撞障碍物: -100 (避免碰撞)
% 每走一步: -1 (鼓励最短路径)
% 出边界: -50 (保持在边界内)
参数调优
| 参数 | 典型范围 | 影响 | 调整建议 |
|---|---|---|---|
| 学习率 α | 0.01-0.5 | 学习速度 | 从0.1开始,收敛慢则增大,震荡则减小 |
| 折扣因子 γ | 0.8-0.99 | 未来奖励重要性 | 长期任务用0.9-0.99,短期用0.8 |
| 探索率 ε | 0.1-0.5 | 探索程度 | 训练初期0.3,后期衰减到0.1 |
| 训练回合数 | 500-5000 | 训练充分性 | 简单地图500,复杂地图2000+ |
扩展与改进方向
1. 添加动态障碍物
% 在训练过程中随机移动障碍物
if mod(episode, 100) == 0
% 随机选择一个障碍物移动到新位置
map = move_obstacle_randomly(map, start_pos, goal_pos);
end
2. 使用深度Q网络(DQN)处理大状态空间
% 当地图很大时,可以用神经网络近似Q函数
% 替换Q表为神经网络
net = create_dqn_network(map_size);
3. 多目标路径规划
% 修改奖励函数,使智能体依次访问多个目标点
goal_sequence = {[5,5], [10,10], [3,8]};
current_goal_index = 1;
4. 实时路径重规划
% 检测环境变化时重新规划
function new_path = replan_path(Q, current_pos, goal_pos, new_map)
% 使用当前Q表和新地图重新规划
end
使用建议与调试技巧
-
训练失败常见原因:
- 学习率太高:Q值震荡不收敛 → 减小α
- 探索率太低:陷入局部最优 → 增大ε
- 奖励设计不合理:调整奖励值比例
- 训练回合不足:增加max_episodes
-
性能优化:
% 使用稀疏矩阵存储Q表(大型地图) Q = sparse(state_count, actions); % 并行训练多个智能体 parfor episode = 1:max_episodes % 并行训练代码 end -
可视化调试:
- 观察奖励曲线是否上升
- 检查成功率是否提高
- 可视化中间路径了解学习过程
这个程序提供了完整的Q-learning路径规划实现。你可以通过修改地图大小、障碍物分布、奖励函数等来适应不同场景。

浙公网安备 33010602011771号