当前位置: 首页 > news >正文

【强化学习】#5 时序差分学习

主要参考学习资料:《强化学习(第2版)》[加]Richard S.Suttion [美]Andrew G.Barto 著

文章源文件:https://github.com/INKEM/Knowledge_Base

缩写说明

  • DP:动态规划
  • GPI:广义策略迭代
  • MC:蒙特卡洛
  • MDP:马尔可夫决策决策过程
  • TD:时序差分

概述

  • 时序差分是一种在状态的下一个时刻就能更新其价估计的无模型算法。
  • Sarsa是同轨策略下的时序差分控制方法。
  • Q学习是离轨策略下的时序差分控制方法。
  • 期望Sarsa综合并推广了Sarsa和Q学习,具有更优的表现。
  • 双学习思想用于解决最大化操作导致的最大化偏差问题。

目录

  • 时序差分预测
  • Sarsa
  • Q学习
  • 期望Sarsa
  • 最大化偏差与双学习

时序差分(TD)学习结合了蒙特卡洛方法和动态规划方法的思想。与蒙特卡洛方法一致,时序差分方法可以直接从与环境互动的经验中学习策略,而不需要构件关于环境动态特性的模型;与动态规划一致,时序差分方法无需等待交互的最终结果,而可以基于已得到的其他状态的估计值来更新当前状态的价值函数。

时序差分预测

我们先回顾一下,蒙特卡洛方法需要一直等到计算出一次访问后的回报之后(也就是到达该次访问所在幕的终点),再用这个回报作为 V ( S t ) V(S_t) V(St)的目标进行估计。一个适用于非平稳环境(参见多臂赌博机一章)的简单的每次访问型蒙特卡洛方法可以表示成

V ( S t ) ← V ( S t ) + α [ G t − V ( S t ) ] V(S_t)\leftarrow V(S_t)+\alpha[G_t-V(S_t)] V(St)V(St)+α[GtV(St)]

其中 α \alpha α是常量步长参数,该方法称为常量αMC。蒙特卡洛方法的估计是无偏的,因为

v π ( s ) = ˙ E π [ G t ∣ S t = s ] v_\pi(s)\dot=\mathbb E_\pi[G_t|S_t=s] vπ(s)=˙Eπ[GtSt=s]

而TD方法只需要等到一次访问的下一个时刻,就能用观察到的收益 R t + 1 R_{t+1} Rt+1和已有的估计值 V ( S t + 1 ) V(S_{t+1}) V(St+1)来进行一次更新

V ( S t ) ← V ( S t ) + α [ R t + 1 + γ V ( S t + 1 ) − V ( S t ) ] V(S_t)\leftarrow V(S_t)+\alpha[R_{t+1}+\gamma V(S_{t+1})-V(S_t)] V(St)V(St)+α[Rt+1+γV(St+1)V(St)]

这种方法被称为TD(0)或单步TD,它是在多步TD方法TD(λ)(将在后续章节讨论)的一个特例。TD方法的估计是有偏的,尽管

v π ( s ) = ˙ E π [ G t ∣ S t = s ] = E π [ R t + 1 + γ G t + 1 ∣ S t = s ] = E π [ R t + 1 + γ v π ( S t + 1 ) ∣ S t = s ] \begin{split} v_\pi(s)& \dot=\mathbb E_\pi[G_t|S_t=s]\\ &=\mathbb E_\pi[R_{t+1}+\gamma G_{t+1}|S_t=s]\\ &=\mathbb E_\pi[R_{t+1}+\gamma v_\pi(S_{t+1})|S_t=s] \end{split} vπ(s)=˙Eπ[GtSt=s]=Eπ[Rt+1+γGt+1St=s]=Eπ[Rt+1+γvπ(St+1)St=s]

而在估计中我们用于替代 v π ( S t + 1 ) v_\pi(S_{t+1}) vπ(St+1) V ( S t + 1 ) V(S_{t+1}) V(St+1)本身也是一个估计,因此存在偏差,但随着样本量的增加,TD方法会趋于无偏。

以下是使用TD(0)进行策略估计的算法伪代码:

在常量αMC和TD(0)中,我们都可以把 α \alpha α后的括号部分视为一种现有估计值与估计目标的误差,即蒙特卡洛误差 G t − V ( S t ) G_t-V(S_t) GtV(St),而TD误差

δ t = ˙ R t + 1 + γ V ( S t + 1 ) − V ( S t ) \delta_t\dot=R_{t+1}+\gamma V(S_{t+1})-V(S_t) δt=˙Rt+1+γV(St+1)V(St)

如果状态价值函数估计 V V V在遍历一幕的过程中不会更新(即蒙特卡洛方法采用的过程),则蒙特卡洛误差可以写为TD误差之和

G t − V ( S t ) = R t + 1 + γ G t + 1 − V ( S t ) + γ V ( S t + 1 ) − γ V ( S t + 1 ) = δ t + γ ( G t + 1 − V ( S t + 1 ) ) = δ t + γ δ t + 1 + γ 2 δ t + 2 + ⋯ + γ T − t − 1 δ T − 1 + γ T − t ( G T − V ( S T ) ) = δ t + γ δ t + 1 + γ 2 δ t + 2 + ⋯ + γ T − t − 1 δ T − 1 + γ T − t ( 0 − 0 ) = ∑ k = t T − 1 γ k − t δ k \begin{split} G_t-V(S_t)&=R_{t+1}+\gamma G_{t+1}-V(S_t)+\gamma V(S_{t+1})-\gamma V(S_{t+1})\\ &=\delta_t+\gamma(G_{t+1}-V(S_{t+1}))\\ &=\delta_t+\gamma\delta_{t+1}+\gamma^2\delta_{t+2}+\cdots+\gamma^{T-t-1}\delta_{T-1}+\gamma^{T-t}(G_T-V(S_T))\\ &=\delta_t+\gamma\delta_{t+1}+\gamma^2\delta_{t+2}+\cdots+\gamma^{T-t-1}\delta_{T-1}+\gamma^{T-t}(0-0)\\ &=\sum^{T-1}_{k=t}\gamma^{k-t}\delta_k \end{split} GtV(St)=Rt+1+γGt+1V(St)+γV(St+1)γV(St+1)=δt+γ(Gt+1V(St+1))=δt+γδt+1+γ2δt+2++γTt1δT1+γTt(GTV(ST))=δt+γδt+1+γ2δt+2++γTt1δT1+γTt(00)=k=tT1γktδk

而在TD(0)中, V V V在一次遍历中会不断更新,使这个等式并不准确。但在时间步长较小的情况下,该等式仍能近似成立,这种泛化在TD学习的理论和算法中很重要。

时序差分预测方法具有如下优势:

  • 相比DP方法,TD方法不需要一个描述收益和下一状态联合概率分布的模型。
  • 相比MC方法,TD方法的更新只需等到下一个时刻即可,这对于持续性任务和幕非常长的分幕式任务是很实用的。

同时,对于任何固定的策略 π \pi π,TD(0)都已被证明能够收敛到 v π v_\pi vπ。但是关于TD和MC哪种方法收敛得更快、数据利用更有效,这些仍未被严格证明。不过在实践中,TD方法在随机任务上通常比常量αMC方法收敛得更快。

Sarsa

现在,我们使用时序差分方法来解决控制问题。GPI模式下的时序差分方法仍然可以分为同轨策略和离轨策略,本节介绍一种同轨策略下的时序差分控制方法。

如蒙特卡洛方法一节中所讲,在没有环境模型的情况下,估计动作价值函数比估计状态价值函数更有效。我们只需将状态的价值替换为“状态-动作”二元组的价值就能得到对应的更新方法

Q ( S t , A t ) ← Q ( S t , A t ) + α [ R t + 1 + γ Q ( S t + 1 , A t + 1 ) − Q ( S t , A t ) ] Q(S_t,A_t)\leftarrow Q(S_t,A_t)+\alpha[R_{t+1}+\gamma Q(S_{t+1},A_{t+1})-Q(S_t,A_t)] Q(St,At)Q(St,At)+α[Rt+1+γQ(St+1,At+1)Q(St,At)]

每当从非终止状态的 S t S_t St进行一次状态转移之后,我们就进行一次更新。如果 S t + 1 S_{t+1} St+1为终止状态,则定义 Q ( S t , A t ) = 0 Q(S_t,A_t)=0 Q(St,At)=0。上述更新规则利用了五元组 ( S t , A t , R t + 1 , S t + 1 , A t + 1 ) (S_t,A_t,R_{t+1},S_{t+1},A_{t+1}) (St,At,Rt+1,St+1,At+1)的元素,因此被命名为Sarsa

同样地,为了保证试探性,我们可以用 ϵ \epsilon ϵ-软性策略和 ϵ \epsilon ϵ-贪心策略来进行策略改进,或者其他保证所有“状态-动作”二元组都能被访问到的方式,来使其最终收敛到最优策略。Sarsa算法的伪代码如下:

Q学习

Q学习是一种离轨策略下的时序差分控制,它直接以对最优动作价值函数 q ∗ q_* q的估计为目标

Q ( S t , A t ) ← Q ( S t , A t ) + α [ R t + 1 + γ max ⁡ a Q ( S t + 1 , a ) − Q ( S t , A t ) ] Q(S_t,A_t)\leftarrow Q(S_t,A_t)+\alpha[R_{t+1}+\gamma\underset a\max Q(S_{t+1},a)-Q(S_t,A_t)] Q(St,At)Q(St,At)+α[Rt+1+γamaxQ(St+1,a)Q(St,At)]

当该更新公式收敛时,有

Q ( S t , A t ) = R t + 1 + γ max ⁡ a Q ( S t + 1 , a ) Q(S_t,A_t)=R_{t+1}+\gamma\underset a\max Q(S_{t+1},a) Q(St,At)=Rt+1+γamaxQ(St+1,a)

而这正是贝尔曼最优方程的动作价值函数表示形式。因此Q学习可以视为无环境模型的价值迭代(参见动态规划一章),只是Q学习的价值函数需要通过行动策略与环境交互采样获得,而不是直接由环境动态特性计算得出。

需要注意的是,同轨策略和离轨策略仅仅针对需要采取策略与环境交互的方法,价值迭代既不是同轨策略也不是离轨策略。

Q学习的伪代码如下:

但是在一些高风险环境、要求策略包含一定随机性(例如非平稳问题)的情况下,Q学习可能表现得不如Sarsa。考虑一个带悬崖的网格世界问题,贴着悬崖走能以最短路径到达终点,但也靠近危险,远离悬崖需要绕路,但更安全。在走到悬崖边的一个格子时,对Q学习来说,它会通过贪心直接选择出下一个贴着悬崖的格子,因而能很快收敛到最短但靠近危险路径;对Sarsa学习来说,它的软性策略还会随机采样下一个动作,这使得其有一定几率掉下悬崖受到惩罚,因而会逐渐收敛到一个绕路但安全的路径。此时如果分别基于Q学习和Sarsa收敛的价值估计采用同样的 ϵ \epsilon ϵ-贪心策略,则Sarsa会因为不易掉下悬崖而表现得更好。

期望Sarsa

期望Sarsa是一种介于Sarsa和Q学习之间的算法,它采用如下更新公式

Q ( S t , A t ) ← Q ( S t , A t ) + α [ R t + 1 + γ E [ Q ( S t + 1 , A t + 1 ) ∣ S t + 1 ] − Q ( S t , A t ) ] ← Q ( S t , A t ) + α [ R t + 1 + γ ∑ a π ( a ∣ S t + 1 ) Q ( S t + 1 , A t + 1 ) − Q ( S t , A t ) ] \begin{split} Q(S_t,A_t)&\leftarrow Q(S_t,A_t)+\alpha[R_{t+1}+\gamma\mathbb E[Q(S_{t+1},A_{t+1})|S_{t+1}]-Q(S_t,A_t)]\\ &\leftarrow Q(S_t,A_t)+\alpha[R_{t+1}+\gamma\sum_a\pi(a|S_{t+1})Q(S_{t+1},A_{t+1})-Q(S_t,A_t)] \end{split} Q(St,At)Q(St,At)+α[Rt+1+γE[Q(St+1,At+1)St+1]Q(St,At)]Q(St,At)+α[Rt+1+γaπ(aSt+1)Q(St+1,At+1)Q(St,At)]

在Sarsa的基础上,期望Sarsa通过期望消除了使用随机选择的 A t + 1 A_{t+1} At+1更新 Q ( S t , A t ) Q(S_t,A_t) Q(St,At)带来的方差,在相同数量的经验下,它表现得比Sarsa更好。而相较于Q学习,它又不那么激进,会更综合地考虑下一个状态的价值,更加适用于高风险环境。

期望Sarsa既可以是同轨策略也可以是离轨策略,这取决于其用于采样估计 Q Q Q的策略 π ′ \pi' π是否不同于用于计算期望的策略 π \pi π。在离轨策略下,如果 π \pi π是贪心策略,则期望Sarsa就是Q学习,因此其可以视为Q学习的推广。

最大化偏差与双学习

由于最优策略的贪心性质,我们目前讨论的所有控制算法在构建目标策略时都包含了最大化操作。但考虑一种情况,在状态 s s s下,所有动作的真实价值 q ( s , a ) q(s,a) q(s,a)全为零,但它们的估计值 Q ( s , a ) Q(s,a) Q(s,a)是不确定的,可能有些大于零,有些小于零。此时我们如果对估计值采用最大化操作,反而产生了最大的正偏差,我们将其称为最大化偏差

避免最大化偏差的一个方法是双学习。既然估计值 Q Q Q可能高估也可能低估,那么如果采用两组独立更新的估计 Q 1 Q_1 Q1 Q 2 Q_2 Q2,从期望上来看,二者的误差会相互抵消。

双学习的关键在于解耦了选择和评估动作的过程,在更新 Q 1 Q_1 Q1时,我们仍基于 Q 1 Q_1 Q1选择贪心动作,但是不会使用 Q 1 Q_1 Q1作为其更新基准,而是让 Q 2 Q_2 Q2重新给出对这一动作的评估。这相当于在复习时,自己抽查自己往往检验不出薄弱的地方,而两个人相互抽查则更容易发现对方的漏洞。

双学习的思想可以推广到为完备MDP设计的算法中,在Q学习中的推广则被称为双Q学习。双Q学习在每次状态转移随机对 Q 1 Q_1 Q1 Q 2 Q_2 Q2进行更新,其中 Q 1 Q_1 Q1的更新公式如下

Q 1 ( S t , A t ) ← Q 1 ( S t , A t ) + α [ R t + 1 + γ Q 2 ( S t + 1 , a r g m a x a Q 1 ( S t + 1 , a ) ) − Q 1 ( S t , A t ) ] Q_1(S_t,A_t)\leftarrow Q_1(S_t,A_t)+\alpha[R_{t+1}+\gamma Q_2(S_{t+1},\underset a{\mathrm{argmax}}Q_1(S_{t+1},a))-Q_1(S_t,A_t)] Q1(St,At)Q1(St,At)+α[Rt+1+γQ2(St+1,aargmaxQ1(St+1,a))Q1(St,At)]

Q 2 Q_2 Q2的更新只需将上式二者的地位互换即可。

Q Q Q学习的伪代码如下:

相关文章:

【强化学习】#5 时序差分学习

主要参考学习资料:《强化学习(第2版)》[加]Richard S.Suttion [美]Andrew G.Barto 著 文章源文件:https://github.com/INKEM/Knowledge_Base 缩写说明 DP:动态规划GPI:广义策略迭代MC:蒙特卡洛…...

Day119 | 灵神 | 二叉树 | 二叉树的最近共公共祖先

Day119 | 灵神 | 二叉树 | 二叉树的最近共公共祖先 236.二叉树的最近共公共祖先 236. 二叉树的最近公共祖先 - 力扣(LeetCode) 思路: 二叉树的最近公共祖先【基础算法精讲 12】_哔哩哔哩_bilibili 首先我们采用后序遍历 递归函数返回值…...

Elasticsearch 性能优化面试宝典

Elasticsearch 性能优化面试宝典 🚀 目录 设计调优 🏗️写入调优 ⚡查询调优 🔍综合设计 💎总结 📝设计调优 🏗️ 面试题1:索引设计优化 题目: 假设需要设计一个电商商品索引,日增数据量1TB,要求支持多维度查询(名称、分类、价格区间)。请说明索引设计的关…...

mysql数据库-中间件MyCat

1. MyCat简介 在整个 IT 系统架构中,数据库是非常重要,通常又是访问压力较大的一个服务,除了在程序开发的本身做优化,如: SQL 语句优化、代码优化,数据库的处理本身优化也是非常重要的。主从、热备、分表分…...

制作大风车动画

这个案例的风车旋转应用了图形变换来实现,速度和缩放比例应用slider来实现,其中图片的速度,图片大小的信息通过State来定义变量管理,速度和和缩放比例的即时的值通过Prop来管理。 1. 案例效果截图 2. 案例运用到的知识点 2.1. 核…...

嘉立创EDA成图:文件管理

在 工程 文 件夹 中 新建 一 个以 自 己选 手 编号 后 8 位 命名 的 项目 工 程文 件 按要求名字命名(这里以日期命名) 选择半离线或者全离线 添加路径 1. 新建 图 纸文 件 ,文 件 名为 moban.elibz; 点击保存之后打开文件夹有这…...

Vim编辑器命令模式操作指南

Vim 的命令模式(即 Normal 模式)是 Vim 的核心操作模式,用于执行文本编辑、导航、搜索、保存等操作。以下是命令模式下的常用操作总结: 1. 模式切换 进入命令模式:在任何模式下按 Esc 键(可能需要多次按&a…...

jvm安全点(一)openjdk17 c++源码垃圾回收安全点信号函数处理线程阻塞

1. 信号处理入口​​ ​​JVM_HANDLE_XXX_SIGNAL​​ 是 JVM 处理信号的统一入口,负责处理 SIGSEGV、SIGBUS 等信号。​​javaSignalHandler​​ 是实际注册到操作系统的信号处理函数,直接调用 JVM_HANDLE_XXX_SIGNAL。 ​​2. 安全点轮询页的识别​​ …...

手机打电话时由对方DTMF响应切换多级IVR语音应答(二)

手机打电话时由对方DTMF响应切换多级IVR语音应答(二) --本地AI电话机器人 一、前言 前面的篇章《手机打电话时由对方DTMF响应切换多级IVR语音应答(一)》中,我们从理论的角度论述了“根据对方按下DTMF值响应多级IVR”…...

【Java ee初阶】HTTP(2)

一、HTTP的方法 方法 说明 支持的HTTP协议版本 GET 获取资源 1.0、1.1 POST 传输实体主体 1.0、1.1 PUT 传输文件 1.0、1.1 HEAD 获得报文首部 1.0、1.1 DELETE 删除文件 1.0、1.1 OPTIONS 询问支持的方法 1.1 TRACE 追踪路径 1.1 CONNECT 要求用隧道…...

计算机视觉与深度学习 | Python实现EMD-SSA-VMD-LSTM-Attention时间序列预测(完整源码和数据)

EMD-SSA-VMD-LSTM-Attention 一、完整代码实现二、代码结构解析三、关键数学公式四、参数调优建议五、性能优化方向六、工业部署建议 以下是用Python实现EMD-SSA-VMD-LSTM-Attention时间序列预测的完整解决方案。该方案结合了四层信号分解技术与注意力增强的深度学习模型&#…...

Java 应用如何实现 HTTPS:加密数据传输的实用指南

Java 应用如何实现 HTTPS:加密数据传输的实用指南 在当今的互联网环境中,数据安全至关重要,HTTPS 作为加密的数据传输协议,为 Java 应用提供了安全通信的保障。本文将深入探讨 Java 应用如何实现 HTTPS,通过详细代码实…...

手机打电话时如何将通话对方的声音在手机上识别成文字

手机打电话时如何将通话对方的声音在手机上识别成文字 --本地AI电话机器人 上一篇:手机打电话时由对方DTMF响应切换多级IVR语音应答(一) 下一篇:手机打电话时由对方DTMF响应切换多级IVR语音应答(二) 一、…...

18.自动化生成知识图谱的多维度质量评估方法论

文章目录 一、结构维度评估1.1 拓扑结构评估1.1.1 基础图论指标1.1.2 层级结构指标 1.2 逻辑一致性评估1.2.1 形式逻辑验证1.2.2 约束满足度 二、语义维度评估2.1 语义一致性评估2.1.1 标签语义分析2.1.2 关系语义评估 2.2 语义表示质量2.2.1 嵌入质量2.2.2 上下文语义评估 三、…...

W5500使用ioLibrary库创建TCP客户端

1、WIZnet全硬件TCP/IP协议栈 WIZnet全硬件TCP/IP协议栈,支持TCP,UDP,IPv4,ICMP,ARP,IGMP以及PPPoE协议。 以太网:支持BSD和WIZCHIP(W5500/W5300/W5200/W5100/W5100S)的SOCKET APIs驱动程序。 互联网: DHCP客户端 DNS客户端 FTP客…...

2025B难题练习

1.启动多任务排序 拓扑排序 每次选入度为0的点 对每次选的点进行排序 package mainimport ("bufio""fmt""os""slices""strings" )func main() {scanner : bufio.NewScanner(os.Stdin)scanner.Scan()text : scanner.Text()…...

20250517让NanoPi NEO core开发板在Ubuntu core16.04.2下支持TF卡的热插拔

20250517让NanoPi NEO core开发板在Ubuntu core16.04.2下支持TF卡的热插拔 2025/5/17 17:52 缘起:实测NanoPi NEO core开发板上电之后,后插入的TF卡不认/不支持热插拔。 Ubuntu core16.04.2 Ubuntu core20.04 Ubuntu core16.04.3 用NanoPi NEO core开发板…...

Vue百日学习计划Day19-20天详细计划-Gemini版

重要提示: 番茄时钟: 每个番茄钟为25分钟学习,之后休息5分钟。每完成4个番茄钟,进行一次15-30分钟的长休息。动手实践: DevTools 的使用和 Git 命令的掌握都需要大量的实际操作。请务必边学边练。环境准备&#xff1a…...

Uniapp、Flutter 和 React Native 全面对比

文章目录 前言Uni-app、Flutter 和 React Native 跨平台框架对比报告1. 性能对比2. 跨平台能力3. 学习曲线4. 社区生态与第三方库5. 原生能力扩展6. UI 渲染能力7. 企业支持与典型使用场景8. 开发效率与工具链 前言 将对 Uniapp、Flutter 和 React Native 进行全面对比&#x…...

【Linux笔记】——线程互斥与互斥锁的封装

🔥个人主页🔥:孤寂大仙V 🌈收录专栏🌈:Linux 🌹往期回顾🌹:【Linux笔记】——Linux线程封装 🔖流水不争,争的是滔滔不息 一、线程互斥的概念二、互…...

Linux面试题集合(4)

现有压缩文件:a.tar.gz存在于etc目录,如何解压到data目录 tar -zxvf /etc/a.tar.gz -C /data 给admin.txt创建一个软链接 ln -s admin.txt adminl 查找etc目录下以vilinux开头的文件 find /etc -name vilinux* 查找admin目录下以test开头的文件 find admin -name te…...

Java二叉树题目练习

Java二叉题目练习 相同的树对称二叉树平衡二叉树二叉树的最近公共祖先二叉树的层序遍历二叉树层序遍历 ||二叉树遍历 相同的树 二叉树的题目大多数时候就可以采用递归的方法写 因为二叉树是由根左子树和右子树组成,每一棵左子树和右子树又可以被看成一颗完整的树&am…...

WORD个人简历单页326款模版分享下载

WORD个人简历模版下载:WORD个人简历模版https://pan.quark.cn/s/7e79a822c490...

Linux容器技术详解

容器技术基础 什么是容器 容器是一种轻量级的虚拟化技术,它将应用程序及其依赖(库、二进制文件、配置文件等)打包在一个独立的单元中,可以在任何支持容器运行时的环境中一致地运行。 Docker官网:https://www.docker…...

显卡、Cuda和pytorch兼容问题

这里写目录标题 驱动与CUDA版本兼容性问题1. **驱动与CUDA版本兼容性问题**2. **任务特性与硬件适配差异**3. **优化策略与框架配置差异**4. **散热与功耗限制**5. **数据传输与CPU瓶颈**排查建议总结 查询PyTorch中实际使用的CUDA版本**1. 查询PyTorch中实际使用的CUDA版本***…...

仅需三张照片即可生成沉浸式3D购物体验?谷歌电商3D方案全解析

随着消费者对线上购物体验的要求不断提高,传统2D图片已难以满足用户“真实感知商品”的需求。尤其在鞋类、家具、服装等高决策成本的商品上,缺乏空间感和交互性的购物方式成为转化率瓶颈。 谷歌敏锐地捕捉到这一趋势,早在2022年起便开始探索通过生成式AI技术实现“低成本、…...

PIC16F877A LCD1602 DHT11 温湿度读取显示代码 MPLAB

#include <xc.h> #include <stdio.h> #include <stdlib.h> #...

PIC16F18877 的主时钟 设置方法

#include <xc.h>// ========== 配置位设置 ========== // #pragma config FEXTOSC = OFF // 使用内部振荡器 #pragma...

西门子 Teamcenter13 Eclipse RCP 开发 1.3 工具栏 单选按钮

西门子 Teamcenter13 Eclipse RCP 开发 1.3 工具栏 单选按钮 1 配置文件2 插件控制3 命令框架 位置locationURI备注菜单栏menu:org.eclipse.ui.main.menu添加到传统菜单工具栏toolbar:org.eclipse.ui.main.toolbar添加到工具栏 style 值含义显示效果push普通按钮&#xff08;默…...

asp.net core api RESTful 风格控制器

在 ASP.NET Core API 中&#xff0c;遵循 RESTful 风格的控制器一般具备以下几个关键特征&#xff1a; ✅ RESTful 风格控制器的命名规范 控制器命名 使用 复数名词&#xff0c;表示资源集合&#xff0c;如 ProductsController、UsersController。 路由风格 路由使用 [Rout…...

智能合约调用全景实战:前端 JS 与后端 Java 两种方式全面解析

目录 前言前端调用以太坊合约新建一个智能合约将合约部署到Hardhat本地链前端(HTML + JavaScript)调用合约后端调用以太坊合约生成java类调用智能合约(maven 插件方式)不生成Java类,通过合约ABI直接调用智能合约前后端调用方式对比开发建议结语前言 随着 Web3 的兴起,越…...

Javascript:WebAPI

获取网页元素 queryselector queryselector是 JavaScript 中用于选择 DOM 元素的重要方法&#xff0c;它允许使用 CSS 选择器语法来查找页面中的元素。 一般queryselector获取的元素都是html中第一个选择器的元素 支持选择器类型&#xff1a;类选择器(.class) &#xff0c…...

(4)python爬虫--JsonPath

文章目录 前言一、安装JsonPath库第一步&#xff1a; 打开pycharm第二步: 安装jsonpath 二、 jsonpath的基本使用2.1 基础语法2.2 语法测试2.2.1 准备json文件(store.json)2.2.2 jsonpath解析json语法 三、实战练习需求:爬取淘票票上所有的城市3.1 下载城市json文件3.2 解析城市…...

CentOS 上配置 Docker 使用 NVIDIA GPU

CentOS 上配置 Docker 使用 NVIDIA GPU&#xff08;前提是已安装 NVIDIA 驱动&#xff09;&#xff1a; 在 CentOS 上配置 Docker 使用 NVIDIA GPU 本文介绍如何在已安装 NVIDIA 驱动的 CentOS 系统中&#xff0c;配置 Docker 使用 GPU 资源进行加速。 ✅ 前提条件 已安装 Cent…...

JAVA Spring MVC+Mybatis Spring MVC的工作流程*

目录 注解总结 将传送到客户端的数据转成json数据 **描述一下Spring MVC的工作流程** 1。属性赋值 BeanUtils.copyProperties(addUserDTO,user); 添加依赖&#xff1a; spring web、mybatis framework、mysql driver Controller和ResponseBody优化 直接改成RestControl…...

【人工智能】DeepSeek解码:揭秘AI大模型训练的创新密码

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 DeepSeek作为开源AI领域的先锋,以其高效、低成本的大模型训练技术震撼业界。本文深入剖析DeepSeek-V3和R1模型的训练密码,聚焦其创新的混…...

Java 方法向 Redis 里操作字符串有什么需要注意的?​

在 Java 开发中&#xff0c;Redis 作为高性能的键值存储数据库&#xff0c;常被用于缓存数据、处理高并发场景等。当我们使用 Java 方法向 Redis 中操作字符串类型数据时&#xff0c;有许多关键要点需要格外注意。这些要点不仅关系到代码的正确性和性能&#xff0c;还影响着整个…...

C#与KepOPC通讯

使用C#连接KepOPC服务器进行数据读写的基础示例 using System; using Opc; using System.Threading;namespace KepOPCDemo {class Program{static void Main(string[] args){// OPC服务器连接参数string serverName "Kepware.KEPServerEX.V6"; // 根据实际安装的服…...

【软件测试】性能测试 —— 工具篇 LoadRunner 介绍与使用

&#x1f970;&#x1f970;&#x1f970;来都来了&#xff0c;不妨点个关注叭&#xff01; &#x1f449;博客主页&#xff1a;欢迎各位大佬!&#x1f448; 文章目录 1. LoadRunner 是什么&#xff1f;2. LoadRunner 安装前提&#xff1a;浏览器的选择 —— IE / 360极速浏览器…...

Linux面试题集合(6)

创建多级目录或者同级目录 mkdir -p 文件名/文件名/文件名 mkdir -p 文件名 文件名 文件名 Linux创建一个文件 touch 文件名 DOS命令创建文件 echo 内容>文件名&#xff08;创建一个有内容的文件&#xff09; echo >文件名&#xff08;创建一个没有内容的文件&#xff09…...

技术测评:小型单文件加密工具的功能解析

最近在测试一款名为OEMexe的文件加密工具&#xff0c;发现它确实有一些独特之处值得分享。这款软件体积非常小巧&#xff0c;仅209KB&#xff0c;属于绿色单文件版程序&#xff0c;无需安装即可直接运行。 主要特点 多格式支持&#xff1a;能够处理多种常见文件格式&#xff0…...

06、基础入门-SpringBoot-依赖管理特性

06、基础入门-SpringBoot-依赖管理特性 Spring Boot 的依赖管理特性是其核心优势之一&#xff0c;极大地简化了项目的构建和维护过程。以下是其主要特点&#xff1a; ## 1. 父项目依赖管理 ### 1.1 继承 spring-boot-starter-parent 在 pom.xml 文件中&#xff0c;通过继承 spr…...

基于 Python 的界面程序复现:标准干涉槽型设计计算及仿真

基于 Python 的界面程序复现&#xff1a;标准干涉槽型设计计算及仿真 在工业设计与制造领域&#xff0c;刀具的设计与优化是提高生产效率和产品质量的关键环节之一。本文将介绍如何使用 Python 复现一个用于标准干涉槽型设计计算及仿真的界面程序&#xff0c;旨在帮助工程师和…...

我的创作纪念日——《惊变256天》

我的创作纪念日——《惊变256天》 机缘收获日常成就憧憬 最近&#xff0c;博主收到了 CSDN 发来的系统消息&#xff0c;这才惊觉&#xff0c;自上次第128天创作纪念日之后&#xff0c;竟又悄然走过了 128 天。站在 256 天这个颇具意义的里程碑前回望&#xff0c;博主在2023 年 …...

Linux 的 UDP 网络编程 -- 回显服务器,翻译服务器

目录 1. 回显服务器 -- echo server 1.1 相关函数介绍 1.1.1 socket() 1.1.2 bind() 1.1.3 recvfrom() 1.1.4 sendto() 1.1.5 inet_ntoa() 1.1.6 inet_addr() 1.2 Udp 服务端的封装 -- UdpServer.hpp 1.3 服务端代码 -- UdpServer.cc 1.4 客户端代码 -- UdpClient.…...

回溯法理论基础 LeetCode 77. 组合 LeetCode 216.组合总和III LeetCode 17.电话号码的字母组合

目录 回溯法理论基础 回溯法 回溯法的效率 用回溯法解决的问题 如何理解回溯法 回溯法模板 LeetCode 77. 组合 回溯算法的剪枝操作 LeetCode 216.组合总和III LeetCode 17.电话号码的字母组合 回溯法理论基础 回溯法 回溯法也可以叫做回溯搜索法&#xff0c;它是一…...

LeetCode --- 156双周赛

题目列表 3541. 找到频率最高的元音和辅音 3542. 将所有元素变为 0 的最少操作次数 3543. K 条边路径的最大边权和 3544. 子树反转和 一、找到频率最高的元音和辅音 分别统计元音和辅音的出现次数最大值&#xff0c;然后相加即可&#xff0c;代码如下 // C class Solution {…...

第五项修炼:打造学习型组织

最近一直接到的需求&#xff0c;都是公司董事长或总经理都特别推崇《第五项修炼&#xff1a;打造学习型组织》的内容&#xff0c;让各个层级的管理者都持续学习、应用、实践。我不禁开始反思&#xff0c;这背后到底隐藏着什么原因&#xff1f; 随着商业环境的变化和复杂性的增加…...

Bellman - Ford 算法与 SPFA 算法求解最短路径问题 ——从零开始的图论讲解(4)

目录 前言 为什么Dijkstra算法面对负权值图会有误差??? 举例说明 什么是Bellman -Ford算法? BF算法的核心思想 什么是松弛 为什么最多松弛N-1次? 代码实现 举例 初始状态&#xff08;dist[] 数组&#xff09; 第 1 轮松弛&#xff08;遍历所有边&#xff09; …...

Python训练营打卡 Day27

函数专题2&#xff1a;装饰器 知识点回顾&#xff1a; 装饰器的思想&#xff1a;进一步复用函数的装饰器写法注意内部函数的返回值 昨天我们接触到了函数大部分的功能&#xff0c;然后在你日常ctrl点进某个复杂的项目&#xff0c;发现函数上方有一个xxx,它就是装饰器 装饰器本质…...