首页 > 其他分享 >Q-learning原理及代码实现

Q-learning原理及代码实现

时间:2024-11-02 20:18:48浏览次数:5  
标签:状态 动作 代码 奖励 state learning 原理 size

目录

1. Q-learning原理        

  1.1 Q值

  1.2  更新规则

  1.3  目标

  1.4  探索与利用

2.代码实现

  2.1 代码示例

  2.2 解释


1. Q-learning原理        

        Q-learning是一种基于值强化学习算法,用于在不依赖环境模型的情况下学习最优策略。它的目标是通过学习动作-状态对的价值(即Q值),找到使得累计奖励最大的策略。以下是Q-learning的关键步骤和公式:

  1.1 Q值

        Q值(动作价值)是一个函数,表示在某一状态下选择某一动作后,能够获得的未来累计奖励。Q值表示为 Q(s, a),其中 s 是当前状态,a 是当前动作。

  1.2  更新规则

        Q-learning 的核心是 Q 值的更新公式。在每一步,Q-learning 会通过与环境交互,更新对应的 Q 值:

Q(s, a) \leftarrow Q(s, a) + \alpha \left[ r + \gamma \max_{a'} Q(s', a') - Q(s, a) \right]

其中:

  • Q(s, a) 是当前 Q 值
  • \alpha 是学习率,控制更新的速度
  • r 是执行动作后获得的即时奖励
  • \gamma 是折扣因子,权衡当前奖励和未来奖励的影响
  • \max_{a'} Q(s', a') 是在新状态 s' 下所有可能动作的最大 Q 值

  1.3  目标

        通过反复更新Q值,Q-learning可以逐渐逼近最优动作价值函数 Q^*(s, a)。这样,在每个状态下,选择Q值最大的动作就能得到最优策略。

  1.4  探索与利用

        Q-learning 需要平衡“探索”和“利用”:

  • 探索:选择随机动作,以探索新的可能性。
  • 利用:选择当前 Q 值最高的动作,以获得最大奖励。

        常用的探索策略是 \epsilon-贪心策略,即以概率 \epsilon 随机选择动作,以概率 1 - \epsilon 选择当前最佳动作。

        Q-learning 已广泛应用于游戏、路径规划等领域,特别适合在离散状态和动作空间下的控制任务。


2.代码实现

        我们可以用一个简单的迷宫问题来举例,展示如何使用Q-learning找到从起点到终点的最优路径。假设一个5x5的迷宫,其中:

  • 起点在左上角(0, 0),终点在右下角(4, 4)。
  • 代理(智能体)每次可以向上、下、左、右四个方向移动。
  • 如果撞墙或走出边界,则返回到该状态,并获得-1的奖励。
  • 到达终点时获得+10的奖励。
  • 其余位置每次移动获得-0.1的奖励,以鼓励代理尽快找到终点。

  2.1 代码示例

        以下是一个基于Q-learning的简单实现,用来训练智能体找到从起点到终点的最短路径。

import numpy as np
import random

# 环境设置
maze_size = 5
goal = (4, 4)  # 目标状态
actions = ['up', 'down', 'left', 'right']  # 动作空间
action_dict = {'up': (-1, 0), 'down': (1, 0), 'left': (0, -1), 'right': (0, 1)}

# Q-learning参数
alpha = 0.1       # 学习率
gamma = 0.9       # 折扣因子
epsilon = 0.1     # 探索概率
episodes = 5000   # 训练轮数

# 初始化Q表
Q_table = np.zeros((maze_size, maze_size, len(actions)))

# 定义奖励函数
def get_reward(state):
    if state == goal:
        return 10
    else:
        return -0.1

# 获取下一个状态
def next_state(state, action):
    row, col = state
    move = action_dict[action]
    next_row, next_col = row + move[0], col + move[1]
    if 0 <= next_row < maze_size and 0 <= next_col < maze_size:
        return (next_row, next_col)
    else:
        return state  # 撞墙则停在原地

# Q-learning算法
for episode in range(episodes):
    state = (0, 0)  # 初始状态
    while state != goal:
        # 选择动作
        if random.uniform(0, 1) < epsilon:
            action_index = random.randint(0, len(actions) - 1)  # 随机选择动作
        else:
            action_index = np.argmax(Q_table[state[0], state[1]])  # 利用Q值选择最优动作
        action = actions[action_index]

        # 执行动作,观察奖励和下一个状态
        next_state_ = next_state(state, action)
        reward = get_reward(next_state_)

        # 更新Q值
        best_next_action = np.argmax(Q_table[next_state_[0], next_state_[1]])
        Q_table[state[0], state[1], action_index] += alpha * (reward + gamma * Q_table[next_state_[0], next_state_[1], best_next_action] - Q_table[state[0], state[1], action_index])

        # 状态更新
        state = next_state_

# 打印结果Q表
print("Learned Q-table:")
print(Q_table)

# 显示路径
state = (0, 0)
path = [state]
while state != goal:
    action_index = np.argmax(Q_table[state[0], state[1]])
    action = actions[action_index]
    state = next_state(state, action)
    path.append(state)

print("Optimal path from start to goal:", path)

  2.2 解释

  1. 环境初始化:我们定义了一个5x5的迷宫,每个位置可以向上、下、左、右四个方向移动。
  2. Q表更新:Q表存储在Q_table中,维度为(maze_size, maze_size, len(actions))。每个状态在四个方向上有一个Q值。
  3. 训练过程
    • 通过epsilon-贪心策略选择动作,以平衡探索和利用。
    • 根据所选动作获得奖励,计算下一个状态,并用更新规则调整当前状态的Q值。
  4. 输出路径:训练完成后,输出从起点到目标的最优路径。

        通过多次迭代,智能体将学习到从左上角到右下角的最短路径。

标签:状态,动作,代码,奖励,state,learning,原理,size
From: https://blog.csdn.net/qq_56683019/article/details/143416630

相关文章

  • chrome浏览器断点调试工具之无限debugger的原理与绕过
    文章目录1、debugger介绍2、无限debugger案例演示3、无限debugger解决方法3.1实现原理3.2方法1:禁用断点(全局)3.3方法2:局部禁用(1)3.4方法3:局部禁用(2)3.5方法4:利用第三方工具fiddler解除无限debug1、debugger介绍debugger是JavaScript中定义的一个专门用于断点调......
  • 软件工程 - 如何平衡代码质量和项目进度 - 论CICD的重要性
    共同愿景在软件工程的视角里,代码质量与项目进度是朝向同一个方向的作用力,彼此之间互相促进,它们拥有同一个愿景:保质保量的完成项目。项目周期内,团队时间的分配上维度上也不是矛盾的,是彼此分工不同,但相辅相成。通过均衡科学分配代码质量时间与项目开发时间,让项目的左膀右臂......
  • 软件系统设计 - 代码优化 代码重构 - 正确的重构方式 与 重构手法列表
    正确的重构方式:不会引入错误并有条不紊地改进程序结构熟练掌握众多重构手法,将思辨与实践结合,迭代持续开展重构工作。运用大量微小且保持软件行为的重构步骤,一步步达成大规模的修改。在开始重构前,我们需要先通读代码,并尝试理解代码如何工作,然后通过重构将这些理解从脑海里......
  • 《代码大全》读后感-第一章
    当我翻开《代码大全》这本书,开始阅读第一章时,仿佛开启了一场充满智慧与启迪的编程之旅。这一章犹如一把钥匙,为我打开了通往高质量软件开发世界的大门,让我对软件构建有了全新的认识和深刻的感悟。第一章以一种引人入胜的方式介绍了软件构建的重要性和复杂性。它让我明白,软件构建不......
  • 基于51单片机温湿度采集数码管手机app显示+源代码程序+proteus仿真+dht11温湿度传感器
    一、设计简介本项目是简单的物联网(IoT)应用,使用51单片机STC89C52与温湿度传感器DHT11相结合,测量温湿度数据显示在八位数码管,同时通过WiFi模块ESP8266(ESP-01S)将测得的温湿度数据发送到手机APP上,而手机APP则使用AppInventor进行开发。二、功能设计1、数码管实时显示当前温湿度......
  • 《代码大全》读后感-十一章
    第十一章着重探讨了变量的使用,这看似基础的部分,实则蕴含着无尽的奥秘和重要性。变量作为编程的基本元素之一,其正确的运用直接关系到程序的可读性、可维护性以及性能表现。开篇,书中强调了使用变量的一般事项。它让我明白变量不仅仅是存储数据的容器,更是构建清晰逻辑和高效算法的基......
  • 《代码大全》读后感-第九章
    第九章着重探讨了高质量的类和子程序的编写,这对于软件开发来说至关重要。在当今复杂的软件系统中,类和子程序是构建软件大厦的基石,其质量直接决定了整个软件的稳定性、可维护性和可扩展性。首先,书中强调了类的设计。一个好的类应该具有明确的职责和清晰的接口。职责单一的类更容易......
  • C++游戏代码
        这是我们班一个大聪明LQH做的,大家看看怎么样,如果很好,关注sum不想++,他能告诉你彩damn.#include<bits/stdc++.h>#include<windows.h>usingnamespacestd;voidmai(intxxx,intx1,intx2,intx3,intma11,intma12,intma13,intma21,intma22,intma23,in......
  • 数组篇-代码随想录
    数组篇跳-二分查找-704-力扣classSolution{publicintsearch(int[]nums,inttarget){if(nums==null||nums.length==0)return-1;if(target<nums[0]||target>nums[nums.length-1])return-1;intleft=0,......
  • 代码随想录一刷day6 (链表day2)(链表完结)
    24.两两交换链表中的节点分三步走;1.创建dummyhead2.三个指针 cur  t1 t23.  cur->next=t2;  t1->next=t2->next;  t2->t1->next; 最后让cur=t1;注意最后返回的是dummyhead-》next 而不是head;注意最后deletedummyhead19.删除链表的倒数第N个节点注......