强化学习课程:stanford_cs234 学习笔记(3)introduction to RL

文章目录

  • 前言
  • 7 markov 实践
    • 7.1 markov 过程再叙
    • 7.2 markov 奖励过程 MRP(markov reward process)
    • 7.3 markov 价值函数与贝尔曼方程
    • 7.4 markov 决策过程MDP(markov decision process)的 状态价值函数
      • 7.4.1 状态价值函数
      • 7.4.2 状态价值函数的 贝尔曼期望方程(Bellman Expectation Equation)
    • 7.5 markov 决策过程MDP(markov decision process)的 动作价值函数
      • 7.5.1 动作价值函数
      • 7.5.2 动作价值函数和状态价值函数
      • 7.5.3 动作价值函数的贝尔曼期望等式
    • 7.6 动作价值和状态价值例子
      • 7.6.1 边缘化(marginalization),就


前言

第一节课的后半段其实就是一个马尔可夫的实际案例教学,我这里在网上找到一个合适案例进行学习,cs234 的课程感觉有点空。
在这里插入图片描述

7 markov 实践

7.1 markov 过程再叙

markov 过程就是一个状态转移过程,且该当前状态只和上一个状态有关,和历史无关。
即: P ( s t ∣ s t − 1 ) = P ( s t ∣ s t − 1 , s t − 2 , s t − 3 , . . . , s n ) P(s_t| s_{t-1}) = P(s_t | s_{t-1}, s_{t-2}, s_{t-3},...,s_n) P(stst1)=P(stst1,st2,st3,...,sn)

markov 状态转移矩阵:
P = [ p s 1 ∣ s 1 p s 2 ∣ s 1 . . . p s n ∣ s 1 p s 2 ∣ s 1 p s 2 ∣ s 2 . . . p s n ∣ s 2 . . . p s 1 ∣ s n p s 2 ∣ s n . . . p s n ∣ s n ] P= \begin{equation} \begin{bmatrix} p_{s_1|s_1} & p_{s_2|s_1} &...& p_{s_n|s_1} \\ p_{s_2|s_1} & p_{s_2|s_2} &...& p_{s_n|s_2} \\ ... \\ p_{s_1|s_n} & p_{s_2|s_n} &...& p_{s_n|s_n} \end{bmatrix} \end{equation} P= ps1s1ps2s1...ps1snps2s1ps2s2ps2sn.........psns1psns2psnsn
矩阵中的 第i行第j列表示状态 s i s_i si s j s_j sj 的概率 p ( s i ∣ s j ) = p ( s t + 1 = s j ∣ s t = s i ) p(s_i|s_j) = p(s_{t+1}=s_j | s_{t} = s_i) p(sisj)=p(st+1=sjst=si)。称
P ( s ′ ∣ s ) P(s' | s) P(ss) 为转移函数。这里要求 从某个状态到其他所有状态的概率和必须为1, 即P矩阵每行概率和为1

如果我们按照满足markov 性,根据状态转移矩阵,得到一个状态转移序列
s1->s1->s2->s3->s4->s5->s6 那么就得到了一个markov chain 即马尔可夫链。

7.2 markov 奖励过程 MRP(markov reward process)

马尔可夫奖励过程是 [S, P r, γ \gamma γ]
S:状态集合
P:状态转移矩阵
r : reward
γ \gamma γ:discount factor

为什么要奖励(reward)?
(1)一个稳定的世界需要反馈,合理的反馈可以让我们趋于一个稳定。
因此引入奖励机制。我们将奖励机制和markov 过程结合,那么有
(2)我们针对不同场景,有不同的回报,因此奖励机制可以调整我们如何适应变化的环境。

为什么要折扣(discount factor)
(1)一个马尔可夫过程是有可能出现闭环,如果无限循环下去,那么奖励就有可能无限累加,要避免这种奖励因子不断累加,那么就需要折扣。在想想这句古话:一股做气,再而衰,三而竭。这不就是折扣因子么。
(2)有时候我们需要近期的效果,那么我们会将长远利益打一些折扣。相反,我们关注长远利益时,需要近期利益打折扣

将reward 和 discount factor 结合得到回报(Return)
G t = R t + γ ∗ R t + 1 + γ 2 ∗ R t + 2 + . . . = ∑ k = 0 ∞ γ k R t + k G_t=R_{t} + \gamma*R_{t+1} + \gamma^2*R_{t+2} + ... = \sum_{k=0}^{\infty}\gamma^kR_{t+k} Gt=Rt+γRt+1+γ2Rt+2+...=k=0γkRt+k

7.3 markov 价值函数与贝尔曼方程

价值(value):一个状态的期望回报,即从这个状态出发的未来累积奖励的期望值,被称为这个状态的价值:

V ( s ) = E [ R t + γ ∗ R t + 1 + γ 2 ∗ R t + 2 + . . . ∣ s = s t ] = E [ R t + γ ( R t + 1 + γ ∗ R t + 2 + . . . ∣ s = s t ) ] = E [ R t + γ G ( s = s t + 1 ∣ s = s t ) ] = E [ R t + γ G t + 1 ∣ s = s t ] = E [ R t ∣ s t ] + E γ G t + 1 ∣ s t = r ( s ) + γ V t + 1 ∣ s = s t = r ( s ) + γ ∑ p ( s t + 1 ∣ s t ) V t + 1 , 注:我第一遍推成 r ( s ) + γ ∑ p ( s t + 1 ∣ s t ) V t ,导致后面直接推不下去了 = r ( s ) + γ ∑ p ( s ′ ∣ s ) V ( s ′ ) , s ′ ∈ S = 贝尔曼方程( B e l l m a n E q u a t i o n ) V(s)\\ = E[R_{t} + \gamma*R_{t+1} + \gamma^2*R_{t+2} + ... | s=s_t]\\ = E[R_t + \gamma (R_{t+1} + \gamma*R_{t+2} + ...| s=s_t)]\\ = E[R_t + \gamma G(s=s_{t+1}|s=s_{t})]\\ = E[R_t + \gamma G_{t+1}|s=s_{t}]\\ = E[R_t|s_t] + E\gamma G_{t+1}| s_t\\ = r(s) + \gamma V_{t+1}|s=s_{t}\\ = r(s) + \gamma \sum{ p(s_{t+1}|s_t)V_{t+1}},\textcolor{#FF0000}{注:我第一遍推成r(s) + \gamma \sum{ p(s_{t+1}|s_t)V_t},导致后面直接推不下去了}\\ = r(s) + \gamma \sum{ p(s'|s)V(s')}, s' \in S \\ = 贝尔曼方程(Bellman Equation) V(s)=E[Rt+γRt+1+γ2Rt+2+...∣s=st]=E[Rt+γ(Rt+1+γRt+2+...∣s=st)]=E[Rt+γG(s=st+1s=st)]=E[Rt+γGt+1s=st]=E[Rtst]+EγGt+1st=r(s)+γVt+1s=st=r(s)+γp(st+1st)Vt+1注:我第一遍推成r(s)+γp(st+1st)Vt,导致后面直接推不下去了=r(s)+γp(ss)V(s),sS=贝尔曼方程(BellmanEquation

于是我们不难得到:
当s’= s1的时候:
[ V ( s 1 ) ] = [ r ( s 1 ) ] + γ [ p s 1 ∣ s 1 p s 2 ∣ s 1 . . . p s n ∣ s 1 ] [ V ( s 1 ) V ( s 2 ) . . . V ( s n ) ] \begin{equation} \begin{bmatrix} V(s_1) \\ \end{bmatrix} = \begin{bmatrix} r(s_1) \\ \end{bmatrix} + \gamma \begin{bmatrix} p_{s_1|s_1} & p_{s_2|s_1} &...& p_{s_n|s_1} \\ \end{bmatrix} \begin{bmatrix} V(s1) \\ V(s2) \\ ... \\ V(sn)\\ \end{bmatrix} \end{equation} [V(s1)]=[r(s1)]+γ[ps1s1ps2s1...psns1] V(s1)V(s2)...V(sn)
当s’=s2的时候:
[ V ( s 2 ) ] = [ r ( s 2 ) ] + γ [ p s 1 ∣ s 2 p s 2 ∣ s 2 . . . p s n ∣ s 2 ] [ V ( s 1 ) V ( s 2 ) . . . V ( s n ) ] \begin{equation} \begin{bmatrix} V(s_2) \\ \end{bmatrix} = \begin{bmatrix} r(s_2) \\ \end{bmatrix} + \gamma \begin{bmatrix} p_{s_1|s_2} & p_{s_2|s_2} &...& p_{s_n|s_2} \\ \end{bmatrix} \begin{bmatrix} V(s1) \\ V(s2) \\ ... \\ V(sn)\\ \end{bmatrix} \end{equation} [V(s2)]=[r(s2)]+γ[ps1s2ps2s2...psns2] V(s1)V(s2)...V(sn)

接下来,我们写成矩阵形式:

[ V ( s 1 ) V ( s 2 ) . . . V ( s n ) ] = [ r ( s 1 ) r ( s 2 ) . . . r ( s n ) ] + γ [ p s 1 ∣ s 1 p s 2 ∣ s 1 . . . p s n ∣ s 1 p s 2 ∣ s 1 p s 2 ∣ s 2 . . . p s n ∣ s 2 . . . p s 1 ∣ s n p s 2 ∣ s n . . . p s n ∣ s n ] [ V ( s 1 ) V ( s 2 ) . . . V ( s n ) ] \begin{equation} \begin{bmatrix} V(s1) \\ V(s2) \\ ... \\ V(sn)\\ \end{bmatrix} = \begin{bmatrix} r(s1) \\ r(s2) \\ ... \\ r(sn)\\ \end{bmatrix} + \gamma \begin{bmatrix} p_{s_1|s_1} & p_{s_2|s_1} &...& p_{s_n|s_1} \\ p_{s_2|s_1} & p_{s_2|s_2} &...& p_{s_n|s_2} \\ ... \\ p_{s_1|s_n} & p_{s_2|s_n} &...& p_{s_n|s_n} \end{bmatrix} \begin{bmatrix} V(s1) \\ V(s2) \\ ... \\ V(sn)\\ \end{bmatrix} \end{equation} V(s1)V(s2)...V(sn) = r(s1)r(s2)...r(sn) +γ ps1s1ps2s1...ps1snps2s1ps2s2ps2sn.........psns1psns2psnsn V(s1)V(s2)...V(sn)

于是就得到:
V = R + γ P V V=R+\gamma P V V=R+γPV
V − γ P V = R V - \gamma P V=R VγPV=R
( I − γ P ) V = R (I - \gamma P)V = R (IγP)V=R
V = ( I − γ P ) − 1 R V=(I - \gamma P)^{-1}R V=(IγP)1R

按照以往计算经验,这个矩阵解起来巨麻烦,所以会用 动态规划(dynamic programming)、 **蒙特卡罗(模拟特-Carlo method)**方法 或 时序差分(temporal difference)

7.4 markov 决策过程MDP(markov decision process)的 状态价值函数

7.4.1 状态价值函数

智能体(agent)的策略(Policy)通常用 π \pi π表示。策略 π ( a ∣ s ) = P ( A t = a ∣ S t = s ) \pi(a|s) = P(A_t = a| S_t = s) π(as)=P(At=aSt=s)是一个函数,表示在s状态下采取a动作的概率。当一个策略是确定性策略(deterministic policy)的时候,那么智能体在每个状态只输出一个确定动作
当智能体的策略是随机测策略(stochastic policy)时,那么这个函数输出的是关于动作的概率分布。

状态价值函数:
我们用 V π ( s ) V^{\pi}(s) Vπ(s)表示在MDP基于测率 π \pi π策略得到的价值函数期望:
V π ( s ) = E π [ G t ∣ S t = s ] V^{\pi}(s) = E_\pi[G_t | S_t= s] Vπ(s)=Eπ[GtSt=s]
我这里专门推敲了下: V π V^\pi Vπ和 V 是一回事,只是为了讲名是什么策略,因此加了 π \pi π,即乘以一个概率。

7.4.2 状态价值函数的 贝尔曼期望方程(Bellman Expectation Equation)

根据上面贝尔曼方程算 V ( s ) V(s) V(s)
V ( s ) = r ( s ) + γ ∑ p ( s ′ ∣ s ) V ( s ′ ) , s ′ ∈ S V(s) = r(s) + \gamma \sum{ p(s'|s)V(s')}, s' \in S V(s)=r(s)+γp(ss)V(s),sS
当我们要将在那个策略下时,不难得到:
V π ( s ) = E π [ G t ∣ S t = s ] = ∑ π ( a ∣ s ) [ r ( s ) + γ ∑ p ( s ′ ∣ s ) V ( s ′ ) ] , s ′ ∈ S V^{\pi}(s) = E_\pi[G_t | S_t= s]\\ =\sum \pi(a|s) [ r(s) + \gamma \sum{ p(s'|s)V(s') } ], s' \in S Vπ(s)=Eπ[GtSt=s]=π(as)[r(s)+γp(ss)V(s)],sS——因为需要策略 π \pi π得概率,因此需要乘以 π \pi π

V π ( s ) = r ( s , a ) + γ ∑ s ′ ∈ S p ( s ′ ∣ s , a ) ∑ a ′ ∈ A π ( a ∣ s ′ ) Q π ( s ′ , a ′ ) V^\pi(s)=r(s, a) + \gamma \sum_{s' \in S} p(s'|s, a) \sum_{a' \in A}\pi(a|s') Q^{\pi} (s',a') Vπ(s)=r(s,a)+γsSp(ss,a)aAπ(as)Qπ(sa)

7.5 markov 决策过程MDP(markov decision process)的 动作价值函数

markov 决策过程MDP(markov decision process)—— 动作价值函数

7.5.1 动作价值函数

不同于MRP,在MDP过程中,由于动作的存在,额外定义一个动作价值函数(action-value function)。用 Q π Q^\pi Qπ 表示,在s 状态下,执行动作a的得到的期望:
Q π ( s , a ) = E π [ G t ∣ S t = s , A t = a ] Q^\pi(s, a) = E_\pi[G_t | S_t = s, A_{t}=a] Qπ(s,a)=Eπ[GtSt=s,At=a] 。说实话我这里被定义给搞晕了,因此我理解这里就是不需要乘以 π ( a ∣ s ) \pi(a|s) π(as)

7.5.2 动作价值函数和状态价值函数

所以得到 V π V^{\pi} Vπ Q π Q^\pi Qπ的关系:

(1) V π ( s ) = ∑ a ∈ A π ( a ∣ s ) Q π ( s , a ) V^{\pi}(s) = \sum_{a \in A} \pi(a|s) Q^\pi(s, a) Vπ(s)=aAπ(as)Qπ(s,a)
这个式子描述的是:使用策略 π \pi π, 状态 s的价值期望,等于动作价值函数乘以发生动作概率的乘积的总和。这里是动作未发生,需要乘上动作的概率和动作的价值

(2) Q π ( s , a ) = r ( s , a ) + γ ∑ P ( s ′ ∣ s , a ) V π ( s ′ ) Q^\pi(s, a) = r(s,a) + \gamma \sum P(s' | s, a) V^\pi(s') Qπ(s,a)=r(s,a)+γP(ss,a)Vπ(s)
使用策略 π \pi π时,状态s下采取a动作后的价值期望 等于 当下的奖励加上 经过 γ \gamma γ衰减之后的所有状态状态转移概率与相应价值的乘积。
这里是动作已经确定,但是状态不确定,因此乘的是状态转移矩阵和状态

也就是说状态与状态之间不再是单纯的转移,还有动作的这个价值反馈加进去。

7.5.3 动作价值函数的贝尔曼期望等式

根据定义:
Q π ( s , a ) = r ( s , a ) + γ ∑ s ′ ∈ S P ( s ′ ∣ s , a ) V π ( s ′ ) Q^\pi(s, a) = r(s,a) + \gamma \sum_{s'\in S} P(s' | s, a) V^\pi(s') Qπ(s,a)=r(s,a)+γsSP(ss,a)Vπ(s)

又因为:
V π ( s ) = ∑ a ∈ A π ( a ∣ s ) Q π ( s , a ) V^{\pi}(s) = \sum_{a \in A} \pi(a|s) Q^\pi(s, a) Vπ(s)=aAπ(as)Qπ(s,a)
那么:
V π ( s ′ ) = ∑ a ∈ A π ( a ∣ s ′ ) Q π ( s ′ , a ) V^{\pi}(s') = \sum_{a \in A} \pi(a|s') Q^\pi(s', a) Vπ(s)=aAπ(as)Qπ(s,a)
上面的式子可以再变个型,带入后:
Q π ( s , a ) = r ( s , a ) + γ ∑ s ′ ∈ S P ( s ′ ∣ s , a ) V π ( s ′ ) = r ( s , a ) + γ ∑ s ′ ∈ S P ( s ′ ∣ s , a ) ∑ a ∈ A π ( a ∣ s ′ ) Q π ( s ′ , a ) Q^\pi(s, a)= r(s,a) + \gamma \sum_{s'\in S} P(s' | s, a) V^\pi(s')\\ =r(s,a) + \gamma \sum_{s'\in S} P(s' | s, a) \sum_{a \in A} \pi(a|s') Q^\pi(s', a) Qπ(s,a)=r(s,a)+γsSP(ss,a)Vπ(s)=r(s,a)+γsSP(ss,a)aAπ(as)Qπ(s,a)
——————————————————————
动作价值函数和状态价值函数的贝尔曼方程很常见,所以我这里推敲了下。
——————————————————————

7.6 动作价值和状态价值例子

在这里插入图片描述
图中的
(1)虚线表示动作到状态
(2)图中的实现表示从当前状态开始当前动作
(3)红色的数字是标记状态奖励
(4)没有标记数字的线表示概率为1,如果标记了表示对应概率。

7.6.1 边缘化(marginalization),就

这里有个一般的计算MDP的方法,就是将测率的动作边缘化:
(1) 得到一个没有动作的mrp。即对于某个状态,我跟将根据动作策略进行加权,就得到r’(s)是该状态下的奖励:
s ′ = ∑ a ∈ A π ( a ∣ s ) r ( s , a ) s'=\sum_{a \in A} \pi(a|s)r(s,a) s=aAπ(as)r(s,a)

(2)同理,将计算采取动作的概率 π \pi π与 将s转移到s’转移矩阵进行相乘再累加,就得到一个MRP的从s转移到s‘的转移概率。

这样的做法有如下好处:
简化问题结构
MDP 涉及状态和动作两层结构,分析和求解复杂。而给定策略后,动作选择就变成确定的概率分布,这时只剩下状态和状态之间的转移(+奖励)——正好就是 MRP 的结构。
MRP 更容易求解
MRP 没有动作维度,可以直接用线性代数(比如矩阵解法或贝尔曼方程迭代)来求解状态值函数 𝑉(𝑠)非常方便。

这个方法是*给定策略下的通用方法。 如果你要做最优策略求解(如值迭代、Q-learning),那就不能只转成 MRP,因为你需要在每一步决策中“寻找最优动作”,那就是另一套框架了(比如 Bellman Optimality Equation)。

实践代码如下:

import numpy as npdef join(str1, str2):return str1 + '-' + str2# markov_chain is a list that save the index of state 
# for example:s1->s1->s2->s3->s4->s5->s6 
# start_index: the start index for markov_chain, not the state index.
def get_return(start_index, markov_chain, rewards, gamma):G_t = 0# >>>>>>> the code is very tricky but effective! <<<<<<<for idx in reversed(range(start_index, len(markov_chain))):# the state index is start at 1 end in 6, so when we use the idx we need to minus 1G_t = gamma * G_t + rewards[markov_chain[idx] - 1]return G_tdef get_value(p_matrix, rewards, gamma):states_amount = len(rewards)rewards = np.array(rewards)rewards = rewards.reshape((-1, 1))value = np.dot(np.linalg.inv(np.eye(states_amount, states_amount) - gamma * p_matrix), rewards)return valuedef mrp_test():np.random.seed(0)p = [[0.8, 0.1, 0.1, 0.0, 0.0, 0.0],[0.0, 0.2, 0.5, 0.3, 0.0, 0.0],[0.0, 0.0, 0.5, 0.5, 0.0, 0.0],[0.1, 0.1, 0.1, 0.1, 0.3, 0.3],[0.2, 0.5, 0.1, 0.0, 0.1, 0.1],[0.0, 0.0, 0.2, 0.3, 0.4, 0.1],]p = np.array(p)# fist to checkt if the sum of each row is 1.0H, W = p.shapefor h in range(H):sum_h = np.sum(p[h,:])# for float compoare we can not suppose it will be exactly 1.0 actually is 0.999999999....if sum_h < 0.9999999 or sum_h > 1.0: print("error in line:" + str(h) + " sum:" + str(sum_h))exit()#          s1, s2, s3, s4, s5, s6rewards = [-1, -2,  0,  1,  2,  4] gamma = 0.7markov_chain = [1, 1, 2, 3, 4, 5, 6, 1]# get the return for agentG_t = get_return(0, markov_chain, rewards, gamma)# get the value for agentV_t = get_value(p, rewards, gamma)print(">>> markov finish!")def mdp_test():states = ["s1", "s2", "s3", "s4", "s5", "s6"]actions = ["hold_s1", "arrival_s2","arrival_s3","arrival_s4", "arrival_s5", "arrival_s6", "stochastic_arrival"]p = {"s1-hold_s1-s1": 1.0,"s1-arrival_s2-s2": 1.0,"s2-arrival_s1-s1": 1.0,"s2-arrival_s3-s3": 1.0,"s3-arrival_s4-s4": 1.0,"s3-arrival_s6-s6": 1.0,"s4-arrival_s5-s5": 1.0,"s5-arrival_s6-s6": 1.0,"s4-stochastic_arrival_s2": 0.2,"s4-stochastic_arrival_s3": 0.3,"s4-stochastic_arrival_s4": 0.5,}rewards = {"s1-hold_s1":   -1,"s1-arrival_s2": 0,"s2-arrival_s1":-1,"s2-arrival_s3":-2,"s3-arrival_s4":-2,"s3-arrival_s6": 7,"s4-arrival_s5": 2,"s5-arrival_s6": 8,"s4-stochastic_arrival_s2": 1,"s4-stochastic_arrival_s3": 1,"s4-stochastic_arrival_s4": 1 }gamma = 0.5mdp = (states, actions, p, gamma)pi_1 = {"s1-hold_s1": 0.5,"s1-arrival_s2": 0.5,"s2-arrival_s1": 0.5,"s2-arrival_s3": 0.5,"s3-arrival_s4": 0.5,"s3-arrival_s5": 0.5,"s4-arrival_s5": 0.5,"s4-stochastic_arrival": 0.5,} pi_2 = {"s1-hold_s1": 0.6,"s1-arrival_s2": 0.4,"s2-arrival_s1": 0.3,"s2-arrival_s3": 0.7,"s3-arrival_s4": 0.5,"s3-arrival_s5": 0.5,"s4-arrival_s5": 0.1,"s4-stochastic_arrival": 0.9,} # 转化后的MRP的状态转移矩阵p_mdp2mrp_pi_1 = [# s1, s2,  s3,  s4,  s5,  s6[1.0 * 0.5, 1.0 * 0.5, 0.0,       0.0,       0.0,       0.0      ],[1.0 * 0.5, 0.0,       1.0 * 0.5, 0.0,       0.0,       0.0      ],[0.0,       0.0,       0.0,       1.0 * 0.5, 0.0,       1.0 * 0.5],[0.0,       0.2 * 0.5, 0.3 * 0.5, 0.5,       1.0 * 0.5, 0.0      ],[0.0,       0.0,       0.0,       0.0,       0.0,       1.0 * 0.5],[0.0,       0.0,       0.0,       0.0,       0.0,       1.0      ],]p_mdp2mrp_pi_1 = np.array(p_mdp2mrp_pi_1)R_mdp2mrp_pi_1 = [-1 * 0.5, -1 * 0.5 + -2 * 0.5,7 * 0.5 + -2 * 0.5,2 * 0.5 +  1 * 0.5, 8 * 0.5,0]# get the  mrp base on mdpv = get_value(p_mdp2mrp_pi_1, R_mdp2mrp_pi_1, gamma)print("mdp v=" + str(v))print("mdp finish!")if __name__ == "__main__":#mrp_test()mdp_test()

运行结果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/74659.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

操作系统 4.5-文件使用磁盘的实现

通过文件进行磁盘操作入口 // 在fs/read_write.c中 int sys_write(int fd, const char* buf, int count) {struct file *file current->filp[fd];struct m_inode *inode file->inode;if (S_ISREG(inode->i_mode))return file_write(inode, file, buf, count); } 进程…

libreoffice-help-common` 的版本(`24.8.5`)与官方源要求的版本(`24.2.7`)不一致

出现此错误的原因主要是软件包依赖冲突&#xff0c;具体分析如下&#xff1a; ### 主要原因 1. **软件源版本不匹配&#xff08;国内和官方服务器版本有差距&#xff09; 系统中可能启用了第三方软件源&#xff08;如 PPA 或 backports 源&#xff09;&#xff0c;导致 lib…

使用Geotools中的原始方法来操作PostGIS空间数据库

目录 前言 一、原生PostGIS连接介绍 1、连接参数说明 2、创建DataStore 二、工程实战 1、Maven Pom.xml定义 2、空间数据库表 3、读取空间表的数据 三、总结 前言 在当今数字化与信息化飞速发展的时代&#xff0c;空间数据的处理与分析已成为众多领域不可或缺的一环。从…

讯飞语音合成(流式版)语音专业版高质量的分析

一、引言 在现代的 Web 应用开发中&#xff0c;语音合成技术为用户提供了更加便捷和人性化的交互体验。讯飞语音合成&#xff08;流式版&#xff09;以其高效、稳定的性能&#xff0c;成为了众多开发者的首选。本文将详细介绍在 Home.vue 文件中实现讯飞语音合成&#xff08;流…

走进未来的交互世界:下一代HMI设计趋势解析

在科技日新月异的今天&#xff0c;人机交互界面&#xff08;HMI&#xff09;设计正以前所未有的速度发展&#xff0c;不断引领着未来的交互世界。从简单的按钮和图标&#xff0c;到如今的智能助手和虚拟现实&#xff0c;HMI设计不仅改变了我们的生活方式&#xff0c;还深刻影响…

洛谷题单3-P1217 [USACO1.5] 回文质数 Prime Palindromes-python-流程图重构

题目描述 因为 151 151 151 既是一个质数又是一个回文数&#xff08;从左到右和从右到左是看一样的&#xff09;&#xff0c;所以 151 151 151 是回文质数。 写一个程序来找出范围 [ a , b ] ( 5 ≤ a < b ≤ 100 , 000 , 000 ) [a,b] (5 \le a < b \le 100,000,000…

学习笔记,DbContext context 对象是保存了所有用户对象吗

DbContext 并不会将所有用户对象保存在内存中&#xff1a; DbContext 是 Entity Framework Core (EF Core) 的数据库上下文&#xff0c;它是一个数据库访问的抽象层它实际上是与数据库的一个连接会话&#xff0c;而不是数据的内存缓存当您通过 _context.Users 查询数据时&…

本地命令行启动服务并连接MySQL8

启动服务命令 net start mysql8 关闭服务命令 net stop mysql8 本地连接MySQL数据库mysql -u [用户名] -p[密码] 这里&#xff0c;我遇到了个问题 —— 启动、关闭服务时&#xff0c;显示 “发生系统错误 5。拒绝访问。 ” 解法1&#xff1a;在 Windows 上以管理员身份打开…

数据蒸馏:Dataset Distillation by Matching Training Trajectories 论文翻译和理解

一、TL&#xff1b;DR 数据集蒸馏的任务是合成一个较小的数据集&#xff0c;使得在该合成数据集上训练的模型能够达到在完整数据集上训练的模型相同的测试准确率&#xff0c;号称优于coreset的选择方法本文中&#xff0c;对于给定的网络&#xff0c;我们在蒸馏数据上对其进行几…

【spring cloud Netflix】Ribbon组件

1.基本概念 SpringCloud Ribbon是基于Netflix Ribbon 实现的一套客户端负载均衡的工具。简单的说&#xff0c;Ribbon 是 Netflix 发布的开源项目&#xff0c;主要功能是提供客户端的软件负载均衡算法&#xff0c;将 Netflix 的中间层服务连接在一 起。Ribbon 的客户端组件提供…

P1036 [NOIP 2002 普及组] 选数(DFS)

题目描述 已知 n 个整数 x1​,x2​,⋯,xn​&#xff0c;以及 1 个整数 k&#xff08;k<n&#xff09;。从 n 个整数中任选 k 个整数相加&#xff0c;可分别得到一系列的和。例如当 n4&#xff0c;k3&#xff0c;4 个整数分别为 3,7,12,19 时&#xff0c;可得全部的组合与它…

在响应式网页的开发中使用固定布局、流式布局、弹性布局哪种更好

一、首先看下固定布局与流体布局的区别 &#xff08;一&#xff09;固定布局 固定布局的网页有一个固定宽度的容器&#xff0c;内部组件宽度可以是固定像素值或百分比。其容器元素不会移动&#xff0c;无论访客屏幕分辨率如何&#xff0c;看到的网页宽度都相同。现代网页设计…

二分查找与二叉树中序遍历——面试算法

目录 二分查找与分治 循环方式 递归方式 元素中有重复的二分查找 基于二分查找的拓展问题 山脉数组的顶峰索引——局部有序 旋转数字中的最小数字 找缺失数字 优化平方根 中序与搜索树 二叉搜索树中搜索特定值 验证二叉搜索树 有序数组转化为二叉搜索树 寻找两个…

字符串——面试考察高频算法题

目录 转换成小写字母 字符串转化为整数 反转相关的问题 反转字符串 k个一组反转 仅仅反转字母 反转字符串里的单词 验证回文串 判断是否互为字符重排 最长公共前缀 字符串压缩问题 转换成小写字母 给你一个字符串 s &#xff0c;将该字符串中的大写字母转换成相同的…

现代复古电影海报品牌徽标设计衬线英文字体安装包 Thick – Retro Vintage Cinematic Font

Thick 是一种大胆的复古字体&#xff0c;专为有影响力的标题和怀旧的视觉效果而设计。其厚实的字体、复古魅力和电影风格使其成为电影海报、产品标签、活动品牌和编辑设计的理想选择。无论您是在引导电影的黄金时代&#xff0c;还是在现代布局中注入复古活力&#xff0c;Thick …

[C++面试] new、delete相关面试点

一、入门 1、说说new与malloc的基本用途 int* p1 (int*)malloc(sizeof(int)); // C风格 int* p2 new int(10); // C风格&#xff0c;初始化为10 new 是 C 中的运算符&#xff0c;用于在堆上动态分配内存并调用对象的构造函数&#xff0c;会自动计算所需内存…

Unity URP管线与HDRP管线对比

1. 渲染架构与底层技术 URP 渲染路径&#xff1a; 前向渲染&#xff08;Forward&#xff09;&#xff1a;默认单Pass前向&#xff0c;支持少量实时光源&#xff08;通常4-8个逐物体&#xff09;。 延迟渲染&#xff08;Deferred&#xff09;&#xff1a;可选但功能简化&#…

JDK8卸载与安装教程(超详细)

JDK8卸载与安装教程&#xff08;超详细&#xff09; 最近学习一个项目&#xff0c;需要使用更高级的JDK&#xff0c;这里记录一下卸载旧版本与安装新版本JDK的过程。 JDK8卸载 以windows10操作系统为例&#xff0c;使用快捷键winR输入cmd&#xff0c;打开控制台窗口&#xf…

python爬虫:DrissionPage实战教程

如果本文章看不懂可以看看上一篇文章&#xff0c;加强自己的基础&#xff1a;爬虫自动化工具&#xff1a;DrissionPage-CSDN博客 案例解析&#xff1a; 前提&#xff1a;我们以ChromiumPage为主&#xff0c;写代码工具使用Pycharm&#xff08;python环境3.9-3.10&#xff09; …

07-01-自考数据结构(20331)- 排序-内部排序知识点

内部排序算法是数据结构核心内容,主要包括插入类(直接插入、希尔)、交换类(冒泡、快速)、选择类(简单选择、堆)、归并和基数五大类排序方法。 知识拓扑 知识点介绍 直接插入排序 定义:将每个待排序元素插入到已排序序列的适当位置 算法步骤: 从第二个元素开始遍历…