强化学习代码-利用Q-learning实现三维世界的路径规划-002 可以保存和读取策略、Python+TensorFlow 内容:在三维的立体空间中,存在大量的障碍物,如何规避障碍物,找到一条从初始点到终点的最优路径,改程序通过强化学习Q-learning的方法寻找到一条最优路径。 图中蓝色点表示可用走路径,黑色点表示障碍物
当我们把路径规划问题搬到三维空间,事情就开始变得有意思了。想象你操控的无人机不仅要避开摩天大楼,还得在立体交通网里找到最短路线——这可比平面导航刺激多了。今天咱们用最经典的Q-learning算法,手把手实现个能保存经验的智能体。
先来搭环境骨架。咱们用三维网格世界,障碍物用坐标黑名单实现:
class GridWorld3D: def __init__(self, size=10): self.size = size self.obstacles = set() for _ in range(int(size*0.3)): x, y = np.random.randint(0, size, 2) self.obstacles.update({(x,y,z) for z in range(size)}) def is_valid(self, pos): return (0 <= pos[0] < self.size and 0 <= pos[1] < self.size and 0 <= pos[2] < self.size and tuple(pos) not in self.obstacles)这里有个小技巧:用集合存储障碍物坐标,判断碰撞时直接查表比遍历列表快10倍不止。注意我们生成的是贯穿整个高度的柱状障碍,模拟现实中的建筑物。
接下来是重头戏Q-learning的实现。考虑到三维状态空间爆炸问题,咱们用字典实现稀疏存储:
class QAgent: def __init__(self, alpha=0.1, gamma=0.9): self.q_table = defaultdict(lambda: np.zeros(6)) # 6个移动方向 self.alpha = alpha # 学习率 self.gamma = gamma # 折扣因子 def get_action(self, state, epsilon): if np.random.rand() < epsilon: return np.random.randint(6) else: return np.argmax(self.q_table[state])这里用defaultdict自动处理未访问过的状态,避免初始化整个状态空间。动作对应六个移动方向:±x, ±y, ±z,相当于在三维网格中上下左右前后移动。
强化学习代码-利用Q-learning实现三维世界的路径规划-002 可以保存和读取策略、Python+TensorFlow 内容:在三维的立体空间中,存在大量的障碍物,如何规避障碍物,找到一条从初始点到终点的最优路径,改程序通过强化学习Q-learning的方法寻找到一条最优路径。 图中蓝色点表示可用走路径,黑色点表示障碍物
训练循环的关键在于奖励设计。咱们给成功到达终点+100奖励,碰撞-50,每步-1鼓励最短路径:
def train(env, agent, episodes=1000): epsilon = 1.0 for ep in range(episodes): state = env.start_pos while True: action = agent.get_action(state, epsilon) next_pos = move(state, action) # 根据动作计算新坐标 reward = -1 if not env.is_valid(next_pos): reward = -50 next_pos = state # 碰撞后停留在原地 elif next_pos == env.goal: reward = 100 # Q值更新公式 old_q = agent.q_table[state][action] max_next_q = np.max(agent.q_table[next_pos]) new_q = (1 - agent.alpha)*old_q + agent.alpha*(reward + agent.gamma*max_next_q) agent.q_table[state][action] = new_q # 更新状态 state = next_pos if state == env.goal or ep % 100 == 0: break epsilon *= 0.995 # 探索衰减注意当撞墙时让智能体留在原地,这比直接结束回合更能训练出避障能力。epsilon的指数衰减让智能体从随机探索逐步过渡到利用已有经验。
模型保存用TensorFlow的Saver虽然有点杀鸡用牛刀,但确实方便:
def save_model(sess, q_table, path='model'): # 将字典转为Tensor states = tf.constant(list(q_table.keys()), name='states') q_values = tf.constant([q_table[k] for k in q_table], name='q_values') saver = tf.train.Saver() sess.run(tf.global_variables_initializer()) saver.save(sess, path) def load_model(path): sess = tf.Session() saver = tf.train.import_meta_graph(path+'.meta') saver.restore(sess, path) states = sess.run('states:0') q_values = sess.run('q_values:0') return {s:q for s,q in zip(states, q_values)}这里有个坑:直接保存Python字典会丢失类型信息,转成Tensor再存更可靠。恢复时要注意Tensor的命名空间,建议在保存时显式指定name参数。
实际跑起来后会发现,在10x10x10的网格中,大约训练500次后智能体就能稳定找到无障碍最优路径。遇到复杂障碍时,可以通过以下方法提升表现:
- 增加ε衰减周期,让探索更充分
- 对重复撞墙的行为施加额外惩罚
- 在状态编码中加入周边障碍信息
最后说个实战技巧:用matplotlib的scatter3D做可视化时,把探索过的路径用淡蓝色半透明显示,最优路径用红色高亮,障碍物用黑色立方体,一眼就能看出智能体是不是在"抄近道"。
完整代码已打包放在Github,包含预训练模型和交互式演示。下次遇到三维路径规划,别急着上A*,试试这个会自己成长的方案说不定有惊喜。