- 博客(633)
- 问答 (1)
- 收藏
- 关注
原创 【强化学习】PPO(Proximal Policy Optimization,近端策略优化)
PPO(近端策略优化)是OpenAI提出的强化学习算法,作为TRPO的简化版本,旨在解决传统策略梯度方法中更新过大导致性能崩坏的问题。PPO通过限制策略更新幅度实现稳定训练,主要有两种实现方式:PPO-Clip(通过裁剪机制限制更新幅度)和PPO-Penalty(通过KL散度约束限制更新)。PPO-Clip的核心包括近端比率裁剪损失和价值函数损失,前者通过限制策略更新幅度确保稳定性,后者用于优化策略。此外,PPO还引入熵奖励项以增强策略的探索性。PPO的工作流程包括初始化模型、采样指令、生成回答、评估奖励、
2025-11-10 20:19:12
1027
原创 【强化学习】信任区域策略优化(Trust Region Policy Optimization,TRPO)
摘要:本文介绍了信任区域策略优化(TRPO)算法,针对策略梯度法(PG)存在的数据利用率低、更新幅度不可控等问题进行了改进。TRPO通过引入信任区域概念,在优化目标中加入KL散度约束,确保新策略不会偏离旧策略太远。其核心在于使用重要性采样修正策略分布偏差,允许对同一批数据进行多次小批量更新,提高样本利用率。相比PG,TRPO能实现更稳定的策略优化和性能提升,为后续PPO算法的提出奠定了基础。
2025-11-07 01:56:22
982
原创 【强化学习】重要性采样
重要性采样(Importance Sampling)是一种**利用从一个分布中采样得到的数据来估计另一个分布的期望值**的方法,在蒙特卡洛方法中是一种常用的技巧,用于提高估计的效率和准确性。这种方法适用于目标分布难以直接采样,或者直接采样效率较低的情况。在强化学习中主要用于解决**异策略(Off-policy)学习**
2025-11-07 01:41:54
825
原创 【强化学习】同策略学习(On-Policy )与异策略学习(Off-Policy )
摘要: 强化学习中的策略优化分为同策略(On-Policy)和异策略(Off-Policy)两类。同策略(如SARSA、PPO)直接通过目标策略与环境交互采集数据,样本分布一致但利用率低;异策略(如Q-Learning、DQN)则通过行为策略采集数据供目标策略学习,支持数据复用和离线训练,但需重要性采样解决分布偏差问题。前者训练稳定但效率低,后者样本利用率高但需处理分布差异。典型算法的选择取决于任务对样本效率与稳定性的需求。
2025-11-07 01:39:02
424
原创 【强化学习】优势函数与广义优势估计
摘要: 优势函数$A^\pi(s,a)=Q^\pi(s,a)-V^\pi(s)$衡量动作$a$在状态$s$下优于平均策略的程度。为简化计算,通常用TD误差$\delta_t=r_t+\gamma V^\pi(s_{t+1})-V^\pi(s_t)$近似优势函数。广义优势估计(GAE)通过参数$\lambda$平衡偏差与方差,融合多步TD残差:$A_t=\sum_{k=0}^T (\gamma\lambda)^k \delta_{t+k}$。当$\lambda=0$时为单步TD,$\lambda=1$接近蒙特
2025-11-07 01:31:36
805
原创 【强化学习】 Actor-Critic(AC)方法
Actor-Critic 方法基于值函数 (Value-based) 和基于策略 (Policy-based) 方法的优点,核心思想是:**利用 Critic 网络来评估当前策略的好坏,然后 Actor 网络根据 Critic 的评估结果来更新策略**。
2025-11-07 01:26:37
331
原创 【强化学习】时序差分法(TD,Temporal Difference)估计
摘要:时序差分法(TD)通过单步采样更新价值函数,克服了蒙特卡洛(MC)方法需完整回合的缺点。MC采用真实回报更新无偏但方差大,TD使用下一状态估计值更新偏差较大但方差小。TD更新公式为V(s_t)←V(s_t)+η[r_t+γV(s_{t+1})-V(s_t)],相比MC效率更高但精度较低。
2025-11-07 01:25:24
810
原创 【强化学习】蒙特卡洛(Monte Carlo)方法
蒙特卡洛采样(Monte Carlo Sampling)是一种通过多次随机采样来近似计算 “难以直接求解的期望或积分” 的方法。其核心思想是:对于一个随机变量的期望(如强化学习中的累积回报期望),如果无法通过数学公式直接计算,就通过大量随机采样的结果来近似计算期望。
2025-11-07 01:20:48
926
原创 【强化学习】 REINFORCE 算法
摘要:REINFORCE算法改进了策略梯度法,通过使用"rewards to go"($G_t$)替代总回报$G(\tau)$,只考虑当前及未来奖励。为进一步降低方差,算法引入基线(baseline),即状态价值函数$V^\pi(s)$,通过优势函数$A^\pi(s,a)=Q^\pi(s,a)-V^\pi(s)$评估动作相对优势。带基线的REINFORCE通过$G_t-b(s_t)$计算梯度,其中$b(s_t)$由价值网络估计,提高了策略更新的稳定性。(150字)
2025-11-07 01:07:49
890
原创 【强化学习】基于策略的强化学习算法——策略梯度法
本文介绍了基于策略的强化学习方法中的策略梯度法(PG)。与基于值函数的方法不同,PG直接优化参数化策略πθ(a|s),通过梯度上升最大化期望累积奖励J(θ)。策略梯度定理表明,J(θ)的梯度可表示为轨迹回报与动作对数概率梯度的乘积期望。PG使用时采用蒙特卡洛采样估计梯度:当轨迹回报为正时增加对应动作概率,为负时降低概率。这种方法避免了基于值函数的间接优化,直接调整策略参数使高回报动作更可能被选择。
2025-11-02 17:33:51
892
原创 【强化学习】 基于价值的强化学习算法
本文介绍了两种基于价值的强化学习算法:价值迭代和Q-learning。价值迭代通过动态规划方法反复更新价值函数直至收敛,从而提取最优策略,适用于已知环境模型的情况。Q-learning则是一种无模型的值迭代算法,通过更新Q函数来学习最优策略,适合于未知环境下的学习任务。两种方法都通过优化价值函数(状态价值函数V(s)或状态-动作价值函数Q(s,a))来间接推导最优策略,最终使智能体能够选择带来最大长期回报的动作。文章还分别给出了两种算法的基本流程图解。
2025-11-02 17:20:53
356
原创 【强化学习】强化学习原理及相关概念介绍
强化学习(Reinforcement Learning, RL)是一种机器学习方法,它通过智能体(Agent)与环境(Environment)交互来学习策略(Policy),使得在不同状态(State)下采取的动作(Action)能够最大化累积奖励(Reward)。强化学习的核心思想是试错学习(Trial-and-Error Learning)和延迟奖励(Delayed Reward)
2025-11-02 17:12:35
350
原创 Leetcode 114. 二叉树展开为链表 前序遍历 /原地遍历
本文介绍了Leetcode 114题"二叉树展开为链表"的四种解法。前两种解法使用前序遍历,分别采用递归和迭代方式存储节点顺序,再重新构建右子树链表。第三种解法使用栈进行迭代遍历,在遍历过程中直接修改指针。第四种解法通过寻找左子树的最右节点,进行原地指针调整。所有解法的时间复杂度均为O(n),空间复杂度前三种为O(n),最后一种为O(1)。这些方法都实现了将二叉树按前序遍历顺序展开为单链表的功能。
2025-10-05 14:32:48
250
原创 Leetcode 84. 柱状图中最大的矩形 单调栈
文章摘要: 本文介绍了Leetcode 84题"柱状图中最大的矩形"的三种解法。第一种暴力枚举宽度,时间复杂度O(n²)会超时;第二种暴力枚举高度,同样O(n²)复杂度;第三种采用单调栈优化,通过维护递增栈快速计算左右边界,时间复杂度优化至O(n)。单调栈解法通过添加哨兵节点简化边界处理,在遍历时动态计算当前高度对应的最大矩形面积。最终给出的C++实现展示了这一高效算法的具体实现细节。
2025-10-05 14:15:53
251
原创 Leetcode 75. 颜色分类 荷兰国旗问题 插入排序 / 分区
本文介绍了两种解决Leetcode 75题(颜色分类)的高效算法: 插入排序法:通过维护p0和p1两个指针,在单次遍历中将0和1依次插入正确位置,时间复杂度O(n),空间复杂度O(1)。 分区法:使用left、right和i三个指针将数组划分为0区、1区和2区。通过交换元素动态调整区间边界,最终完成排序。这种方法同样满足一次遍历和原地排序的要求。 两种方法都优于简单的排序或计数排序,提供了更优的空间和时间复杂度解决方案。
2025-10-05 13:27:50
336
原创 Leetcode 295. 数据流的中位数 堆
文章摘要:本文介绍了两种堆解法来高效查找数据流的中位数。核心思想是使用大顶堆存储左半部分数据(堆顶为最大值),小顶堆存储右半部分数据(堆顶为最小值)。解法1通过条件判断维护两个堆的大小关系,解法2采用更简洁的交换策略确保左堆大小始终等于或比右堆大1。两种方法都能在O(1)时间内获取中位数,其中解法2通过统一处理将插入操作简化为固定步骤。时间复杂度均为O(log n)的插入和O(1)的查询。
2025-10-04 21:48:19
327
原创 Leetcode 347. 前 K 个高频元素 堆 / 优先队列
本文介绍了Leetcode 347题"前K个高频元素"的一种解法。使用小顶堆(优先队列)来维护出现频率最高的K个元素,时间复杂度优于O(n log n)。首先统计每个元素的出现频率,然后遍历频率表,维护一个大小为K的小顶堆:当堆满时,若当前元素频率大于堆顶则替换。最终堆中即为前K高频元素。该方法通过控制堆大小避免了全排序,满足题目进阶要求。代码实现使用了自定义比较器构建小顶堆,最后输出结果时需逆序处理。
2025-10-04 21:22:08
364
原创 【数据结构】非线性数据结构——堆
堆是一种完全二叉树结构,分为大根堆(父节点≥子节点)和小根堆(父节点≤子节点),通常用数组存储。核心操作包括插入(上浮调整)、删除堆顶(下沉调整)和建堆(自底向上调整),时间复杂度均为O(log n)。堆的主要应用包括堆排序(O(n log n))、优先队列和Top K问题。堆排序分为构建大顶堆和排序两大阶段:首先从最后一个非叶子节点开始调整建立堆结构,然后通过反复交换堆顶元素与末尾元素并调整堆,实现原地排序。示例代码展示了堆排序的具体实现过程。
2025-10-04 20:13:21
1067
原创 Leetcode 215. 数组中的第K个最大元素 快速排序 / 堆排序
本文介绍了LeetCode 215题「数组中的第K个最大元素」的多种解法。重点比较了三种快速排序实现:第一种超时;第二种基于官解的双指针法;第三种采用分治思想,通过随机选取基准值将数组分为大、等、小三部分。还提供了堆排序解法,包括使用优先队列的简洁实现。不同方法在时间/空间复杂度上各有优劣,快速排序平均O(n),最坏O(n²);堆排序为O(nlogn)。
2025-10-04 17:28:06
251
原创 计算机如何生成随机数? 什么是种子?
摘要:随机数分为伪随机数(PRNG)和真随机数(TRNG)两类。PRNG通过确定性算法和初始种子生成看似随机的数列,具有可预测性和周期性,通常采用动态变量(如系统时间)作为种子提高随机性。TRNG则从物理世界的不确定性(如电子噪声、量子现象)中提取信息,具有真正的随机性和不可预测性。PRNG是计算机最常用的随机数类型,而TRNG适用于对安全性要求更高的场景。
2025-10-04 16:38:30
207
原创 Leetcode 239. 滑动窗口最大值 优先队列 / 双向单调队列
本文介绍了两种解决Leetcode 239题"滑动窗口最大值"的方法。第一种使用优先队列存储当前窗口的最大值,通过维护一个存储值和索引的大根堆,在滑动窗口时移除过期元素来获取最大值,时间复杂度为O(nlogn)。第二种采用双向单调非递增队列,在遍历过程中维护一个单调递减队列,确保队首始终是当前窗口最大值,时间复杂度优化至O(n)。后者更高效,通过实时淘汰不可能成为最大值的元素实现最优解。两种方法都提供了清晰的代码实现。
2025-10-03 10:55:48
231
原创 Leetcode 76. 最小覆盖子串 滑动窗口+哈希表
摘要: 该算法解决最小覆盖子串问题,要求在字符串s中找到包含字符串t所有字符的最短子串。使用滑动窗口和哈希表统计字符出现次数:先统计t中字符频次,再用双指针遍历s。右指针扩展窗口,当窗口包含t所有字符时,左指针收缩窗口以寻找最小长度。时间复杂度O(n),空间复杂度O(m),其中n为s长度,m为t的字符种类数。最终返回满足条件的最短子串或空串。 关键词:滑动窗口、哈希表、双指针、字符串匹配
2025-10-02 21:27:51
154
原创 Leetcode 208. 实现 Trie (前缀树)
本文实现了一个前缀树(Trie)数据结构,用于高效存储和查询字符串。通过定义节点结构Node(包含结束标志位isend和26个子节点指针数组),构建多叉树结构。类Trie提供三个核心操作:insert插入单词时逐字符创建路径并标记终点;search检查单词是否存在;startsWith判断是否有前缀匹配。关键函数searchPrefix通过遍历字符查找对应节点,时间复杂度为O(L)(L为字符串长度)。该实现适用于字典查询、自动补全等场景,空间换时间特性显著。
2025-09-25 22:41:31
262
原创 Leetcode 148. 排序链表 归并排序
本文介绍了两种归并排序方法来解决Leetcode 148题(排序链表)。方法一采用自顶向下的递归方式,通过快慢指针找到链表中间节点进行分割,然后递归排序并合并两个有序子链表。方法二采用自底向上的迭代方式,先计算链表长度,然后按不同子链表长度逐步合并。两种方法的核心都是实现链表的分割和有序合并操作,其中合并操作通过递归方式处理。时间复杂度均为O(nlogn),空间复杂度分别为O(logn)和O(1)。
2025-09-25 22:04:01
305
原创 Leetcode 146. LRU 缓存 哈希表 + 双向链表
本文介绍了LRU(最近最少使用)缓存机制的设计原理与C++实现。LRU缓存通过淘汰最近最少使用的数据来优化存储空间,其核心操作包括快速查找、更新优先级和淘汰旧数据。文章采用"哈希表+双向链表"结构实现,哈希表保证O(1)查找,双向链表维护访问顺序。代码实现包含节点结构定义、缓存初始化、数据存取方法(get/put),以及链表操作辅助函数(添加到头部、移除节点、移动节点等)。当缓存满时,会移除链表尾部节点并更新哈希表。这种设计能高效满足LRU缓存的访问和淘汰需求。
2025-09-25 17:40:55
397
原创 Leetcode 138. 随机链表的复制 哈希 / 拼接+拆分
这道题目要求深度复制一个带有随机指针的链表。解题思路主要有两种方法: 哈希表法:使用哈希表存储原节点与新节点的映射关系。第一次遍历创建新节点,第二次遍历设置新节点的next和random指针。时间复杂度O(n),空间复杂度O(n)。 拼接+拆分法:在原链表中每个节点后面插入其复制节点,设置random指针后再拆分链表。时间复杂度O(n),空间复杂度O(1)。关键步骤包括:节点复制、random指针设置和链表拆分。 两种方法都能正确实现链表的深度复制,哈希表法更直观,而拼接法更节省空间。
2025-09-25 12:13:48
210
原创 Leetcode 4. 两两交换链表中的节点 递归 / 迭代
两两交换链表节点问题有两种解法。递归解法通过交换当前节点与下一节点,并递归处理剩余链表;迭代解法使用指针遍历链表,每次交换相邻节点,并维护前驱指针保证链表连续性。两种方法的时间复杂度均为O(n),递归空间复杂度为O(n)(栈空间),迭代为O(1)。关键点在于正确处理节点交换顺序和边界条件(空链表或单节点链表)。
2025-09-25 11:28:42
284
原创 Leetcod 739. 每日温度 栈
文章摘要: 该题目要求根据每日温度数组计算需要等待多少天才能迎来更高温度。两种解法均采用单调栈策略:维护一个存储温度和索引的栈,当遇到更高温度时,弹栈并计算天数差。解法一通过条件分支分别处理温度升高和降低的情况;解法二简化了逻辑,统一在循环外压栈。两种方法时间复杂度均为O(n),空间复杂度O(n)。关键点在于利用单调栈保持温度递减顺序,高效处理"下一个更大元素"问题。
2025-09-24 18:24:07
227
原创 Leetcode 394. 字符串解码 栈
LeetCode 394题要求解码形如"3[a2[c]]"的字符串为"accaccacc"。使用栈结构处理嵌套:遇到数字计算倍数,遇到字母暂存结果,遇到'['将当前结果和倍数入栈,遇到']'弹栈并重复拼接字符串。解法时间复杂度O(n),空间复杂度O(n),有效处理了嵌套括号的字符串解码问题。
2025-09-24 16:41:26
173
原创 Leetcode 155. 最小栈 辅助栈
LeetCode 155题要求设计一个能在O(1)时间内完成push、pop、top和获取最小值操作的最小栈。提供了两种解法:1)使用辅助栈同步存储最小值,push/pop时同步操作两个栈;2)使用单个栈存储元素值和当前最小值的pair,通过比较更新最小值。两种方法都能满足题目要求,第一种空间占用略多但实现直观,第二种更简洁但每次操作需处理pair结构。两种解法的时间复杂度均为O(1),空间复杂度O(n)。
2025-09-24 15:53:59
259
原创 Leetcode 437. 路径总和 III DFS /前缀和+哈希表
本文介绍了两种解决二叉树路径总和问题的算法。第一种采用DFS深度优先搜索,递归遍历每个节点作为起点,统计满足条件的路径数,时间复杂度O(n^2)。第二种使用前缀和+哈希表的优化方法,通过记录路径前缀和快速查找目标差值,将时间复杂度降至O(n)。两种方法各有特点:DFS实现简单但效率较低,适合小规模数据;前缀和方法更高效但需要额外空间存储哈希表,适合处理大规模二叉树。两种解法都采用递归实现,体现了树形结构的典型处理方式。
2025-09-23 15:13:05
268
原创 Leetcode 199. 二叉树的右视图 层序遍历
本文介绍了Leetcode 199题"二叉树的右视图"的层序遍历解法。题目要求返回从右侧观察二叉树时能看到的节点值序列。给出的C++解决方案使用BFS层序遍历,在每层处理时记录第一个节点值(即最右侧节点),然后优先将右子节点入队,再处理左子节点。这种方法确保每层的最右侧节点被首先访问并记录,时间复杂度为O(n),空间复杂度为O(n)。代码简洁高效,通过队列实现层序遍历,最终返回右视图的节点值序列。
2025-09-23 12:38:26
216
原创 Leetcode 230. 二叉搜索树中第 K 小的元素 中序遍历
本文通过Leetcode 230题讲解如何在二叉搜索树中找到第k小的元素。二叉搜索树的中序遍历结果即为升序排列,因此可以采用中序遍历的方法。算法使用栈进行迭代遍历:先将所有左子节点压栈,然后依次弹出栈顶元素并访问,同时递减k值。当k减至0时返回当前节点值。这种方法的时间复杂度为O(H+k),空间复杂度为O(H),H为树的高度。该解法高效地利用了二叉搜索树的性质,通过迭代避免了递归的额外空间开销。
2025-09-23 12:24:30
207
原创 Leetcode 98. 验证二叉搜索树 递归/中序遍历
摘要: Leetcode 98题要求验证给定的二叉树是否是二叉搜索树(BST)。二叉搜索树需满足左子树所有节点值小于根节点,右子树所有节点值大于根节点,且左右子树也必须是BST。本文提供了三种解法: 递归法:通过传递上下界(low和high)验证每个节点是否在合法范围内。 中序遍历法(递归):中序遍历BST应得到严格递增序列,通过检查序列是否有序判断。 中序遍历法(迭代):使用栈模拟递归,实时比较当前节点与前驱节点值,确保严格递增。 三种方法时间复杂度均为O(n),空间复杂度递归法为O(h)(h为树高),中
2025-09-23 12:10:52
203
原创 Leetcode 108. 将有序数组转换为二叉搜索树 递归
摘要: Leetcode 108题要求将有序数组转换为高度平衡的二叉搜索树。两种递归解法都采用中序遍历策略:方法一总是选择中间位置左边的数字作为根节点(k=(l+r)/2),方法二则选择右边数字(k=(l+r+1)/2)。两种方法均通过分治思想递归构建左右子树,确保生成的BST保持平衡。代码实现上,方法二通过索引优化避免了数组拷贝,直接在原数组区间上操作。时间复杂度均为O(n),空间复杂度O(logn)。
2025-09-23 00:42:52
251
原创 Leetcode 994. 腐烂的橘子 多源 BFS
本文介绍LeetCode 994题"腐烂的橘子"的BFS解法。题目要求在m×n网格中,新鲜橘子(1)被腐烂橘子(2)感染,每分钟向四周扩散,求所有橘子腐烂所需时间或返回-1(若有橘子无法腐烂)。 算法采用多源BFS:1)统计初始腐烂橘子和新鲜橘子数量;2)使用队列进行层级遍历,每轮处理当前所有腐烂橘子,并向四周扩散;3)每扩散一轮时间加1,直到无法继续扩散。最后检查剩余新鲜橘子数量,若为0则返回总时间-1(最后一轮不需额外时间),否则返回-1。时间复杂度O(mn),空间复杂度O(mn)。
2025-09-18 16:29:00
244
原创 Leetcode 763. 划分字母区间 贪心
摘要 Leetcode 763题要求将字符串划分为尽可能多的片段,使每个字符仅出现在一个片段中。两种解法思路相似:第一种解法通过双指针遍历,每次找到当前字符的最后出现位置来扩展右边界;第二种解法优化了效率,先预处理记录每个字符的最后出现位置。当遍历到当前右边界时,切分片段并更新指针。时间复杂度从O(n^2)优化到O(n),空间复杂度O(1)。
2025-09-16 22:36:11
283
原创 Leetcode 169. 多数元素 哈希计数 / 排序 / 摩尔投票
本文介绍了三种在数组中找到多数元素(出现次数超过n/2)的算法:1)哈希计数法,通过统计元素频率找出众数;2)排序法,利用众数必在中点的特性;3)摩尔投票法,通过擂台赛思想以O(1)空间复杂度高效求解。三种方法分别体现了哈希统计、排序特性和巧妙计数的不同解题思路,其中摩尔投票法最优。
2025-09-15 11:27:53
151
原创 求最小公倍数(GCD)和最大公约数(LCM)——原理和代码
本文介绍了最大公约数(GCD)和最小公倍数(LCM)的计算方法。GCD采用欧几里得算法(辗转相除法),通过递归公式gcd(a,b)=gcd(b,a%b)实现,并处理了负数和零值情况。LCM则基于公式lcm(a,b)=|a*b|/gcd(a,b)计算。文中提供了C++实现代码,并通过测试案例验证了算法的正确性,包括正数、负数和零值输入的情况。
2025-09-14 16:45:20
194
原创 【AI知识点】模型训练优化之——混合精度训练
混合精度训练结合FP16和FP32的优势,通过前向传播使用FP16加速计算,反向传播后转换为FP32更新权重,配合梯度缩放防止数值下溢。这种方法在保持模型精度的同时,显著提升训练速度并减少显存占用,已成为现代深度学习训练的标配技术。
2025-09-11 21:46:10
615
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅