Python论文复现:VMD之自适应选择分解模态数K值

news2024/11/23 8:16:25

Python论文复现:《基于稀疏指标的优化变分模态分解方法》

  信号分解方法中,虽然变分模态分解(Variational Mode Decomposition, VMD)有严格的数学推导,能有效抑制端点效应、模态混叠等问题,但其分解模态数需预设。然而实际工程中,真实信号的频谱较为嘈杂且频带个数较难确定,一般观察分析具体信号的频谱图设置合理的模态数。
  相比人工选取方法,自适应选取方法通常定义分解好坏的指标,进一步确定该指标下的最佳模态数。考虑到《基于稀疏指标的优化变分模态分解方法》从IMF频带稀疏性(VMD分解的初衷)的角度寻优,且稀疏指标有严格的理论支撑《信号的稀疏性分析》,故本文对其进行复现。

vmd分解

  VMD 假定所有分量都是集中在各自中心频率附近的窄带信号,根据分量窄带条件建立约束优化问题,从而估计信号分量的中心频率以及重构相应分量。具体原理不再赘述,由于之前有粉丝不知道我用的什么代码,故在此公开,可单独放在vmdpy.py文件,后面的主程序Auto_VMD.py会调用:

import numpy as np

def  VMD(f, alpha, tau, K, DC, init, tol):
    """
    u,u_hat,omega = VMD(f, alpha, tau, K, DC, init, tol)
    Variational mode decomposition
    Python implementation by Vinícius Rezende Carvalho - vrcarva@gmail.com
    code based on Dominique Zosso's MATLAB code, available at:
    https://www.mathworks.com/matlabcentral/fileexchange/44765-variational-mode-decomposition
    Original paper:
    Dragomiretskiy, K. and Zosso, D. (2014) ‘Variational Mode Decomposition’, 
    IEEE Transactions on Signal Processing, 62(3), pp. 531–544. doi: 10.1109/TSP.2013.2288675.
    
    
    Input and Parameters:
    ---------------------
    f       - the time domain signal (1D) to be decomposed
    alpha   - the balancing parameter of the data-fidelity constraint
    tau     - time-step of the dual ascent ( pick 0 for noise-slack )
    K       - the number of modes to be recovered
    DC      - true if the first mode is put and kept at DC (0-freq)
    init    - 0 = all omegas start at 0
                       1 = all omegas start uniformly distributed
                      2 = all omegas initialized randomly
    tol     - tolerance of convergence criterion; typically around 1e-6

    Output:
    -------
    u       - the collection of decomposed modes
    u_hat   - spectra of the modes
    omega   - estimated mode center-frequencies
    """
    
    if len(f)%2:
       f = f[:-1]

    # Period and sampling frequency of input signal
    fs = 1./len(f)
    
    ltemp = len(f)//2 
    fMirr =  np.append(np.flip(f[:ltemp],axis = 0),f)  
    fMirr = np.append(fMirr,np.flip(f[-ltemp:],axis = 0))

    # Time Domain 0 to T (of mirrored signal)
    T = len(fMirr)
    t = np.arange(1,T+1)/T  
    
    # Spectral Domain discretization
    freqs = t-0.5-(1/T)

    # Maximum number of iterations (if not converged yet, then it won't anyway)
    Niter = 500
    # For future generalizations: individual alpha for each mode
    Alpha = alpha*np.ones(K)
    
    # Construct and center f_hat
    f_hat = np.fft.fftshift((np.fft.fft(fMirr)))
    f_hat_plus = np.copy(f_hat) #copy f_hat
    f_hat_plus[:T//2] = 0

    # Initialization of omega_k
    omega_plus = np.zeros([Niter, K])


    if init == 1:
        for i in range(K):
            omega_plus[0,i] = (0.5/K)*(i)
    elif init == 2:
        omega_plus[0,:] = np.sort(np.exp(np.log(fs) + (np.log(0.5)-np.log(fs))*np.random.rand(1,K)))
    else:
        omega_plus[0,:] = 0
            
    # if DC mode imposed, set its omega to 0
    if DC:
        omega_plus[0,0] = 0
    
    # start with empty dual variables
    lambda_hat = np.zeros([Niter, len(freqs)], dtype = complex)
    
    # other inits
    uDiff = tol+np.spacing(1) # update step
    n = 0 # loop counter
    sum_uk = 0 # accumulator
    # matrix keeping track of every iterant // could be discarded for mem
    u_hat_plus = np.zeros([Niter, len(freqs), K],dtype=complex)    

    #*** Main loop for iterative updates***

    while ( uDiff > tol and  n < Niter-1 ): # not converged and below iterations limit
        # update first mode accumulator
        k = 0
        sum_uk = u_hat_plus[n,:,K-1] + sum_uk - u_hat_plus[n,:,0]
        
        # update spectrum of first mode through Wiener filter of residuals
        u_hat_plus[n+1,:,k] = (f_hat_plus - sum_uk - lambda_hat[n,:]/2)/(1.+Alpha[k]*(freqs - omega_plus[n,k])**2)
        
        # update first omega if not held at 0
        if not(DC):
            omega_plus[n+1,k] = np.dot(freqs[T//2:T],(abs(u_hat_plus[n+1, T//2:T, k])**2))/np.sum(abs(u_hat_plus[n+1,T//2:T,k])**2)

        # update of any other mode
        for k in np.arange(1,K):
            #accumulator
            sum_uk = u_hat_plus[n+1,:,k-1] + sum_uk - u_hat_plus[n,:,k]
            # mode spectrum
            u_hat_plus[n+1,:,k] = (f_hat_plus - sum_uk - lambda_hat[n,:]/2)/(1+Alpha[k]*(freqs - omega_plus[n,k])**2)
            # center frequencies
            omega_plus[n+1,k] = np.dot(freqs[T//2:T],(abs(u_hat_plus[n+1, T//2:T, k])**2))/np.sum(abs(u_hat_plus[n+1,T//2:T,k])**2)
            
        # Dual ascent
        lambda_hat[n+1,:] = lambda_hat[n,:] + tau*(np.sum(u_hat_plus[n+1,:,:],axis = 1) - f_hat_plus)
        
        # loop counter
        n = n+1
        
        # converged yet?
        uDiff = np.spacing(1)
        for i in range(K):
            uDiff = uDiff + (1/T)*np.dot((u_hat_plus[n,:,i]-u_hat_plus[n-1,:,i]),np.conj((u_hat_plus[n,:,i]-u_hat_plus[n-1,:,i])))

        uDiff = np.abs(uDiff)        
            
    #Postprocessing and cleanup
    
    #discard empty space if converged early
    Niter = np.min([Niter,n])
    omega = omega_plus[:Niter,:]
    
    idxs = np.flip(np.arange(1,T//2+1),axis = 0)
    # Signal reconstruction
    u_hat = np.zeros([T, K],dtype = complex)
    u_hat[T//2:T,:] = u_hat_plus[Niter-1,T//2:T,:]
    u_hat[idxs,:] = np.conj(u_hat_plus[Niter-1,T//2:T,:])
    u_hat[0,:] = np.conj(u_hat[-1,:])    
    
    u = np.zeros([K,len(t)])
    for k in range(K):
        u[k,:] = np.real(np.fft.ifft(np.fft.ifftshift(u_hat[:,k])))
        
    # remove mirror part
    u = u[:,T//4:3*T//4]

    # recompute spectrum
    u_hat = np.zeros([u.shape[1],K],dtype = complex)
    for k in range(K):
        u_hat[:,k]=np.fft.fftshift(np.fft.fft(u[k,:]))

    return u, u_hat, omega

边际谱

  论文作者是在每个IMF的边际谱上计算稀疏化指标,而边际谱是希尔伯特谱在时间维度上的积分。笔者首先将求边际谱的代码函数化,由于需要进行希尔伯特变换,本代码需要调用PyEMD与scipy库。
h ( z ) = ∫ 0 T H ( t , f ) d t   h(z) = \int_0^T H(t,f)dt\ h(z)=0TH(t,f)dt 

from PyEMD import Visualisation
from scipy.signal import hilbert

#求窄带信号的边际谱
def mspect(Fs,signal,draw=1):
    fmin,fmax=0,Fs/2
    size=len(signal)//2
    df=(fmax-fmin)/(size-1)
    t=np.arange(0,len(signal)/Fs,1/Fs)
    vis = Visualisation()
    #希尔伯特变化
    signal=signal.reshape(1,-1)
    #求瞬时频率
    freqs = abs(vis._calc_inst_freq(signal, t, order=False, alpha=None))
    #求瞬时幅值
    amp= abs(hilbert(signal))
    #去掉为1的维度
    freqs=np.squeeze(freqs)
    amp=np.squeeze(amp)
    result=np.zeros(size)
    for i,j in zip(freqs,amp):
        if i>=fmin and i<=fmax:
            result[round((i-fmin)/df)]+=j
    
    f=np.arange(fmin,size*df,df)
    #可视化
    if draw==1:                           #可视化
        plt.figure()
        plt.rcParams['font.sans-serif']='Times New Roman'
        plt.plot(f,result)
        plt.xlabel('f/HZ',fontsize=16)
        plt.ylabel('amplitude',fontsize=16)
        plt.title('Marginal Spectrum',fontsize=20)
    
    return f,result

基于稀疏指标自适应寻找最佳分解K值

  总结论文思路如下:
  1)初始化VMD参数,惩罚因子 α \alpha α为3000,拉格朗日乘子更新因子为0.01,分解模态数K为2;
  2)VMD分解并计算各IMF的边际谱,计算各IMF的稀疏度(考虑了能量权值因子);

   S i = max ⁡ { M S i } max ⁡ { max ⁡ { M S 1 } ⋯ max ⁡ { M S k } } { E ( M S i 2 ) / [ E ( M S i ) ] 2 } {S}_{i}=\frac{\max \left\{ M{{S}_{i}} \right\}}{\max \left\{ \max \left\{ M{{S}_{1}} \right\}\cdots \max \left\{ M{{S}_{k}} \right\} \right\}}\left\{ E(MS_{i}^{2})/{{\left[ E(M{{S}_{i}}) \right]}^{2}} \right\} Si=max{max{MS1}max{MSk}}max{MSi}{E(MSi2)/[E(MSi)]2}

  3)取各IMF边际谱稀疏度作为该分解模态数K下的整体稀疏度;

   S K = 1 K ∑ i = 1 K S i {{S}_{K}}=\frac{1}{K}\sum\limits_{i=1}^{K}{{{S}_{i}}} SK=K1i=1KSi

  4)当 S K < S K − 1 ( K > 2 ) {{S}_{K}}<{{S}_{K-1}}(K>2) SK<SK1(K>2)时,选取最佳分解模态数为K-1,进入步骤5),反之令 K = K + 1 K=K+1 K=K+1回到步骤2)继续迭代;
  5)采用最佳的分解模态数进行VMD分解。
  该文在确定最佳分解模态数时是选取第一个极大值点,或者稀疏度随K单调递减时,选取第一个点2。然而,实际信号极值点可能不为最大值点,且若出现先递减后递增(稀疏度大于K=2)的情况时,该方法无法取到最佳K值。
  本人对选取方法做了一点小改变,即:预设最大K值(依据信号复杂度设置,本人取10),计算K从2至最大值期间的稀疏度,取最大稀疏度对应的K值作为最佳分解模态数。主函数Auto_VMD.py具体代码如下(画时频图的代码,我之前的博文有):

from vmdpy import VMD
import matplotlib.pyplot as plt
import numpy as np
from PyEMD import Visualisation
from scipy.signal import hilbert

#求窄带信号的边际谱
def mspect(Fs,signal,draw=1):
    fmin,fmax=0,Fs/2
    size=len(signal)//2
    df=(fmax-fmin)/(size-1)
    t=np.arange(0,len(signal)/Fs,1/Fs)
    vis = Visualisation()
    #希尔伯特变化
    signal=signal.reshape(1,-1)
    #求瞬时频率
    freqs = abs(vis._calc_inst_freq(signal, t, order=False, alpha=None))
    #求瞬时幅值
    amp= abs(hilbert(signal))
    #去掉为1的维度
    freqs=np.squeeze(freqs)
    amp=np.squeeze(amp)
    result=np.zeros(size)
    for i,j in zip(freqs,amp):
        if i>=fmin and i<=fmax:
            result[round((i-fmin)/df)]+=j
    
    f=np.arange(fmin,size*df,df)
    #可视化
    if draw==1:                           #可视化
        plt.figure()
        plt.rcParams['font.sans-serif']='Times New Roman'
        plt.plot(f,result)
        plt.xlabel('f/HZ',fontsize=16)
        plt.ylabel('amplitude',fontsize=16)
        plt.title('Marginal Spectrum',fontsize=20)
    
    return f,result


#基于稀疏指标自适应确定K值的VMD分解   
def Auto_VMD_main(signal,Fs,draw=1,maxK=10):
    
    #vmd参数设置
    alpha = 3000       # moderate bandwidth constraint   2000
    tau = 0.            # noise-tolerance (no strict fidelity enforcement)
    DC = 0             # no DC part imposed
    init = 1           # initialize omegas uniformly
    tol = 1e-7
    
    #寻找最佳K
    S=[[],[]]
    flag,idx=-2,2
    for K in range(2,maxK+1):
        IMFs,_,_=VMD(signal, alpha, tau, K, DC, init, tol)                                    #分解信号
        M_spect=[]
        max_M=[]
        for i in range(len(IMFs)):
            # _,_=fftlw(Fs,IMFs[i,:],1)
            _,M=mspect(Fs,IMFs[i,:],0)
            max_M.append(max(M))
            temp=np.mean(M**2)/(np.mean(M)**2)
            M_spect.append(temp)
        
        max_M=max_M/max(max_M)
        S_index=np.mean(max_M*M_spect)
        if S_index>flag:
            flag=S_index
            idx=K
        S[0].append(K)
        S[1].append(S_index)
 
    
    #用最佳K值分解信号
    IMFs, _, _ = VMD(signal, alpha, tau, idx, DC, init, tol)
    #可视化寻优过程与最终结果
    if draw==1:
        plt.figure()
        plt.rcParams['font.sans-serif']='Times New Roman'
        plt.plot(S[0],S[1])
        plt.scatter([idx],[flag],c='r',marker='*')
        plt.xlabel('K',fontsize=16)
        plt.ylabel('Sparse index',fontsize=16)
        plt.title('Optimization Process',fontsize=20)
        
        plt.figure()
        for i in range(len(IMFs)):
            plt.subplot(len(IMFs),1,i+1)
            plt.plot(t,IMFs[i])
            if i==0:
                plt.rcParams['font.sans-serif']='Times New Roman'
                plt.title('Decomposition Signal',fontsize=14)
            elif i==len(IMFs)-1:
                plt.rcParams['font.sans-serif']='Times New Roman'
                plt.xlabel('Time/s')
    return IMFs
    
if __name__=='__main__':
      #仿真信号1
      Fs=6000   #采样频率
      t = np.arange(0, 1.0, 1.0 / Fs)
      signal=np.multiply(np.sin(2*np.pi*100*t),(np.cos(2*np.pi*1000*t)+np.cos(2*np.pi*1500*t)+np.cos(2*np.pi*2000*t)))
      
      # #仿真信号2
      # Fs=1000   #采样频率
      # t = np.arange(0, 1.0, 1.0 / Fs)
      # f1,f2,f3 = 100,200,300
      # signal = np.piecewise(t, [t < 1, t < 0.6, t < 0.3],
      #                     [lambda t: np.sin(2 * np.pi * f1 * t), lambda t: np.sin(2 * np.pi * f2 * t),
      #                       lambda t: np.sin(2 * np.pi * f3 * t)])    
      # #仿真信号3
      # Fs=1000   #采样频率
      # t = np.arange(0, 1.0, 1.0 / Fs)
      # f1,f2,f3 = 100,200,300
      # signal = 3*np.sin(2*np.pi*f1*t)+6*np.sin(2*np.pi*f2*t)+5*np.sin(2*np.pi*f3*t) 
      
      IMFs=Auto_VMD_main(signal,Fs,draw=1,maxK=10)
    
      from eemd_hht import hhtlw
      tt,ff,c_matrix=hhtlw(IMFs,t,f_range=[0,Fs/2],t_range=[0,t[-1]],ft_size=[128,128])     #画希尔伯特谱

仿真信号分析

  仿真如下信号验证,采样频率为6000 Hz,信号时间长度为1 s:

   y = sin ⁡ ( 2 π f 1 t ) ∗ [ cos ⁡ ( 2 π f 2 t ) + cos ⁡ ( 2 π f 3 t ) + cos ⁡ ( 2 π f 4 t ) ] y=\sin \left( 2\pi {{f}_{1}}t \right)*\left[ \cos \left( 2\pi {{f}_{2}}t \right)+\cos \left( 2\pi {{f}_{3}}t \right)+\cos \left( 2\pi {{f}_{4}}t \right) \right] y=sin(2πf1t)[cos(2πf2t)+cos(2πf3t)+cos(2πf4t)]

   f 1 , f 2 , f 3 , f 4 = 100 , 1000 , 1500 , 2000 {{f}_{1}},{{f}_{2}},{{f}_{3}},{{f}_{4}}=100,1000,1500,2000 f1,f2,f3,f4=100,1000,1500,2000
  由于傅里叶变化的思想是采用标准正弦波来拟合信号,而本文信号由于出现正弦波相乘,经过三角函数积化和差可转换为6个正弦波,故原始信号频谱包含6个频率成分。
   y = 1 2 sin ⁡ ( 2 π ( f 1 + f 2 ) t ) + sin ⁡ ( 2 π ( f 1 − f 2 ) t ) + sin ⁡ ( 2 π ( f 1 + f 3 ) t ) + y=\frac{1}{2}\sin \left( 2\pi \left( {{f}_{1}}+{{f}_{2}} \right)t \right)+\sin \left( 2\pi \left( {{f}_{1}}-{{f}_{2}} \right)t \right)+\sin \left( 2\pi \left( {{f}_{1}}+{{f}_{3}} \right)t \right)+ y=21sin(2π(f1+f2)t)+sin(2π(f1f2)t)+sin(2π(f1+f3)t)+
     sin ⁡ ( 2 π ( f 1 − f 3 ) t ) + sin ⁡ ( 2 π ( f 1 + f 4 ) t ) + sin ⁡ ( 2 π ( f 1 − f 4 ) t ) \sin \left( 2\pi \left( {{f}_{1}}-{{f}_{3}} \right)t \right)+\sin \left( 2\pi \left( {{f}_{1}}+{{f}_{4}} \right)t \right)+\sin \left( 2\pi \left( {{f}_{1}}-{{f}_{4}} \right)t \right) sin(2π(f1f3)t)+sin(2π(f1+f4)t)+sin(2π(f1f4)t)
  原始信号的时域图与频谱图如下:
在这里插入图片描述

  采用稀疏度自动寻找最佳K值为6,寻优过程以及分解后的时频图如下:
在这里插入图片描述

转子试验台数据分析

  采用转子试验台数据(无故障状态)分析,采样频率为30720 Hz,样本长度为1024,原始时域及频域图如下,大致可以分为6-8个频带,图中圈圈为本方法确定的最佳模态分量数下各IMF的频带中心,基本符合信号包含的窄带个数:
在这里插入图片描述  采用稀疏度自动寻找最佳K值为6,寻优过程以及分解后的时频图如下:
在这里插入图片描述  各IMF的边际谱如下,基本对应频谱中的各频率成分:
在这里插入图片描述

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

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

相关文章

Docker笔记9 | Docker中网络功能知识梳理和了解

9 | Docker中网络功能知识梳理和了解 1 外部访问容器1.1 访问方式1.2 映射所有接口地址1.3 映射到指定地址的指定端口1.4 映射到指定地址的任意端口1.5 查看映射端口配置 2 容器互联2.1 新建网络2.2 连接容器 3 配置DNS 简单说&#xff1a;Docker 允许通过外部访问容器或容器互…

Python中的全局变量与局部变量

1 定义 全局变量指的是在整个python文件中定义的变量&#xff0c;而局部变量是在函数内部定义的变量。 a 1 def yang_func():b 2 从以上代码中可以看出&#xff0c;变量a是全局变量&#xff0c;变量b是定义在yang_func()函数的内部&#xff0c;因此b是局部变量。 2 使用范…

云原生之部署Docker管理面板SimpleDocker

云原生之部署Docker管理面板SimpleDocker 一、SimpleDocker介绍1. SimpleDocker简介2. SimpleDocker特点 二、本地环境介绍1. 本地环境规划2. 本次实践介绍 三、本地环境检查1.检查Docker服务状态2. 检查Docker版本3.检查docker compose 版本 四、下载SimpleDocker镜像五、部署…

【GD32开发】一、GD32F103 TIMER0 PWM死区时间计算

一、PWM死区时间如何计算&#xff1f; GD32F103的数据手册关于死区时间控制的公式如上图。 DTCFG的值为 设置死区结构体的寄存器值 tDTS_CK的值为 系统时钟的时钟周期。 如&#xff1a;GD32F103的系统时钟是108Mhz, 则tDTS_CK 1/108Mhz 9.26ns。( stm32的这个值跟定时器的…

如何从 Android 内部存储中恢复已删除的照片?

我们使用手机录制的照片和视频通常存储在手机的内存中。我们存储它们以记住我们生活的美丽。然而&#xff0c;在管理这些照片的过程中&#xff0c;一些用户却发现自己不小心删除了这些照片&#xff0c;这很尴尬。 如果您的 Android 设备遇到过此类问题&#xff0c;那么您来对地…

SpringBoot日记本系统小白部署指南

哈喽&#xff0c;大家好&#xff0c;我是兔哥。 之前写的SpringBoot日记本系统备受好评&#xff0c;考虑到还是有很多小伙伴不会部署&#xff0c;所以这一篇文章就单独来讲一下部署步骤吧。 需要资源 idea&#xff08;破不破解都行&#xff09; MySQL&#xff08;最好5.7以…

redis高级篇一

redis 是多线程还是单线程 redis单线程的操作 主要是指redis的网路IO和键值对的读写是由一个线程来完成的&#xff0c;Redis在处理客户端的请求时&#xff0c;包括获取&#xff08;socket 读&#xff09;&#xff0c;解析&#xff0c;执行&#xff0c;内容返回&#xff08;so…

linux(动静态库)

目录&#xff1a; 1.文件时间的概念 2.动态库和静态库 3.如何制作动静态库 -------------------------------------------------------------------------------------------------------------------------------- 1.文件时间的概念 我们现在就开始学习这三个时间分别表示了什…

AI百科:一个开启人工智能时代的综合性平台

无论是人工智能的快速发展还是AI技术在各个领域的广泛应用&#xff0c;都让我们对智能未来充满了期待和好奇。随着科技的进步&#xff0c;发现了一个好网站&#xff0c;一个集合了丰富AI工具和产品介绍的综合性网站—— AI百科。 在人工智能&#xff08;AI&#xff09;领域的快…

【实用工具 - vscode】实现Linux服务器的远程操控

&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f; &#x1f36d;&#x1f36d;系列专栏&#xff1a;【计算机工具】 ✒️✒️本篇内容&#xff1a;vscode的下载安装&#xff0c;常见插件及详细安装方法&#xff0c;插件停用及卸载&#xff0c;vscode快捷键 …

如何将文件制作成二维码

日常生活和工作中&#xff0c;为了让大家更方便的查阅文件&#xff0c;可将文件生成二维码&#xff0c;打印在通知书、会议要求&#xff0c;或是直接用“二维码”分享。通过草料二维码可以将多种类型的文件快速生成文件二维码&#xff0c;微信扫码查看即可查看和下载文件。 ● …

项目风险管理的四个阶段,你了解多少?

项目风险管理是项目管理的一部分&#xff0c;目的是保证项目总目标的实现。 风险管理包括风险识别、风险估计、风险解决和风险监控。风险管理贯穿在项目中的每个环节&#xff0c;在项目的生命周期中监控风险是非常重要的手段。 风险管理包含四个阶段&#xff1a; 1、风险识别…

从需求分析到功能扩展:打破瓶颈,构建智能采购管理软件

在当今快速发展的商业环境下&#xff0c;采购管理已成为企业发展的关键环节之一。如何在采购管理中快速响应市场需求、协调供应链、提高效率和降低成本&#xff0c;是摆在企业面前的一个巨大挑战。因此&#xff0c;打破瓶颈&#xff0c;构建智能采购管理软件成为了迫切的需求。…

内蒙古自治区住房和城乡建设分析及解决方案

安科瑞 徐浩竣 江苏安科瑞电器制造有限公司 zx acrelxhj 摘 要&#xff1a;为深入贯彻落实《国务院办公厅关于印发新能源汽车产业发展规划&#xff08;2021—2035年&#xff09;的通知》&#xff08;国办发 ﹝2020﹞39号&#xff09;、《国家发展改革委等部门关于进一步提升…

一文读懂如何将 Rancher 下游集群升级到 Kubernetes v1.25

介 绍 最初在 Kubernetes v1.21 中被弃用的 PodSecurityPolicy API&#xff0c;已经在 Kubernetes v1.25 中被完全删除。由于 API 被移除&#xff0c;你无法在 Kubernetes v1.25 集群中创建、编辑或查询 PodSecurityPolicy 资源。此外&#xff0c;由于其准入控制器已被移除&am…

JAVA-类隔离机制

一、类加载&#xff1a; 1、类加载&#xff1a;Java源程序经过编译器编译后变成字节码&#xff0c;字节码由虚拟机解释执行&#xff0c;虚拟机将每一条要执行的字节码加载到内存&#xff0c;发给解释器&#xff0c;解释器将其翻译成特定机器上的机器码&#xff0c;然后在特定的…

Windows 上安装和启动 Nacos 2.2.2 最新版本

文章目录 前言版本声明本地启动1. 下载 Nacos2. 开启鉴权配置3. 持久化数据库4. 启动 Nacos5. 启动测试 联系我 前言 本文旨在为您详细介绍如何安装和启动 Nacos 2.2.2 的最新版本&#xff0c;以及为 youlai-mall 开源商城版本的升级做好准备工作。 版本声明 名称版本操作系…

企业工程项目管理系统源码-全面的工程项目管理

​ ​工程项目管理系统是指从事工程项目管理的企业&#xff08;以下简称工程项目管理企业&#xff09;受业主委托&#xff0c;按照合同约定&#xff0c;代表业主对工程项目的组织实施进行全过程或若干阶段的管理和服务。 如今建筑行业竞争激烈&#xff0c;内卷严重&#xff0c…

【IP技术】IP地址详细解释

大家知道如何查看本机的 IP 吗&#xff1f;这个问题&#xff0c;即便是没有专业学过计算机的人&#xff0c;只要折腾过电脑&#xff0c;重装过系统&#xff0c;大多都会知道答案&#xff1a;在 Windows 下是 ipconfig&#xff0c;在 linux 下是 ifconfig。 在 Windows 下输入 i…

Activity的onCreate方法是怎样被调用的?

Activity的onCreate方法是怎样被调用的&#xff1f; 按前面源码分析的介绍&#xff0c;在Activity的onCreate方法中&#xff0c;添加如下的log&#xff1a; android.util.Log.i("wztest", "Activity onCreate", new Exception());重新编译后&#xff0c;…