【强化学习的数学原理】第05课-蒙特卡洛方法-笔记
学习资料:bilibili 西湖大学赵世钰老师的【强化学习的数学原理】课程。链接:强化学习的数学原理 西湖大学 赵世钰
文章目录
- 一、通过例子介绍蒙特卡洛
- 二、 MC Basic 算法介绍
- 三、MC Basic 算法例子
- 例1:MC Baxic算法
- 例2:episode length对算法的影响
- 四、MC Exploring Starts 算法
- 五、MC Epsilon-Greedy 算法介绍
- 六、MC Epsilon-Greedy 算法例子
- 七、本节课summary
一、通过例子介绍蒙特卡洛
之前提到的值迭代算法、策略迭代算法都属于model-based reinforcement learning,而蒙特卡洛方法属于model-free reinforcement learning。对于初学者来说,最难以理解的是,如何在没有模型的情况下去估计一些变量。其中有一个重要的思想就是 Monte Carlo Estimation。下面举一个例子来简要介绍 Monte Carlo Estimation。
这是一个抛硬币的例子。若正面朝上,则X=1;若反面朝上,则X=-1,目标是计算期望 E(X)。
方法一是利用 model-based 的方法来解决该问题,列出概率分布模型,然后根据模型计算期望。不过,对于现实中的大部分问题,我们无法直接这样列出概率分布模型。
`
方法二是利用 model-free 的方法,其基本思想是多次投掷硬币,采样很多次,然后对所有的采样结果求平均。用这个平均数来近似期望。
那么,这种蒙特卡洛估计是准确的吗?当采样次数N比较小的时候,该估计是不准确的;当N逐渐变大,估计变得越来越准确。(有大数定律作为理论支撑)
通过上述例子,我们可以了解蒙特卡洛的基本思想。如下图所示:
二、 MC Basic 算法介绍
MC Basic 算法是基于policy iteration策略迭代算法的,但策略迭代算法是mode-based reinforcement learning,MC Basic 算法是 model-free reinforcement learning。理解MC Basic 算法的关键是,理解如何把mode-based reinforcement learning转换成 model-free reinforcement learning。
下图简要回顾了以下 policy iteration 算法。分为policy evaluation 和 policy improvement 两部分。在 policy evaluation 中根据给定的策略计算state value,在 policy improvement 中根据刚刚算好的 state value 来更新策略,在这一步中,最重要的就是计算 q π k ( s , a ) q_{\pi_k}(s,a) qπk(s,a),根据算出来的结果来选择动作 a a a 。
有两种方法来计算 q π k ( s , a ) q_{\pi_k}(s,a) qπk(s,a)。
第一种是基于模型的方法,根据公式来计算。(如下图 expression 1 所示)
第二种是不需要模型的方法,回到了 q π k ( s , a ) q_{\pi_k}(s,a) qπk(s,a) 最原始的定义。从状态s出发,采取动作a,得到一个return,多次采样取平均值,用平均值来近似 q π k ( s , a ) q_{\pi_k}(s,a) qπk(s,a) 。
下面将详细讲解如何使用蒙特卡洛估计来计算 q π k ( s , a ) q_{\pi_k}(s,a) qπk(s,a) 。从状态s出发,采取动作a,产生一个episode,得到一个return g ( s , a ) g(s,a) g(s,a)。多次进行采样,就会得到一个集合 g ( j ) ( s , a ) {g^{(j)}(s,a)} g(j)(s,a) ,对集合中的所有奖励取平均值,用平均值来近似 q π k ( s , a ) q_{\pi_k}(s,a) qπk(s,a)。总的来说,当没有模型的时候,可以依赖于数据(data/sample/experience)来模拟模型。
下面是 MC Basic 算法的具体描述。该算法和 policy iteration 算法几乎一致,唯一的区别就是 policy iteration 算法用基于模型的方法来计算 q π k ( s , a ) q_{\pi_k}(s,a) qπk(s,a) ,而 MC Basic 算法用蒙特卡洛估计来计算 q π k ( s , a ) q_{\pi_k}(s,a) qπk(s,a) 。
下面是该算法的伪代码。
Highlights:
(1)MC Basic 是 policy iteration 的一个变形。
(2)MC Basic 算法虽然展示了 MC-based model-free RL 的核心,但是该算法的效率非常低。
(3)为什么MC Basic 算法估计的是 action value,而不是 state value 呢?因为 state value 是不能用来提升策略的,所以我们必须要计算 action value。那如果先估计 state value ,再由 state value 算出 action value 行不行呢?实际上也是不行的,因为由 state value 算出 action value 需要依赖下面这个公式,而下面这个公式又是一个 model based 的公式。
(4)因为policy iteration是收敛的,而 MC Basic 和 policy iteration 是几乎一致的,所以 MC Basic 也是收敛的。
三、MC Basic 算法例子
例1:MC Baxic算法
下面通过一个具体的例子来阐述MC Baxic算法。在这个例子中,有一个初始策略 π 0 \pi_0 π0 , 这个策略在大多数状态下都是正确的,但是在状态 s 1 s_1 s1 和状态 s 3 s_3 s3 时的策略不太好,下面对这两个状态的策略进行优化。
MC Basic 算法和policy iteration一样,分为policy evaluation和policy improvement两步。在policy evaluation中,需要求 q π k ( s , a ) q_{\pi_k}(s,a) qπk(s,a),也就是说要从每个状态动作对(s,a)出发,找到每一个(s,a)的 q π k ( s , a ) q_{\pi_k}(s,a) qπk(s,a)。在这个例子里,有 9 state × 5 action = 45 个状态动作对。假设从每一个(s,a)出发都要有n条轨迹,那一共有 45×n 条轨迹。
以状态动作对 ( s 1 , a ) (s_1,a) (s1,a) 为例。首先做policy evaluation。这个grid world中,policy 和环境都是deterministic的,所以对 ( s 1 , a ) (s_1,a) (s1,a) 采样n条轨迹,得到的轨迹都是一样的,因此只要采样一条轨迹就好了。
从 s 1 s_1 s1 出发, 采取动作 a 1 a_1 a1,回到状态 s 1 s_1 s1 ,又采取动作 a 1 a_1 a1……如此循环往复,生成了一条关于状态动作对 ( s 1 , a 1 ) (s_1,a_1) (s1,a1) 的轨迹。 随后求出这条轨迹对应的return。其他状态动作对的return求法也类似。
policy evaluation 之后,需要进行 policy improvement。方法和之前类似,对一个状态s,找出 q π k ( s , a ) q_{\pi_k}(s,a) qπk(s,a) 中最大的那个作为新的策略即可。 policy improvement 后可以发现,此时 s 1 s_1 s1 的策略已经达到最优了。
例2:episode length对算法的影响
episode length 肯定不可能无限大,但 episode length 设置为多少比较合适呢?
当episode length=1时,只有紧挨着target area的几个格子的value是正数,其对应的策略也是正确的。其他格子的value都是0,策略也不好。
当episode length=2时,第五行第二个格子、第四个格子对应的策略也都变成了正确的。因为从这两个格子出发, 刚好走两步可以到达目标。
当episode length=3时,对于恰好走三步能够到达目标的格子,其策略也变成了最优的。
当episode length=n时,对于恰好走n步能够到达目标的格子,其策略也变成了最优的。
当episode length=15时,对于恰好走15步能够到达目标的格子,其策略也变成了最优的。此时所有的格子的策略都变成了最优的。
当继续增加episode length时,策略已经基本上不会怎么变化了,变化的主要是state value。当episode length 变为无穷大的时候,state value基本上和optimal state value接近了。
Findings:
(1)当episode length比较短的时候,只有离目标近的状态才能在短的步骤内找到正确的策略。
(2)当episode length不断增加时,离目标越来越远的状态也慢慢地达到了正确策略。
(3)episode length必须要足够长,但也不必是无限长。
四、MC Exploring Starts 算法
之前讲的 MC Basic 算法的缺陷就是效率比较低。MC Exploring Starts 是对 MC Basic 的改进。
先介绍一个概念 visit,visit 在一个episode中出现的一个状态-动作对,如下图episode中的 ( s 1 , a 2 ) (s_1,a_2) (s1,a2), ( s 2 , a 4 ) (s_2,a_4) (s2,a4), ( s 1 , a 2 ) (s_1,a_2) (s1,a2), ( s 2 , a 3 ) (s_2,a_3) (s2,a3) 等等。在 MCB 中,使用的是 Initial-visit method。意思是,对于下面这个episode,只考虑 ( s 1 , a 2 ) (s_1,a_2) (s1,a2),然后用剩下的return,来估计 ( s 1 , a 2 ) (s_1,a_2) (s1,a2) 的action value。
但是按照上面的计算方法也会存在问题,就是这个episode的价值没有被充分利用。这个episode除了访问 ( s 1 , a 2 ) (s_1,a_2) (s1,a2),还访问了 ( s 2 , a 4 ) (s_2,a_4) (s2,a4), ( s 1 , a 2 ) (s_1,a_2) (s1,a2), ( s 2 , a 3 ) (s_2,a_3) (s2,a3) 等等。其实也可以把这个episode从 ( s 2 , a 4 ) (s_2,a_4) (s2,a4)开始,当做一个新的episode,估计 ( s 2 , a 4 ) (s_2,a_4) (s2,a4)的return。下一个 ( s 1 , a 2 ) (s_1,a_2) (s1,a2)开头的episode可以用来估计 ( s 1 , a 2 ) (s_1,a_2) (s1,a2)的return。下一个 ( s 2 , a 3 ) (s_2,a_3) (s2,a3)开头的episode可以用来估计 ( s 2 , a 3 ) (s_2,a_3) (s2,a3)的return。这样就可以把有限的数据利用得非常充分。
这里面包括两种方法:first-visit 和 every-visit。在下图中的original episode中,第一次访问了 ( s 1 , a 2 ) (s_1,a_2) (s1,a2),第三次还访问了 ( s 1 , a 2 ) (s_1,a_2) (s1,a2)。对于every-visit策略,在第一次访问 ( s 1 , a 2 ) (s_1,a_2) (s1,a2) 时,用第一次访问的 ( s 1 , a 2 ) (s_1,a_2) (s1,a2) 来估计其return,在第二次访问 ( s 1 , a 2 ) (s_1,a_2) (s1,a2)时,会用第二次访问的 ( s 1 , a 2 ) (s_1,a_2) (s1,a2) 来再一次估计 ( s 1 , a 2 ) (s_1,a_2) (s1,a2) 的return。但是对于first-visit策略,只是用第一次出现的 ( s 1 , a 2 ) (s_1,a_2) (s1,a2) 来估计其 return,后面再出现 ( s 1 , a 2 ) (s_1,a_2) (s1,a2) 时就不再进行估计了。
另一个要考虑的方面是:何时更新策略
。有两种方法。
第一种方法:在策略评估过程中,从状态-动作对出发,收集完所有的episode,计算其均值,再用来更新策略。这正是MC Basic方法所使用的策略。该策略的问题时,agent需要等很长时间,直到所有的episode都被收集完毕后再更新策略。
第二种方法:在策略评估过程中,从状态-动作对出发,只收集一个episode,立刻就估计action value,随即进行策略更新。这样会提升效率。
但是,第二种方法每次只收集一个episode,会不会导致结果不准确呢?答案是不会。试想policy iteration策略和value iteration策略的差异,policy iteration需要经过无穷多次迭代,而value iteration每次仅需进行一次迭代即可,两种方法最终都能得到准确的结果。
Generalized policy iteration: Generalized policy iteration是一种架构,不是一种具体的算法。It refers to the general idea or framework of switching between policy-evaluation and policy-improvement processes.
下图是 MC Exploring Starts 的伪代码。主要分成两部分: Episode generation 和 Policy evaluation 、policy improvement。
在 episode generation 阶段,生成一个 episode T : s 0 , a 0 , r 1 , . . . , s T − 1 , a T − 1 , r T T: s_0, a_0, r_1,..., s_{T-1}, a_{T-1}, r_{T} T:s0,a0,r1,...,sT−1,aT−1,rT。然后在policy evaluation 和policy improvement 阶段,把episode 倒过来(这样计算效率更高),逐一计算状态-动作对的return。
为什么要exploring starts 这个条件呢?
exploring:从每一个 ( s , a ) (s,a) (s,a) 出发,都要有一个episode,这样才能生成return,计算 q ( s , a ) q(s,a) q(s,a)。如果恰好有一个状态-动作对没有被访问到,那可能就会漏掉这个action,但这个action也有可能是最优的。所以说要确保每一个 ( s , a ) (s,a) (s,a) 都要被访问到。
starts:要访问每一个 ( s , a ) (s,a) (s,a) ,生成return这些数据,有两种方法。第一种是从 ( s , a ) (s,a) (s,a) 出发构建一个episode;第二种是从其他的状态-动作对开始,经过这个 ( s , a ) (s,a) (s,a),来估计 ( s , a ) (s,a) (s,a)的 return。但是第二种方法没法保证一定能访问到 ( s , a ) (s,a) (s,a)。所以可以用第一种方法,虽然比较笨,但是一定能算出 ( s , a ) (s,a) (s,a)的return。
五、MC Epsilon-Greedy 算法介绍
刚刚讲了 MC exploring starts 算法,但这个算法在实际中很难实现。在这一节中,我们尝试去掉exploring starts这个条件,让算法更易于实现。
方法是引入soft policy。简而言之,soft policy 是指对每一个action都有可能去做选择。之前提到过policy分为两种,第一种是deterministic policy(如 greedy policy),第二种是 stochastic policy(如:soft policy)。soft policy 是一种随机的策略。
为什么要引入 soft policy? 如果从某一个(s,a)出发,生成的 episode 特别特别长,因为 soft policy 是探索性、随机性的,那这个 episode 如果足够长,就能够保证任何一个(s,a)都能出现在这个 episode 里面。那就可以克服 MC exploring starts 算法的缺陷了。
使用什么样的 soft policy? 使用 ϵ \epsilon ϵ-greedy policies。
什么是 ϵ \epsilon ϵ-greedy policies? 以往在策略提升的过程中,对于 q ( s , a ) q(s,a) q(s,a) 最大的那个动作,总是赋予这个动作概率1,对其他动作赋予概率0。但在 ϵ \epsilon ϵ-greedy policies 中,不再给 q ( s , a ) q(s,a) q(s,a) 最大的那个动作赋予概率1,也不再给其他动作赋予概率0,而是给每个动作都赋予一定的概率,具体概率大小如下图所示。其中, ϵ \epsilon ϵ 是 [0,1] 之间的一个数, ∣ A ( s ) ∣ |A(s)| ∣A(s)∣ 是在状态s下,可能的动作数量。(这里可以给 ϵ \epsilon ϵ 和 ∣ A ( s ) ∣ |A(s)| ∣A(s)∣ 赋一个值,具象化地感受一下) ϵ \epsilon ϵ-greedy policies 有一个性质,就是选择 greedy action 的概率一定会比选择其他动作的概率大。
为什么用 ϵ \epsilon ϵ-greedy ? 因为这可以达到 **exploitation 和 exploration 的平衡。 exploitation 指充分利用当前的信息, exploration 是探索未知的信息。当 ϵ = 0 \epsilon=0 ϵ=0 时,策略变成贪心的,这样探索性变弱,但充分利用了已有的信息;当 ϵ = 1 \epsilon=1 ϵ=1 时,策略变成均匀分布,这样探索性会变强。
如何把 ϵ \epsilon ϵ-greedy 和 MC-based RL algorithms结合在一起? 以往的策略如下图所示,求出 q π k ( s , a ) q_{\pi_k}(s,a) qπk(s,a) 之后,选择q值最大的动作作为下一个策略(即:直接把该动作的概率设置为1,把其他动作的概率设置为0)。
但在 ϵ \epsilon ϵ-greedy 中,我们不这么做。算出 q π k ( s , a ) q_{\pi_k}(s,a) qπk(s,a) 之后,我们把最大的概率仍然赋值给greedy action,但是会给其他所有action一个相同的、比较小的概率。这样我们就得到了 MC Epsilon-Greedy 算法,和 MC Exploring Starts 相比, MC Epsilon-Greedy 算法使用的是 greedy 的策略。通过使用 MC Epsilon-Greedy 算法,我们就不再需要expoloring starts 这个条件了,无需从每一个 ( s , a ) (s,a) (s,a) 出发去生成 episode。
这是该算法的伪代码。它和 MC Exploring Starts 相比几乎一模一样,除了最后那个 π ( a ∣ s t ) \pi(a|s_t) π(a∣st) 的设置。另一个比较小的区别是,该算法使用了every-visit,而 MC Exploring Starts 使用了 first-visit,目的还是为了充分利用已有的数据,在一个(s, a)出现被访问多次的时候,多次计算其 return。
六、MC Epsilon-Greedy 算法例子
(1)一个单独的episode能访问所有的状态-动作对(s,a)吗?
当 ϵ = 1 \epsilon=1 ϵ=1时,策略是均匀分布,因为每个状态都有5种action,所以每个action都是0.2的概率。结果如下图所示。100 steps 时,会探索到一些state,1000 steps 时,会探索到更多state,10000步时,探索到更多 state,覆盖了所有的 action。图(d)表示探索100万步时,每一个(s,a)被访问到的次数,可以看到,此时虽然只有一个episode,但每一个 state-action pair 几乎都被访问了上千次。
当 ϵ \epsilon ϵ 比较小时,探索能力是比较弱的。结果如下图所示。100 steps 时,会探索到一些state,1000 steps 时,会探索到更多state,但还有很多状态没被探索到,在10000步时,会探索到更多 state,但最左下角那个格子里,向下的那个action没有被探索到。图(d)表示探索100万步时,每一个(s,a)被访问到的次数,可以看到,不同 state-action pair 被访问到的次数差异非常大,很多 state-action pair 都没怎么被访问到。但相比于greedy策略来说,还是有一定的探索能力。
(2)一个例子
在每次迭代中,使用 ϵ \epsilon ϵ greedy 策略,仅产生一个 episode,但这个 episode 包含了100万个 step。用这一个 episode 去更新所有的 state-action pair 的 q ( s , a ) q(s,a) q(s,a)。
下图展示了运行结果。(a)表示最初策略,此时在某一个状态s,选择不同动作的概率是相同的。(b)一次迭代后,产生了新的策略,这个策略相比于(a)好一些,但是还是不够好。(c)两次迭代后,产生了新的策略,这个策略相对更好一些,但还不是最优的,因为它还有可能进入到 forbidden area。总而言之, ϵ \epsilon ϵ greedy 策略通过其探索性避免了 exploring starts 的要求,但是同时也失去了最优性。
下图阐释了这个算法的优缺点。优点是:有更强的探索能力。缺点是:算法牺牲了最优性。所以说,可以设置一个相对小的 ϵ \epsilon ϵ 值,在尽量达到最优性的同时,又不失其探索性。
(3) ϵ \epsilon ϵ 不宜设置得过大
下图的每一个子图中,左边表示在给定 ϵ \epsilon ϵ 下计算出来的最优策略,右边表示最优策略的情况下对应的state value。从下图也可以看出, ϵ \epsilon ϵ 越小,策略的最优性越强(策略的优劣可以通过state value判断)。所以说, ϵ \epsilon ϵ 不宜设置得过大。或者说可以在程序一开始的时候,设置一个比较大的 ϵ \epsilon ϵ ,随着程序的运行, ϵ \epsilon ϵ 慢慢减小。
七、本节课summary
相关文章:
【强化学习的数学原理】第05课-蒙特卡洛方法-笔记
学习资料:bilibili 西湖大学赵世钰老师的【强化学习的数学原理】课程。链接:强化学习的数学原理 西湖大学 赵世钰 文章目录 一、通过例子介绍蒙特卡洛二、 MC Basic 算法介绍三、MC Basic 算法例子例1:MC Baxic算法例2:episode le…...
Spring源码(十三):Spring全系列总结
Spring总结篇,不同于之前抽丝剥茧式地纵向深入源码,本次从横向的角度出发,希望可以带个读者一个完全不同的Spring视角。 2024年重置版,搞点不一样的东西。希望通过本篇的内容,将之前的文章全部给串起来。 相关前文: Spring Boot启动加载Spring Web请求处理流程Spring上…...
算法日记 33 day 动态规划(打家劫舍,股票买卖)
今天来看看动态规划的打家劫舍和买卖股票的问题。 上题目!!!! 题目:打家劫舍 198. 打家劫舍 - 力扣(LeetCode) 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金…...
从零开始打造个人博客:我的网页设计之旅
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 ✨特色专栏:…...
用python将一个扫描pdf文件改成二值图片组成的pdf文件
使用墨水屏读书现在似乎越来越流行,这确实有一定的好处,例如基本不发热,电池续航时间超长,基本不能游戏所以有利于沉浸式阅读,还有不知道是不是真的有用的所谓防蓝光伤害。但是,如果阅读的书籍是扫描图片组…...
Electron开发构建工具electron-vite(alex8088)添加VueDevTools(VitePlugin)
零、介绍 本文章的electron-vite指的是这个项目👉electron-vite仓库,electron-vite网站 本文章的VueDevTools指的是VueDevTools的Vite插件版👉https://devtools.vuejs.org/guide/vite-plugin 一、有一个用electron-vite创建的项目 略 二、…...
服务器数据恢复—raid5阵列热备盘上线失败导致EXT3文件系统不可用的数据恢复案例
服务器数据恢复环境: 两组分别由4块SAS硬盘组建的raid5阵列,两组阵列划分的LUN组成LVM架构,格式化为EXT3文件系统。 服务器故障: 一组raid5阵列中的一块硬盘离线。热备盘自动上线替换离线硬盘,但在热备盘上线同步数据…...
网络安全基础——网络安全法
填空题 1.根据**《中华人民共和国网络安全法》**第二十条(第二款),任何组织和个人试用网路应当遵守宪法法律,遵守公共秩序,遵守社会公德,不危害网络安全,不得利用网络从事危害国家安全、荣誉和利益,煽动颠…...
go-rod vs Selenium:自动化测试工具的比较与选择
自动化测试是软件开发过程中的关键环节,它能够帮助我们发现缺陷、验证功能并提高软件质量。随着Web技术的快速发展,市场上出现了多种自动化测试工具,其中Selenium和go-rod是两个备受关注的选择。本文将从多个维度对这两个工具进行比较&#x…...
Ubuntu20.04+ROS 进行机械臂抓取仿真:环境搭建(一)
目录 一、从官网上下载UR机械臂 二、给UR机械臂添加夹爪 三、报错解决 本文详细介绍如何在Ubuntu20.04ROS环境中为Universal Robots的UR机械臂添加夹爪。首先从官方和第三方源下载必要的软件包,包括UR机械臂驱动、夹爪插件和相关依赖。然后,针对gazeb…...
Pytorch微调深度学习模型
在公开数据训练了模型,有时候需要拿到自己的数据上微调。今天正好做了一下微调,在此记录一下微调的方法。用Pytorch还是比较容易实现的。 网上找了很多方法,以及Chatgpt也给了很多方法,但是不够简洁和容易理解。 大体步骤是&…...
PPT分享 | IBM集团业务流程架构顶层规划-订单到交付-销售到回款方案
PPT下载链接见文末~ IBM业务流程规划方法是一套结构化、体系化的流程设计理论,其企业流程框架(EPF)是一种用于企业业务流程架构设计梳理的方法论。 一、IBM业务流程规划方法的核心 IBM的BPM(业务流程管理)流程管理体…...
后端并发编程操作简述 Java高并发程序设计 六类并发容器 七种线程池 四种阻塞队列
目录 并发集合 1. ConcurrentHashMap: 2. CopyOnWriteArrayList: 3. CopyOnWriteArraySet: 4. BlockingQueue系列: 5. ConcurrentSkipListMap 和 ConcurrentSkipListSet: 6. ConcurrentLinkedDeque:…...
基于LLama_factory的Qwen2.5大模型的微调笔记
Qwen2.5大模型微调记录 LLama-facrotyQwen2.5 模型下载。huggingface 下载方式Modelscope 下载方式 数据集准备模型微调模型训练模型验证及推理模型导出 部署推理vllm 推理Sglang 推理 LLama-facroty 根据git上步骤安装即可,要求的软硬件都装上。 llama-factory运行…...
resnet50,clip,Faiss+Flask简易图文搜索服务
一、实现 文件夹目录结构: templates -----upload.html faiss_app.py 前端代码: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widt…...
亚信安全与飞书达成深度合作
近日,亚信安全联合飞书举办的“走近先进”系列活动正式走进亚信。活动以“安全护航信息化 共筑数字未来路”为主题,吸引了众多数字化转型前沿企业的近百位领导参会。作为“走近先进”系列的第二场活动,本场活动更加深入挖掘了数字化转型的基础…...
Spring框架特性及包下载(Java EE 学习笔记04)
1 Spring 5的新特性 Spring 5是Spring当前最新的版本,与历史版本对比,Spring 5对Spring核心框架进行了修订和更新,增加了很多新特性,如支持响应式编程等。 更新JDK基线 因为Spring 5代码库运行于JDK 8之上,所以Spri…...
.net 8使用hangfire实现库存同步任务
C# 使用HangFire 第一章:.net Framework 4.6 WebAPI 使用Hangfire 第二章:net 8使用hangfire实现库存同步任务 文章目录 C# 使用HangFire前言项目源码一、项目架构二、项目服务介绍HangFire服务结构解析HangfireCollectionExtensions 类ModelHangfireSettingsHttpAuthInfoUs…...
python VS c++
一、语法特点 Python: 语法简洁、优雅,代码可读性极强,采用缩进来表示代码块,摒弃了像 C 那样使用大括号的传统方式,使得代码看上去十分清晰简洁。例如: if 5 > 3:print("5大于3") elif 5 …...
windows C#-属性
属性提供了一种将元数据或声明性信息与代码(程序集、类型、方法、属性等)关联的强大方法。将属性与程序实体关联后,可以使用称为反射的技术在运行时查询该属性。 属性具有以下属性: 属性将元数据添加到您的程序中。元数据是有关程序中定义的类型的信息…...
Redis常见面试题总结(上)
Redis 基础 什么是 Redis? Redis (REmote DIctionary Server)是一个基于 C 语言开发的开源 NoSQL 数据库(BSD 许可)。与传统数据库不同的是,Redis 的数据是保存在内存中的(内存数据库…...
小鹏汽车智慧材料数据库系统项目总成数据同步
1、定时任务处理 2、提供了接口 小鹏方面提供的推送的数据表结构: 这几个表总数为100多万,经过条件筛选过滤后大概2万多条数据 小鹏的人给的示例图: 界面: SQL: -- 查询车型 select bmm.md_material_id, bmm.material_num, bm…...
风尚云网前端学习:一个简易前端新手友好的HTML5页面布局与样式设计
风尚云网前端学习:一个简易前端新手友好的HTML5页面布局与样式设计 简介 在前端开发的世界里,HTML5和CSS3是构建现代网页的基石。本文将通过一个简单的HTML5页面模板,展示如何使用HTML5的结构化元素和CSS3的样式特性,来创建一个…...
论文阅读:A fast, scalable and versatile tool for analysis of single-cell omics data
Zhang, K., Zemke, N.R., Armand, E.J. et al. A fast, scalable and versatile tool for analysis of single-cell omics data. Nat Methods 21, 217–227 (2024). 论文地址:https://doi.org/10.1038/s41592-023-02139-9 代码地址:https://github.com…...
【从零开始的LeetCode-算法】43. 网络延迟时间
有 n 个网络节点,标记为 1 到 n。 给你一个列表 times,表示信号经过 有向 边的传递时间。 times[i] (ui, vi, wi),其中 ui 是源节点,vi 是目标节点, wi 是一个信号从源节点传递到目标节点的时间。 现在,…...
一文理解 Python 编程语言中的 .strip() 方法
🍉 CSDN 叶庭云:https://yetingyun.blog.csdn.net/ Python 中的 strip() 方法:初学者友好指南 在 Python 中,strip() 是一个极为实用的字符串方法,主要用于移除字符串首尾的特定字符。默认情况下,它会清除…...
solr 远程命令执行 (CVE-2019-17558)
漏洞描述 Apache Velocity是一个基于Java的模板引擎,它提供了一个模板语言去引用由Java代码定义的对象。Velocity是Apache基金会旗下的一个开源软件项目,旨在确保Web应用程序在表示层和业务逻辑层之间的隔离(即MVC设计模式)。 Apa…...
【cocos creator】下拉框
https://download.csdn.net/download/K86338236/90038176 const { ccclass, property } cc._decorator;type DropDownOptionData {optionString?: string,optionSf?: cc.SpriteFrame } type DropDownItemData {label: cc.Label,sprite: cc.Sprite,toggle: cc.Toggle }cccl…...
从 Llama 1 到 3.1:Llama 模型架构演进详解
编者按: 面对 Llama 模型家族的持续更新,您是否想要了解它们之间的关键区别和实际性能表现?本文将探讨 Llama 系列模型的架构演变,梳理了 Llama 模型从 1.0 到 3.1 的完整演进历程,深入剖析了每个版本的技术创新&#…...
电话机器人的最佳应用
电话机器人的最佳应用 作者:开源呼叫中心系统 FreeIPCC,Github地址:https://github.com/lihaiya/freeipcc 电话机器人在多个领域中都展现出了其独特的优势和广泛的应用前景。以下是对电话机器人最佳应用的详细归纳: 一、销售与营…...
[面试]-golang基础面试题总结
文章目录 panic 和 recover**注意事项**使用 pprof、trace 和 race 进行性能调试。**Go Module**:Go中new和make的区别 Channel什么是 Channel 的方向性?如何对 Channel 进行方向限制?Channel 的缓冲区大小对于 Channel 和 Goroutine 的通信有…...
Fakelocation Server服务器/专业版 ubuntu
前言:需要Ubuntu系统 Fakelocation开源文件系统需求 Ubuntu | Fakelocation | 任务一 任务一 更新Ubuntu(安装下载不再赘述) sudo -i # 提权 sudo apt update # 更新软件包列表 sudo apt upgrade # 升级已安装的软…...
Node.js的http模块:创建HTTP服务器、客户端示例
新书速览|Vue.jsNode.js全栈开发实战-CSDN博客 《Vue.jsNode.js全栈开发实战(第2版)(Web前端技术丛书)》(王金柱)【摘要 书评 试读】- 京东图书 (jd.com) 要使用http模块,只需要在文件中通过require(http)引入即可。…...
Jackson 对象与json数据互转工具类JacksonUtil
下面是一个基于 Jackson 的工具类 JacksonUtil,用于在 Java 项目中实现对象与 JSON 数据之间的互相转换。该工具类具有简洁、易用、通用的特点。 package com.fy.common.util;import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core…...
【ArcGISPro】根据yaml构建原始Pro的conda环境
使用场景 我们不小心把原始arcgispro-py3的conda环境破坏了,我们就可以使用以下方法进行修复 查找文件 在arcgis目录下找到yaml文件 如果没找到请复制以下内容到新的yaml文件 channels: - esri - defaults dependencies: - anyio=4.2.0=py311haa95532_0 - appdirs=1.4.4=p…...
对撞双指针(七)三数之和
15. 三数之和 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k ,同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。 注意:答案中不可以包含重复的三元组…...
反向代理服务器的用途
代理服务器在网络中扮演着重要的角色,它们可以优化流量、保护服务器以及提高安全性。在代理服务器中,反向代理服务器是一种特殊类型,常用于Web服务器前,它具备多种功能,能够确保网络流量的顺畅传输。那么,让…...
一些好的AI技术学习平台和资料(动态更新)
1. 大模型 1.1 提示词(Prompt) 目前,大模型技术已经深入到工作生活的方方面面,各技术大厂的大模型也层出不穷,从开始的OpenAI一家独大,到当今世界的“百模大战”。从一些日常使用的角度来说,模…...
wireshark抓包分析HTTP协议,HTTP协议执行流程,
「作者主页」:士别三日wyx 「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」:对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 使用WireShark工具抓取「HTTP协议」的数据包&#…...
路由缓存后跳转到新路由时,上一路由中的tip信息框不销毁问题解决
上一路由tip信息框不销毁问题解决 路由缓存篇问题描述及截图解决思路关键代码 路由缓存篇 传送门 问题描述及截图 路由缓存后跳转新路由时,上一个路由的tip信息框没销毁。 解决思路 在全局路由守卫中获取DOM元素,通过css去控制 关键代码 修改文…...
【Angular】async详解
在 Angular 中,async 关键字用于定义异步函数,通常与 await 一起使用来处理 Promise。这使得异步代码看起来更像同步代码,从而更容易理解和维护。 基本用法 定义异步函数:使用 async 关键字。等待 Promise 解析:使用…...
springboot/ssm综合小区管理系统Java社区物业停车缴费系统web物业源码
springboot/ssm综合小区管理系统Java社区物业停车缴费系统web物业源码 基于springboot(可改ssm)htmlvue项目 开发语言:Java 框架:springboot/可改ssm vue JDK版本:JDK1.8(或11) 服务器:tomcat 数据库&…...
【51单片机】程序实验56.独立按键-矩阵按键
主要参考学习资料:B站【普中官方】51单片机手把手教学视频 前置知识:C语言 单片机套装:普中STC51单片机开发板A4标准版套餐7 码字不易,求点赞收藏加关注(•ω•̥) 有问题欢迎评论区讨论~ 目录 独立按键按键介绍实验5 独立按键 矩…...
SAP 零售方案 CAR 系统的介绍与研究
前言 当今时代,零售业务是充满活力和活力的业务领域之一。每天,由于销售运营和客户行为,它都会生成大量数据。因此,公司迫切需要管理数据并从中检索见解。它将帮助公司朝着正确的方向发展他们的业务。 这就是为什么公司用来处理…...
2024 APMCM亚太数学建模C题 - 宠物行业及相关产业的发展分析和策略 完整参考论文(2)
5.2 问题一模型的建立与求解 5.2.1 分析发展情况 为了更好地理解数据的变化趋势,利用matlab通过六个子图对宠物行业中的关键变量进行了可视化展示。 图 1. 宠物数量变化展示了 猫数量、狗数量 和 总宠物数量 在 2019-2023 年间的变化趋势。结果显示:猫的数量呈逐年上升的趋…...
嵌入式的C/C++:深入理解 static、const 与 volatile 的用法与特点
目录 一、static 1、static 修饰局部变量 2、 static 修饰全局变量 3、static 修饰函数 4、static 修饰类成员 5、小结 二、const 1、const 修饰普通变量 2、const 修饰指针 3、const 修饰函数参数 4. const 修饰函数返回值 5. const 修饰类成员 6. const 与 #defi…...
【数据库设计】软件系统需要同时设计注册日志表和登录日志表吗
是的,通常情况下,注册日志表和登录日志表是分别设计的,分别记录不同类型的事件信息。 注册日志表 记录用户的注册信息、注册方式以及是否成功等内容。登录日志表 记录用户每次登录的时间、IP 地址、设备信息、登录状态等内容。 尽管这两者看…...
vim 一次注释多行 的几种方法
在 Vim 中一次注释多行是一个常见操作。可以使用以下方法根据你的具体需求选择合适的方式: 方法 1:手动插入注释符 进入正常模式: 按 Esc 确保进入正常模式。 选择需要注释的多行: 移动到第一行,按下 Ctrlv 进入可视块…...
手机无法连接服务器1302什么意思?
你有没有遇到过手机无法连接服务器,屏幕上显示“1302”这样的错误代码?尤其是在急需使用手机进行工作或联系朋友时,突然出现的连接问题无疑会带来不少麻烦。那么,什么是1302错误,它又意味着什么呢? 1302错…...
Git(一)基本使用
目录 一、使用git -v 查看安装git版本 二、使用mkdir 创建一个文件,并使用 git init 在该目录下创建一个本地仓库, 三、通过git clone命令接入线上仓库 四、使用git status查看仓库状态信息 五、利用echo写入一个文件 并使用cat进行查看 【Linux】e…...