【博弈论】极小极大搜索(Minimax Algorithm)与α-β剪枝(Alpha-Beta Pruning)

news2024/11/30 20:37:00

文章目录

  • 一、极大极小搜索(Minimax Algorithm)
  • 二、α-β剪枝(Alpha-Beta Pruning)
  • 三、解题技巧

一、极大极小搜索(Minimax Algorithm)

在零和博弈(有完整信息的,确定的、轮流行动的,两个参与者收益之和为0的博弈)中,双方都希望自己获胜,因此每一步都选择对自己最有利,对对方最不利的做法。

假设我们是参与博弈的一方。我们用静态估计函数 f ( p ) f(p) f(p)来估计博弈双方的态势:

  • 有利于我方的态势: f ( p ) > 0 f(p)>0 f(p)>0
  • 有利于敌方的态势: f ( p ) < 0 f(p)<0 f(p)<0
  • 双方均衡的态势: f ( p ) = 0 f(p)=0 f(p)=0

显然,我方希望 f ( p ) f(p) f(p)最大化,敌方希望 f ( p ) f(p) f(p)最小化。因此称我方为Max方,敌方为Min方。

在Max方的角度,因为是我们自己做决策,我们可以选择任意一种方案,所以我们只需选择收益最大的方案,也就是说每种方案之间是“或”的关系。
而对于Min方而言,因为是敌方做决策,我们无法控制敌方选择哪种策略,假设敌方足够聪明,我们应该假设敌方选择对他最有利的方案,也就是对我们最不利的方案、使我们收益最小的方案,所以对他而言每种方案之间是“与”的关系。

假设我们在进行动态博弈——你一步,我一步,且一方做完决策之后另一方知晓他所做的决策,那么我们可以把双方的行动展开成一棵树——博弈树。
在博弈树中,每个节点代表一种格局,每条边代表Max方或Min方的一步操作。那些下一步该Max方走的节点称为Max节点,下一步该Min方走的节点称为Min节点。

博弈树的特点:
(1) 博弈的初始状态是初始节点(假如Max方为先手,则初始节点为Max节点);
(2) Max节点是“或”节点,Min节点是“与”节点,这两种节点逐层交替出现;
(3) 整个博弈过程始终站在一方(一般为Max方)的立场上。

博弈树上有以下几种节点:

  • 端节点(叶节点)
  • 与节点(Min节点)
  • 或节点(Max节点)

其中,端节点可能是可解节点或非可解节点。使自己一方(Max方)获胜的为可解节点,使对方(Min)方获胜的为非可解节点。

对于当前的格局,我们的目标是找到一个最有利于自己获胜的策略。将当前棋局作为根节点,假设现在该Max方走了,Max方需要枚举根节点的所有子节点,来判断哪个子节点所对应的格局的静态估计函数的数值,那么这个节点对于Max方就最有利,Max方的下一步应该将格局转变为这个子节点的格局。

f ( u ) f(u) f(u)是节点 u u u所对应的格局的静态估计函数数值(也称效用值)。 f ( u ) f(u) f(u)越大,节点 u u u的格局对Max方越有利,对Min方越不利。显然,博弈树每层的节点类型的交替的——与节点、或节点、与节点、或节点、……,因为博弈双方是轮流采取行动的。

现在,要获得节点 u u u f ( u ) f(u) f(u)值,就需要进行极小极大搜索(min-max search)。极小极大搜索是指:在有限的深度范围内,使用深度优先搜索(DFS)算法,利用递归回溯从可能的走法中选择对自己最有利的走法,即让自己的收益最大、对手的收益最小。

博弈树

  • 或节点(Max方):该节点的效用值为所有子节点效用值的最大值。即:若节点 u u u为或节点且 u u u的子节点为 v 1 , v 2 , ⋯   , v k v_1,v_2,\cdots,v_k v1,v2,,vk,则 f ( u ) = max ⁡ 1 ≤ i ≤ k f ( v i ) f(u)=\max\limits_{1\le i\le k}f(v_i) f(u)=1ikmaxf(vi)
  • 与节点(Min方):该节点的效用值为所有子节点效用值的最小值。即:若节点 u u u为与节点且 u u u的子节点为 v 1 , v 2 , ⋯   , v k v_1,v_2,\cdots,v_k v1,v2,,vk,则 f ( u ) = min ⁡ 1 ≤ i ≤ k f ( v i ) f(u)=\min\limits_{1\le i\le k}f(v_i) f(u)=1ikminf(vi)
  • 端节点:这类节点的效用值取决于具体问题。

由此我们可以归纳出极小极大搜索算法(Minimax Algorithm)的一般步骤:
(1) 利用广度优先搜索算法生成Max方当前状态下可猜测的 k k k步博弈树;
(2) 定义静态估计函数,计算端节点的效用值;
(3) 回溯评估:利用极大极小运算自下而上逐层推出各节点的效用值,其中在Max节点取最大值,在Min节点取最小值;
(4) 根据当前状态子节点的效用值做出最优决策,状态转移到子节点的状态,对方变为Max方,回到(1)开始新的搜索。
极大极小搜索过程

(井字棋)给定一个 3 × 3 3\times3 3×3的棋盘,Max方和Min方轮流走棋,每次仅能在空格摆一个自己的棋,自己的棋子三个连成一线即为获胜。
规定估计函数 f ( p ) f(p) f(p)为:

  • 若格局 p p p是Max方获胜,则 f ( p ) = + ∞ f(p)=+\infty f(p)=+
  • 若格局 p p p是Min方获胜,则 f ( p ) = − ∞ f(p)=-\infty f(p)=
  • 若双方均未获胜,则 f ( p ) = f max ⁡ ( p ) − f min ⁡ ( p ) f(p)=f_{\max}(p)-f_{\min}(p) f(p)=fmax(p)fmin(p),其中
    • f max ⁡ ( p ) f_{\max}(p) fmax(p)表示所有空格全放上Max方的棋子后三子一线的总数,
    • f min ⁡ ( p ) f_{\min}(p) fmin(p)表示所有空格全放上Min方的棋子后三子一线的总数。
      f_max-f_min示例
      那么,先手做出第一步决策的过程是这样的:

井字棋
搜索过程中将很多对称的情况合并为一个情况,给出了 k = 2 k=2 k=2步博弈树,并确定最优策略为走中间。

极大极小搜索过程比较简单,但当考虑的步数过多后就会导致博弈树太大、搜索效率变低,需要进行优化。

二、α-β剪枝(Alpha-Beta Pruning)

α-β剪枝是一种优化方法,在博弈树生成的过程中同时计算各节点的估计值及倒推值,通过对估值的上下限进行估计,减去没有用的分支,减少搜索范围,提高效率。

α-β剪枝的基本思想:

  • “或”节点(Max方):取当前子节点中效用值的极大值为该节点效用值的下界,称为α(α≥该极大值),只有当下一个节点的值大于α才会被选择
  • “与”节点(Min方):取当前子节点中效用值的极小值为该节点效用值的上界,称为β(β≤该极小值),只有当下一个节点的值小于α才会被选择

α:目前Max方可以搜索到的最好值,初始值为 − ∞ -\infty
β:目前Min方可以接受的最坏值,初始值为 + ∞ +\infty +

注意:
设节点 u u u为或节点, u u u的效用值为 f ( u ) f(u) f(u) f ( u ) ≥ α f(u)\ge\alpha f(u)α不一定成立。
同理,设 v v v为与节点, v v v的效用值为 f ( v ) f(v) f(v) f ( v ) ≤ β f(v)\le\beta f(v)β也不一定成立。
α,β是中间量,它们的作用是排除对结果没有影响的分支,不能决定最终节点的效用值。

或节点(Max方)α剪枝规则:
设当前节点为 u u u u u u是或节点,则 u u u的子节点都是与节点端节点,设为 v 1 , v 2 , ⋯   , v k v_1,v_2,\cdots,v_k v1,v2,,vk。我们在扫描 v 1 , v 2 , ⋯   , v k v_1,v_2,\cdots,v_k v1,v2,,vk的过程中,若发现 v i v_i vi的β值小于等于任何祖先节点的α值时,则对该节点以下的分支停止搜索,且 v i v_i vi的最终倒推值就是其β值(可能与未加优化的极大极小搜索的结果不同)。

与节点(Min方)β剪枝规则:
设当前节点为 v v v v v v是与节点,则 v v v的子节点都是或节点端节点,设为 u 1 , u 2 , ⋯   , u k u_1,u_2,\cdots,u_k u1,u2,,uk。我们在扫描 u 1 , u 2 , ⋯   , u k u_1,u_2,\cdots,u_k u1,u2,,uk的过程中,若发现 u i u_i ui的α值大于等于任何祖先节点的β值时,则对该节点以下的分支停止搜索,且 u i u_i ui的最终倒推值就是其α值(可能与未加优化的极大极小搜索的结果不同)。

用一个实际的例子来说明:如果你和一个人在下棋,现在轮到你走。现在你有两种选择:走“A”或者走“B”。如果走“A”,那么你的局势会变好。走“B”也比较好,但是如果你走“B”的话,对方可以在两步之内获胜,这对你是非常不利的。也就是说,你考虑到了走“B”的最坏结果,那么其他可能的结果就可以不考虑了(因为对手不傻,肯定会想方设法使你败北),那么你相当于在博弈树中剪掉了“B”的其他情况。最终,因为“A”至少不会让你在两步以内输棋,所以你选择走“A”。(摘自维基百科)

核心思想是:如果存在一个比某一分支更好的走法,那么就不考察这一分支。

α-β剪枝的一个Python实现:

# encoding: GB2312

tree = [ # 博弈树的结构
    [
        [
            [4, 8, 6],
            [1, 9]
        ],
        [
            [5, 8],
            [-1, 2]
        ]
    ],
    [
        [
            [0, 3],
            [-6, 6]
        ],
        [
            [1],
            [0, 9, -7]
        ]
    ]
]

def is_terminal(node): # 判断是否为端节点
    return isinstance(node, int)

infinity = int(1e10) # 无穷大

def alpha_beta(node, alpha, beta, ismax):
    # node: 当前节点
    # ismax: 若为True则当前节点是Max节点,否则为Min节点
    # 当node为Max节点时,alpha为当前节点的α,beta为父节点的β
    # 当node为Min节点时,alpha为父节点的α,beta为当前节点的β
    if is_terminal(node):
        return node # 若当前节点为端节点,直接返回其效用值
    if ismax:
        value = -infinity # 当前节点的效用值
        for child in node:
            value = max(value,
                alpha_beta(child, alpha, beta, False))
                # 当前节点的效用值是子节点效用值的最大值
            alpha = max(alpha, value)
            if value >= beta:
                # 这个子节点的效用值不小于beta,不可能被选择
                break # 进行β剪枝
        return value
    else:
        value = +infinity
        for child in node:
            value = min(value,
                alpha_beta(child, alpha, beta, True))
            beta = min(beta, value)
            if value <= alpha:
                # 这个子节点的效用值不大于alpha,不可能被选择
                break # alpha剪枝
        return value

print(alpha_beta(tree, -infinity, +infinity, True))

三、解题技巧

对于我们的期末考试而言,给你一棵树,请问需要在哪里剪枝。其实我们并不需要搞那些α,β什么的,只需要简单的逻辑就能算出来。

考虑下面的树:
例题
首先我们假设路线是 Q → P → J → A → R Q\to P\to J\to A\to R QPJAR。现在考虑节点 A A A。Min方不选择去 R R R而是选择去其他端节点的条件是什么呢?是其他端节点的效用值小于 f ( R ) = 4 f(R)=4 f(R)=4。但是 f ( S ) = 8 f(S)=8 f(S)=8 f ( T ) = 6 f(T)=6 f(T)=6都大于 4 4 4,所以Min方还是选择去 R R R。所以 f ( A ) = min ⁡ { 4 , 8 , 6 } = 4 f(A)=\min\{4,8,6\}=4 f(A)=min{4,8,6}=4

现在考虑节点 J J J。Max方选择去 B B B而不是去 A A A的条件是什么呢?就是 f ( B ) > f ( A ) = 4 f(B)>f(A)=4 f(B)>f(A)=4。而 f ( B ) = min ⁡ { f ( U ) , f ( V ) } f(B)=\min\{f(U),f(V)\} f(B)=min{f(U),f(V)},所以转化为 min ⁡ { f ( U ) , f ( V ) } > 4 \min\{f(U),f(V)\}>4 min{f(U),f(V)}>4,即 [ f ( U ) > 4 ] ∧ [ f ( V ) > 4 ] [f(U)>4]\land[f(V)>4] [f(U)>4][f(V)>4]这是一个且的关系。现在 f ( U ) = 1 f(U)=1 f(U)=1 f ( U ) > 4 f(U)>4 f(U)>4已经不满足了,所以这个且的关系肯定不成立,不论 f ( V ) f(V) f(V)是多少都不可能成立,所以Max方不会去 B B B。因此要把 V V V剪掉, f ( J ) = f ( A ) = 4 f(J)=f(A)=4 f(J)=f(A)=4

再考虑节点 P P P。Min方去 K K K而不是去 J J J的条件是什么呢?就是 f ( K ) < f ( J ) = 4 f(K)<f(J)=4 f(K)<f(J)=4。而 f ( K ) = max ⁡ { f ( C ) , f ( D ) } f(K)=\max\{f(C),f(D)\} f(K)=max{f(C),f(D)},故转化为 [ f ( C ) < 4 ] ∧ [ f ( D ) < 4 ] [f(C)<4]\land[f(D)<4] [f(C)<4][f(D)<4] f ( C ) = min ⁡ { f ( W ) , f ( X ) } f(C)=\min\{f(W),f(X)\} f(C)=min{f(W),f(X)} f ( D ) = min ⁡ { f ( Y ) , f ( Z ) } f(D)=\min\{f(Y),f(Z)\} f(D)=min{f(Y),f(Z)},又转化为 { [ f ( W ) < 4 ] ∨ [ f ( X ) < 4 ] } ∧ { [ f ( Y ) < 4 ] ∨ [ f ( Z ) < 4 ] } \{[f(W)<4]\lor[f(X)<4]\}\land\{[f(Y)<4]\lor[f(Z)<4]\} {[f(W)<4][f(X)<4]}{[f(Y)<4][f(Z)<4]}其中 f ( W ) = 5 f(W)=5 f(W)=5 f ( X ) = 8 f(X)=8 f(X)=8,都不小于 4 4 4,所以 [ f ( W ) < 4 ] ∨ [ f ( X ) < 4 ] [f(W)<4]\lor[f(X)<4] [f(W)<4][f(X)<4]不成立,那么 f ( K ) < 4 f(K)<4 f(K)<4也不可能成立,所以就没必要考察 D D D了,把 D D D剪掉,并令 f ( P ) = 4 f(P)=4 f(P)=4

再考虑节点 Q Q Q。Max方不去 P P P而是去 N N N的节点是什么呢?是 f ( N ) > f ( P ) = 4 f(N)>f(P)=4 f(N)>f(P)=4。而 f ( N ) = min ⁡ { f ( L ) , f ( M ) } f(N)=\min\{f(L),f(M)\} f(N)=min{f(L),f(M)},故转化为 [ f ( L ) > 4 ] ∧ [ f ( M ) > 4 ] [f(L)>4]\land[f(M)>4] [f(L)>4][f(M)>4] f ( L ) = max ⁡ { f ( E ) , f ( F ) } f(L)=\max\{f(E),f(F)\} f(L)=max{f(E),f(F)} f ( M ) = max ⁡ { f ( G ) , f ( H ) } f(M)=\max\{f(G),f(H)\} f(M)=max{f(G),f(H)},故转化为 { [ f ( E ) > 4 ] ∨ [ f ( F ) > 4 ] } ∧ { [ f ( G ) > 4 ] ∨ [ f ( H ) > 4 ] } \{[f(E)>4]\lor[f(F)>4]\}\land\{[f(G)>4]\lor[f(H)>4]\} {[f(E)>4][f(F)>4]}{[f(G)>4][f(H)>4]} f ( E ) = min ⁡ { f ( Δ ) , f ( Ω ) } f(E)=\min\{f(\Delta),f(\Omega)\} f(E)=min{f(Δ),f(Ω)} f ( F ) = min ⁡ { f ( Ψ ) , f ( Σ ) } f(F)=\min\{f(\Psi),f(\Sigma)\} f(F)=min{f(Ψ),f(Σ)} f ( G ) = f ( Π ) f(G)=f(\Pi) f(G)=f(Π) f ( H ) = min ⁡ { f ( Φ ) , f ( Γ ) , f ( Ξ ) } f(H)=\min\{f(\Phi),f(\Gamma),f(\Xi)\} f(H)=min{f(Φ),f(Γ),f(Ξ)},故转化为 { [ f ( Δ ) > 4 ∧ f ( Ω ) > 4 ] ∨ [ f ( Ψ ) > 4 ∧ f ( Σ ) > 4 ] } ∧ { [ f ( Π ) > 4 ] ∨ [ f ( Φ ) > 4 ∧ f ( Γ ) > 4 ∧ f ( Ξ ) > 4 ] } \{[f(\Delta)>4\land f(\Omega)>4]\lor[f(\Psi)>4\land f(\Sigma)>4]\}\land\{[f(\Pi)>4]\lor[f(\Phi)>4\land f(\Gamma)>4\land f(\Xi)>4]\} {[f(Δ)>4f(Ω)>4][f(Ψ)>4f(Σ)>4]}{[f(Π)>4][f(Φ)>4f(Γ)>4f(Ξ)>4]}观察这个式子。这个式子成立,需要 { [ f ( Δ ) > 4 ∧ f ( Ω ) > 4 ] ∨ [ f ( Ψ ) > 4 ∧ f ( Σ ) > 4 ] } \{[f(\Delta)>4\land f(\Omega)>4]\lor[f(\Psi)>4\land f(\Sigma)>4]\} {[f(Δ)>4f(Ω)>4][f(Ψ)>4f(Σ)>4]} { [ f ( Π ) > 4 ] ∨ [ f ( Φ ) > 4 ∧ f ( Γ ) > 4 ∧ f ( Ξ ) > 4 ] } \{[f(\Pi)>4]\lor[f(\Phi)>4\land f(\Gamma)>4\land f(\Xi)>4]\} {[f(Π)>4][f(Φ)>4f(Γ)>4f(Ξ)>4]}都成立。而前者成立,只需使 [ f ( Δ ) > 4 ∧ f ( Ω ) > 4 ] [f(\Delta)>4\land f(\Omega)>4] [f(Δ)>4f(Ω)>4] [ f ( Ψ ) > 4 ∧ f ( Σ ) > 4 ] [f(\Psi)>4\land f(\Sigma)>4] [f(Ψ)>4f(Σ)>4]成立。
现在 f ( Δ ) = 0 f(\Delta)=0 f(Δ)=0不大于 4 4 4,故 [ f ( Δ ) > 4 ∧ f ( Ω ) > 4 ] [f(\Delta)>4\land f(\Omega)>4] [f(Δ)>4f(Ω)>4]不成立,不论 f ( Ω ) f(\Omega) f(Ω)为何值,因此剪掉 Ω \Omega Ω。而 f ( Ψ ) = − 6 f(\Psi)=-6 f(Ψ)=6也不大与4,故 [ f ( Ψ ) > 4 ∧ f ( Σ ) > 4 ] [f(\Psi)>4\land f(\Sigma)>4] [f(Ψ)>4f(Σ)>4]不成立,不论 f ( Σ ) f(\Sigma) f(Σ)为和值,因此剪掉 Σ \Sigma Σ。这意味着, { [ f ( Δ ) > 4 ∧ f ( Ω ) > 4 ] ∨ [ f ( Ψ ) > 4 ∧ f ( Σ ) > 4 ] } \{[f(\Delta)>4\land f(\Omega)>4]\lor[f(\Psi)>4\land f(\Sigma)>4]\} {[f(Δ)>4f(Ω)>4][f(Ψ)>4f(Σ)>4]}不成立。那么 f ( N ) > f ( P ) f(N)>f(P) f(N)>f(P)的条件就已经不能满足了, N N N这边彻底没戏了,所以把剩下没去过的的都剪掉——也就是把 M M M剪掉。最后, f ( Q ) = f ( P ) = 4 f(Q)=f(P)=4 f(Q)=f(P)=4,也就是说在 Q Q Q状态下Max方选择去 P P P

综上,要剪掉的节点是 V , D , Ω , Σ , M V,D,\Omega,\Sigma,M V,D,Ω,Σ,M。如下图所示:
剪枝结果

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

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

相关文章

steam搬砖项目月入过万靠谱吗

大家好&#xff0c;我是阿阳 什么是国外steam游戏装备汇率差项目 一、项目介绍 其实&#xff0c;Steam就是一个美国的游戏平台&#xff0c;搬砖主要是搬的一款火遍全球的游戏CSGO的装备和饰品。CS听说过吧&#xff0c;这款游戏就是CS的一个系列。&#xff08;通俗易懂的理解就…

【C++数据结构】性能测量

性能测量 4.1 引言 容易计算内存的需求大小&#xff0c;只要知道编译后的代码和数据空间的大小就可以了&#xff1b; 数据空间的大小取决于用户所要解决的问题实例的大小。 要确定程序运行时间&#xff0c;需要通过实验来测量。 程序性能不仅依赖操作类型和数量&#xff0c…

Excel逆向查询的多种方法,赶快学起来

关于匹配查询&#xff0c;我们平时用的做多的就是VLOOKUP函数了&#xff0c;但VLOOKUP函数只能正向查找&#xff0c;不能逆向查询。 像是下面这种情况就不可以&#xff1a; &#xff08;现在我们想用编码去匹配书名&#xff09; 如果在不改变原表格结构的基础上查找出书目编码…

当MySQL和java通过媒婆navicate谈上了恋爱 ------ MySQL的安装和Java的连接

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 **收录于专栏 数据库 ⭐当MySQL和java通过媒婆navicate谈上了恋爱⭐ 文章目录⭐当MySQL和java通过媒婆navicate谈上了恋爱…

vue组件库发布到npm

修改项目的信息 在package.json文件中&#xff1a; 修改Readme文件的信息 注册npm 账号 指路官网 vscode终端登录npm 执行 npm login 输入用户名&#xff0c;密码&#xff0c;邮箱&#xff0c;邮箱验证码 如下图 执行 npm publish 如下图 出现的问题 npm ERR! code E403 …

CSAPP Lab6:Malloc

文章目录一、实验简介二、隐式链表实现基本宏块的相关函数mm_initmm_mallocmm_freemm_reallocextend_heapblk_mergeblk_findblk_split使用下次匹配三、显式链表实现四、分离适配五、完整代码隐式链表显式链表课本实现一、实验简介 实现一个动态内存分配器。 tar xvf mallocla…

Linux 应急响应命令总结,收藏版

系统排查 系统基本信息 CPU 信息 CPU 信息&#xff1a;lscpu 操作系统信息 操作系统信息&#xff1a;uname -a 操作系统信息&#xff1a;cat /proc/version 模块信息 模块信息&#xff1a;lsmod 账户信息 系统所有账户 系统所有账户&#xff1a;cat /etc/passwd 超级权限账户 超…

3D-SKIPDENSESEG医学图像分割

蓝色三角、黄色三角、红色三角相对应。 得到第三个feature map&#xff0c;反卷积会恢复到原来的尺寸 Dense block&#xff0c;通道增加了 Transition&#xff0c;池化 用正则表达式把里面的h5文件匹配一下吧 os.path.join()把两个部分的路径拼一下 root_path —data_train *.…

[kubernetes]-k8s开启swap

导语&#xff1a;记录k8s开启swap后先后做的调整 测试版本 k8s1.20版本 使用参数--fail-swap-onfalse Environment"KUBELET_EXTRA_ARGS--fail-swap-onfalse"使用测试 可以开启swap不报错 但是pod使用swap不太理想。且无法实现在使用swap的时候限制pod的内存。会造…

【Java面试】List接口

文章目录Iterator 和 ListIterator 有什么区别&#xff1f;遍历一个 List 有哪些不同的方式&#xff1f;每种方法的实现原理是什么&#xff1f;Java中List 遍历的最佳实践是什么&#xff1f;说一下 ArrayList 的优缺点如何实现数组和 List 之间的转换&#xff1f;ArrayList 和 …

M4 tm4c1294单片机软件调式总结

1&#xff0c;框架图&#xff1a; 调式基本方法&#xff1a; &#xff08;1&#xff09;加串口打印初始化&#xff0c;单步跟踪查看&#xff0c;类似gdb的单步&#xff1b; &#xff08;2&#xff09;打印命令行&#xff0c;重点参数添加命令行打印; &#xff08;3&#xff…

Redis 的相关基础知识

【一】 Redis 中默认的端口号为什么是6379 图中的人名为 Alessia Merz &#xff0c;其中的 Merz 对应的九键输入法按出来的就是6379 【二】 Redis 默认的数据库 Redis 中默认使用的是16个数据库&#xff0c;类似数组下标从0开始&#xff0c;初始默认使用0号数据库 【三】 Redis…

vscode搭建Verilog HDL开发环境

工欲善其事&#xff0c;必先利其器。应该没有多少人会使用Quartus和vivado这些软件自带的编辑器吧&#xff0c;原因在于这些编辑器效率很低&#xff0c;Verilog HDL代码格式比较固定&#xff0c;通常可以利用代码片段补全加快书写。基本上代码写完之后才会打开Quartus或者vivad…

一文带你了解Spring中的事务管理

文章目录前言一、事务的基础概念二、spring中事务的使用声明式事务编程式事务如何选择事务方式三、spring中事务管理实现原理前言 本文将涉及以下知识点&#xff1a; 事务的基础概念spring当中事务的使用spring当中事务管理的实现原理 一、事务的基础概念 事务&#xff08;T…

python画图

python画图1.使用matplotlib画图2.使用pyecharts画图2.x pyecharts的三种图片渲染工具2.x.1 snapshot_selenium2.x.2 snapshot_phantomjs2.x.3 snapshot_pyppeteer1.使用matplotlib画图 2.使用pyecharts画图 pyecharts是一款将python与echarts结合的强大的数据可视化工具&…

阿里云服务器安装tomcat

一、前置条件 安装tomcat需要先安装jdk&#xff0c;所以没有安装jdk同学&#xff0c;详见参考文章或者此文章 二、Linux上安装tomcat 1. 下载Apache tomcat tomcat官网下载地址 在左边&#xff0c;可以选择下载各种版本的tomcat。根据服务器操作系统选择下载。Linux操作系统…

第七章TCP/IP——ARP网络攻击与欺骗

个人简介&#xff1a;云计算网络运维专业人员&#xff0c;了解运维知识&#xff0c;掌握TCP/IP协议&#xff0c;每天分享网络运维知识与技能。个人爱好: 编程&#xff0c;打篮球&#xff0c;计算机知识个人名言&#xff1a;海不辞水&#xff0c;故能成其大&#xff1b;山不辞石…

分布式文件系统和对象存储魔力象限,右上角都有谁?

自Gartner 首次发布      分布式文件系统和      对象存储魔力象限以来      戴尔科技集团      就牢牢位居领导者象限      今年也不例外      恭喜      连续第七年获评领导者!    对于入选本年度的魔力象限领导者,我们感到十分荣幸。我们相…

docker安装jenkins最新版

前言 使用的是centos7的linux系统&#xff0c; 检查docker 是否开启网络 如果没有开启网络会报错:WARNING: IPv4 forwarding is disabled. Networking will not work. 检查网络状态 sysctl net.ipv4.ip_forward如果返回为“net.ipv4.ip_forward 1”则表示网络转发正常&am…

1534_TriCore编译器Tasking使用_汇编语言语法以及标识符

全部学习汇总&#xff1a; GreyZhang/TriCore_Tasking_Compiler_Skills: Some skills for Tasking compiler on AURIX platform. Happy hacking! (github.com) 1. 如同C语言&#xff0c;汇编语言也可以续行而且采用了同样的续行符号。不过&#xff0c;我遇到的汇编一直都是很统…