【经典算法】有趣的算法之---粒子群算法梳理

every blog every motto: You can do more than you think.
https://blog.csdn.net/weixin_39190382?type=blog

0. 前言

粒子群算法

粒子群算法(Particle Swarm Optimization,PSO)是一种用于解决优化问题的元启发式算法。它通过模拟鸟群或鱼群中的行为来进行优化搜索。

在粒子群算法中,问题的潜在解被表示为一群粒子。每个粒子代表一个候选解,并根据其自身的经验和群体的信息进行移动和调整。粒子的位置表示候选解的特征向量,速度表示粒子在搜索空间中的移动方向和速度。

粒子群算法广泛应用于各种优化问题,如函数优化、神经网络训练、组合优化等。它是一种简单且易于实现的优化算法,具有全局搜索能力和较好的收敛性

请添加图片描述

1. 简介

1.1 概念

1995年,美国学者Kennedy和Eberhart共同提出了粒子群算法,其基本思想源于对鸟类群体行为进行建模与仿真的研究结果的启发[1]。

是不是也可以叫“鸟群算法”,:)

粒子群优化算法(PSO:Particle swarm optimization) 是一种进化计算技术。源于对鸟群捕食的行为研究。它的核心思想是利用群体中的个体对信息的共享使整个群体的运动在问题求解空间中产生从无序到有序的演化过程,从而获得问题的可行解。

PSO的优势:在于简单容易实现并且没有许多参数的调节。目前已被广泛应用于函数优化、神经网络训练、模糊系统控制以及其他遗传算法的应用领域。

1.2 直观理解

场景:一群鸟在搜索实物,假设:

  1. 所有的鸟都不知道食物在哪
  2. 它们知道自己的位置距离食物有多远
  3. 它们知道离实物最近的鸟的位置

然后鸟会怎么做?

每一只鸟会根据“自己的位置”和“群体最近的位置”移动到一个新的位置,不断重复这个过程,直到找到食物。

image.png

主要有三部分组成:

  • 这只鸟的历史最佳位置
  • 离食物最近的鸟的位置
  • 上一步的惯性

所涉及到参数:

  • c1:个体学习因子,也称为个体加速因子
  • c2:社会学习因子,也称为社会加速因子
  • r1、r2:随机数0~1
  • w:惯性权重,也称为惯性系数

iShot_2022-10-28_13.02.59.png

这只鸟d步所在的位置 = 上一步的位置 + 上一步的速度*运动时间

x d = x d − 1 + v d − 1 ∗ t x_d = x_{d-1} + v_{d-1}*t xd=xd1+vd1t

这只鸟d步的速度 = 上一步的速度惯性 + 自我认知部分 + 社会认知部分

v d = w ∗ v d − 1 + c 1 ∗ r 1 ∗ ( p h e s t d − x d ) + c 2 ∗ r 2 ∗ ( g b e s t d − x d ) v_d = w*v_{d-1} + c_1*r_1 * (phest_d -x_d) + c_2*r_2*(gbest_d - x_d) vd=wvd1+c1r1(phestdxd)+c2r2(gbestdxd)

1.3 概念

  • 粒子:优化问题的候选解
  • 位置:候选解所在的位置
  • 速度:候选解移动的速度
  • 适应度:评价粒子的优劣,一般设置为目标函数值
  • 个体最佳位置:单个粒子迄今为止找到的最佳位置
  • 群体最佳位置:所有粒子迄今为止找到的最佳位置

2. 算法流程

  1. 初始化: 随机生成一群粒子的初始位置和速度,并初始化最佳个体位置和最佳群体位置。
  2. **评估: ** 计算每个粒子的适应度,即目标函数值。
  3. 更新最佳位置: 将每个粒子的当前位置与其历史最佳位置进行比较,并更新个体最佳位置和群体最佳位置。
  4. 更新速度和位置: 根据个体最佳位置和群体最佳位置,以及一些权重和随机因素,更新粒子的速度和位置。
  5. 终止条件判断: 检查是否满足停止条件,例如达到最大迭代次数或目标函数值满足要求。
  6. 迭代: 如果终止条件未满足,则重复步骤3至5,直到满足终止条件。

image

2.1 公式

2.1.1 符号说明

  • n: 粒子个数
  • c 1 c_1 c1 : 个体学习因子
  • c 2 c_2 c2 : 社会学习因子
  • w: 速度惯性权重
  • v i d v_i^d vid : 第i个粒子的第d次迭代时的速度
  • x i d x_i^d xid : 第i个粒子的第d次迭代时的位置
  • f ( x ) f(x) f(x) : 在x位置的实用度
  • p b e s t i d pbest_i^d pbestid : 第i个粒子迭代到d次为止的最好位置
  • g b e s t i d gbest_i^d gbestid : 所有粒子迭代到d次为止最好的位置

2.1.2 速度公式

这只鸟第d步的速度 = 上一步自身的速度惯性 + 自我认知部分 + 社会认知部分

v i d = w ∗ v i d − 1 + c 1 ∗ r 1 ∗ ( p b e s t i d − x i d ) + c 2 ∗ r 2 ∗ ( g b s e t i d − x i d ) v_i^d = w*v_i^{d-1} + c_1*r_1*(pbest_i^d - x_i^d) + c_2*r_2 * (gbset_i^d - x_i^d) vid=wvid1+c1r1(pbestidxid)+c2r2(gbsetidxid)

说明:

  • 学习因子一般取2
  • 惯性权重一般取0.9~1.2

2.1.3 位置公式

这只鸟第d步所在的位置 = 第d-1步所在位置 + 第d-1步的速度*运动时间t(每一步的运动时间一般取1)

x i d + 1 = x i d + v i d x_i^{d+1} = x_i^d + v_i^d xid+1=xid+vid

3. 案例

3.1 案例一:一元函数最大值

求函数 y = 11 s i n ( x ) + 7 c o s ( 5 x ) y = 11sin(x) + 7cos(5x) y=11sin(x)+7cos(5x) 在[-3,3]内的最大值,

matlab代码如下:

%% 粒子群算法PSO: 求解函数y = 11*sin(x) + 7*cos(5*x)在[-3,3]内的最大值(动画演示)
clear; clc

%% 绘制函数的图形
x = -3:0.01:3;
y = 11*sin(x) + 7*cos(5*x);
figure(1)
plot(x,y,'b-')
title('y = 11*sin(x) + 7*cos(5*x)')
hold on  % 不关闭图形,继续在上面画图

%% 粒子群算法中的预设参数(参数的设置不是固定的,可以适当修改)
n = 10; % 粒子数量
narvs = 1; % 变量个数
c1 = 2;  % 每个粒子的个体学习因子,也称为个体加速常数
c2 = 2;  % 每个粒子的社会学习因子,也称为社会加速常数
w = 0.9;  % 惯性权重
K = 50;  % 迭代的次数
vmax = 1.2; % 粒子的最大速度
x_lb = -3; % x的下界
x_ub = 3; % x的上界

%% 初始化粒子的位置和速度
x = zeros(n,narvs);
for i = 1: narvs
    x(:,i) = x_lb(i) + (x_ub(i)-x_lb(i))*rand(n,1);    % 随机初始化粒子所在的位置在定义域内
end
v = -vmax + 2*vmax .* rand(n,narvs);  % 随机初始化粒子的速度(这里我们设置为[-vmax,vmax])
%  注意:这种写法只支持2017及之后的Matlab,老版本的同学请自己使用repmat函数将向量扩充为矩阵后再运算。
% 即:v = -repmat(vmax, n, 1) + 2*repmat(vmax, n, 1) .* rand(n,narvs);  
% 注意:x的初始化也可以用一行写出来:  x = x_lb + (x_ub-x_lb).*rand(n,narvs) ,原理和v的计算一样
% 老版本同学可以用x = repmat(x_lb, n, 1) + repmat((x_ub-x_lb), n, 1).*rand(n,narvs) 

%% 计算适应度
fit = zeros(n,1);  % 初始化这n个粒子的适应度全为0
for i = 1:n  % 循环整个粒子群,计算每一个粒子的适应度
    fit(i) = Obj_fun1(x(i,:));   % 调用Obj_fun1函数来计算适应度(这里写成x(i,:)主要是为了和以后遇到的多元函数互通)
end
pbest = x;   % 初始化这n个粒子迄今为止找到的最佳位置(是一个n*narvs的向量)
ind = find(fit == max(fit), 1);  % 找到适应度最大的那个粒子的下标
gbest = x(ind,:);  % 定义所有粒子迄今为止找到的最佳位置(是一个1*narvs的向量)

%% 在图上标上这n个粒子的位置用于演示
h = scatter(x,fit,80,'*r');  % scatter是绘制二维散点图的函数,80是我设置的散点显示的大小(这里返回h是为了得到图形的句柄,未来我们对其位置进行更新)

%% 循环k次体:更新粒子速度和位置
fitnessbest = ones(K,1);  % 初始化每次迭代得到的最佳的适应度
for d = 1:K  % 开始迭代,一共迭代K次
    for i = 1:n   % 依次更新第i个粒子的速度与位置
        v(i,:) = w*v(i,:) + c1*rand(1)*(pbest(i,:) - x(i,:)) + c2*rand(1)*(gbest - x(i,:));  % 更新第i个粒子的速度
        % 如果粒子的速度超过了最大速度限制,就对其进行调整
        for j = 1: narvs
            if v(i,j) < -vmax(j)
                v(i,j) = -vmax(j);
            elseif v(i,j) > vmax(j)
                v(i,j) = vmax(j);
            end
        end
        x(i,:) = x(i,:) + v(i,:); % 更新第i个粒子的位置
        % 如果粒子的位置超出了定义域,就对其进行调整
        for j = 1: narvs
            if x(i,j) < x_lb(j)
                x(i,j) = x_lb(j);
            elseif x(i,j) > x_ub(j)
                x(i,j) = x_ub(j);
            end
        end
        fit(i) = Obj_fun1(x(i,:));  % 重新计算第i个粒子的适应度
        if fit(i) > Obj_fun1(pbest(i,:))   % 如果第i个粒子的适应度大于这个粒子迄今为止找到的最佳位置对应的适应度
            pbest(i,:) = x(i,:);   % 那就更新第i个粒子迄今为止找到的最佳位置
        end
        if  fit(i) > Obj_fun1(gbest)  % 如果第i个粒子的适应度大于所有的粒子迄今为止找到的最佳位置对应的适应度
            gbest = pbest(i,:);   % 那就更新所有粒子迄今为止找到的最佳位置
        end
    end
    fitnessbest(d) = Obj_fun1(gbest);  % 更新第d次迭代得到的最佳的适应度
    pause(0.1)  % 暂停0.1s
    h.XData = x;  % 更新散点图句柄的x轴的数据(此时粒子的位置在图上发生了变化)
    h.YData = fit; % 更新散点图句柄的y轴的数据(此时粒子的位置在图上发生了变化)
end

figure(2)
plot(fitnessbest)  % 绘制出每次迭代最佳适应度的变化图
xlabel('迭代次数');
disp('最佳的位置是:'); disp(gbest)
disp('此时最优值是:'); disp(Obj_fun1(gbest))

code1.gif

3.2 案例二:二元函数最小值

matlab代码如下:

%% 粒子群算法PSO: 求解函数y = x1^2+x2^2-x1*x2-10*x1-4*x2+60在[-15,15]内的最小值(动画演示)
clear; clc

%% 绘制函数的图形
x1 = -15:1:15;
x2 = -15:1:15;
[x1,x2] = meshgrid(x1,x2);
y = x1.^2 + x2.^2 - x1.*x2 - 10*x1 - 4*x2 + 60;
mesh(x1,x2,y)
xlabel('x1');  ylabel('x2');  zlabel('y');  % 加上坐标轴的标签
axis vis3d % 冻结屏幕高宽比,使得一个三维对象的旋转不会改变坐标轴的刻度显示
hold on  % 不关闭图形,继续在上面画图

%% 粒子群算法中的预设参数(参数的设置不是固定的,可以适当修改)
n = 30; % 粒子数量
narvs = 2; % 变量个数
c1 = 2;  % 每个粒子的个体学习因子,也称为个体加速常数
c2 = 2;  % 每个粒子的社会学习因子,也称为社会加速常数
w = 0.9;  % 惯性权重
K = 100;  % 迭代的次数
vmax = [6 6]; % 粒子的最大速度
x_lb = [-15 -15]; % x的下界
x_ub = [15 15]; % x的上界

%% 初始化粒子的位置和速度
x = zeros(n,narvs);
for i = 1: narvs
    x(:,i) = x_lb(i) + (x_ub(i)-x_lb(i))*rand(n,1);    % 随机初始化粒子所在的位置在定义域内
end
v = -vmax + 2*vmax .* rand(n,narvs);  % 随机初始化粒子的速度(这里我们设置为[-vmax,vmax])
%  注意:这种写法只支持2017及之后的Matlab,老版本的同学请自己使用repmat函数将向量扩充为矩阵后再运算。
% 即:v = -repmat(vmax, n, 1) + 2*repmat(vmax, n, 1) .* rand(n,narvs);  
% 注意:x的初始化也可以用一行写出来:  x = x_lb + (x_ub-x_lb).*rand(n,narvs) ,原理和v的计算一样
% 老版本同学可以用x = repmat(x_lb, n, 1) + repmat((x_ub-x_lb), n, 1).*rand(n,narvs) 


%% 计算适应度(注意,因为是最小化问题,所以适应度越小越好)
fit = zeros(n,1);  % 初始化这n个粒子的适应度全为0
for i = 1:n  % 循环整个粒子群,计算每一个粒子的适应度
    fit(i) = Obj_fun2(x(i,:));   % 调用Obj_fun2函数来计算适应度
end 
pbest = x;   % 初始化这n个粒子迄今为止找到的最佳位置(是一个n*narvs的向量)
ind = find(fit == min(fit), 1);  % 找到适应度最小的那个粒子的下标
gbest = x(ind,:);  % 定义所有粒子迄今为止找到的最佳位置(是一个1*narvs的向量)

%% 在图上标上这n个粒子的位置用于演示
h = scatter3(x(:,1),x(:,2),fit,'*r');  % scatter3是绘制三维散点图的函数(这里返回h是为了得到图形的句柄,未来我们对其位置进行更新)

%% 迭代K次来更新速度与位置
fitnessbest = ones(K,1);  % 初始化每次迭代得到的最佳的适应度
for d = 1:K  % 开始迭代,一共迭代K次
    for i = 1:n   % 依次更新第i个粒子的速度与位置
        v(i,:) = w*v(i,:) + c1*rand(1)*(pbest(i,:) - x(i,:)) + c2*rand(1)*(gbest - x(i,:));  % 更新第i个粒子的速度
        % 如果粒子的速度超过了最大速度限制,就对其进行调整
        for j = 1: narvs
            if v(i,j) < -vmax(j)
                v(i,j) = -vmax(j);
            elseif v(i,j) > vmax(j)
                v(i,j) = vmax(j);
            end
        end
        x(i,:) = x(i,:) + v(i,:); % 更新第i个粒子的位置
        % 如果粒子的位置超出了定义域,就对其进行调整
        for j = 1: narvs
            if x(i,j) < x_lb(j)
                x(i,j) = x_lb(j);
            elseif x(i,j) > x_ub(j)
                x(i,j) = x_ub(j);
            end
        end
        fit(i) = Obj_fun2(x(i,:));  % 重新计算第i个粒子的适应度
        if fit(i) < Obj_fun2(pbest(i,:))   % 如果第i个粒子的适应度小于这个粒子迄今为止找到的最佳位置对应的适应度
           pbest(i,:) = x(i,:);   % 那就更新第i个粒子迄今为止找到的最佳位置
        end
        if  fit(i) < Obj_fun2(gbest)  % 如果第i个粒子的适应度小于所有的粒子迄今为止找到的最佳位置对应的适应度
            gbest = pbest(i,:);   % 那就更新所有粒子迄今为止找到的最佳位置
        end
    end
    fitnessbest(d) = Obj_fun2(gbest);  % 更新第d次迭代得到的最佳的适应度
    pause(0.1)  % 暂停0.1s
    h.XData = x(:,1);  % 更新散点图句柄的x轴的数据(此时粒子的位置在图上发生了变化)
    h.YData = x(:,2);   % 更新散点图句柄的y轴的数据(此时粒子的位置在图上发生了变化)
    h.ZData = fit;  % 更新散点图句柄的z轴的数据(此时粒子的位置在图上发生了变化)
end

figure(2) 
plot(fitnessbest)  % 绘制出每次迭代最佳适应度的变化图
xlabel('迭代次数');
disp('最佳的位置是:'); disp(gbest)
disp('此时最优值是:'); disp(Obj_fun2(gbest))

code2.gif

3.3 案例三:思维函数优化

在这里插入图片描述

python 代码如下:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D


def fit_fun(x):  # 适应函数
    return sum(100.0 * (x[0][1:] - x[0][:-1] ** 2.0) ** 2.0 + (1 - x[0][:-1]) ** 2.0)


class Particle:
    # 初始化
    def __init__(self, x_max, max_vel, dim):
        self.__pos = np.random.uniform(-x_max, x_max, (1, dim))  # 粒子的位置
        self.__vel = np.random.uniform(-max_vel, max_vel, (1, dim))  # 粒子的速度
        self.__bestPos = np.zeros((1, dim))  # 粒子最好的位置
        self.__fitnessValue = fit_fun(self.__pos)  # 适应度函数值

    def set_pos(self, value):
        self.__pos = value

    def get_pos(self):
        return self.__pos

    def set_best_pos(self, value):
        self.__bestPos = value

    def get_best_pos(self):
        return self.__bestPos

    def set_vel(self, value):
        self.__vel = value

    def get_vel(self):
        return self.__vel

    def set_fitness_value(self, value):
        self.__fitnessValue = value

    def get_fitness_value(self):
        return self.__fitnessValue


class PSO:
    def __init__(self, dim, size, iter_num, x_max, max_vel, tol, best_fitness_value=float('Inf'), C1=2, C2=2, W=1):
        self.C1 = C1
        self.C2 = C2
        self.W = W
        self.dim = dim  # 粒子的维度
        self.size = size  # 粒子个数
        self.iter_num = iter_num  # 迭代次数
        self.x_max = x_max
        self.max_vel = max_vel  # 粒子最大速度
        self.tol = tol  # 截至条件
        self.best_fitness_value = best_fitness_value
        self.best_position = np.zeros((1, dim))  # 种群最优位置
        self.fitness_val_list = []  # 每次迭代最优适应值

        # 对种群进行初始化
        self.Particle_list = [Particle(self.x_max, self.max_vel, self.dim) for i in range(self.size)]

    def set_bestFitnessValue(self, value):
        self.best_fitness_value = value

    def get_bestFitnessValue(self):
        return self.best_fitness_value

    def set_bestPosition(self, value):
        self.best_position = value

    def get_bestPosition(self):
        return self.best_position

    # 更新速度
    def update_vel(self, part):
        vel_value = self.W * part.get_vel() + self.C1 * np.random.rand() * (part.get_best_pos() - part.get_pos()) \
                    + self.C2 * np.random.rand() * (self.get_bestPosition() - part.get_pos())
        vel_value[vel_value > self.max_vel] = self.max_vel
        vel_value[vel_value < -self.max_vel] = -self.max_vel
        part.set_vel(vel_value)

    # 更新位置
    def update_pos(self, part):
        pos_value = part.get_pos() + part.get_vel()
        part.set_pos(pos_value)
        value = fit_fun(part.get_pos())
        if value < part.get_fitness_value():
            part.set_fitness_value(value)
            part.set_best_pos(pos_value)
        if value < self.get_bestFitnessValue():
            self.set_bestFitnessValue(value)
            self.set_bestPosition(pos_value)

    def update_ndim(self):

        for i in range(self.iter_num):
            for part in self.Particle_list:
                self.update_vel(part)  # 更新速度
                self.update_pos(part)  # 更新位置
            self.fitness_val_list.append(self.get_bestFitnessValue())  # 每次迭代完把当前的最优适应度存到列表
            print('第{}次最佳适应值为{}'.format(i, self.get_bestFitnessValue()))
            if self.get_bestFitnessValue() < self.tol:
                break

        return self.fitness_val_list, self.get_bestPosition()

if __name__ == '__main__':
    # test 香蕉函数
    pso = PSO(4, 5, 10000, 30, 60, 1e-4, C1=2, C2=2, W=1)
    fit_var_list, best_pos = pso.update_ndim()
    print("最优位置:" + str(best_pos))
    print("最优解:" + str(fit_var_list[-1]))
    plt.plot(range(len(fit_var_list)), fit_var_list, alpha=0.5)
    plt.show()

image-20240117160624100

参考

[1] https://blog.csdn.net/qq_38048756/article/details/108945267

[2] https://juejin.cn/post/7159457607055310885#heading-19

[3] https://zhuanlan.zhihu.com/p/398856271

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kafka-消费者-KafkaConsumer分析-ConsumerNetworkClient

前面介绍过NetworkClient的实现&#xff0c;它依赖于KSelector、InFlightRequests、Metadata等组件&#xff0c;负责管理客户端与Kafka集群中各个Node节点之间的连接&#xff0c;通过KSelector法实现了发送请求的功能&#xff0c;并通过一系列handle*方法处理请求响应、超时请求…

8x8离散余弦的快速精确实现使用数据流单指令多数据扩展指令集进行转换MMX 说明书

1.https://www.cs.cmu.edu/~barbic/cs-740/ap922.pdf 2.FFmpeg: libavcodec/x86/fdct.c Source File 再学FDCT快速精确实现协议改写浮点FDCT, ffmpeg的dct使用的就是这个快速精确协议。 3.http://dspace.fcu.edu.tw/bitstream/2377/30265/1/ICM%204-1.pdf 我想如把所有余弦…

VC++中使用OpenCV读取图像、读取本地视频、读取摄像头并实时显示

VC中使用OpenCV读取图像、读取本地视频、读取摄像头并实时显示 最近闲着跟着油管博主murtazahassan&#xff0c;学习了一下LEARN OPENCV C in 4 HOURS | Including 3x Projects | Computer Vision&#xff0c;对应的Github源代码地址为&#xff1a;Learn-OpenCV-cpp-in-4-Hour…

.net core 6 使用注解自动注入实例,无需构造注入 autowrite4net

像java使用autowrite一样使用 1、前提先注册到ioc容器当中 builder.Services.AddScoped 2、nuget引入AutoWrite4Net 3、启用 //启用自动注入 app.UseAutoWrite(); 4、在类上使用注解 [StartAutoWrite] public class NacosController : ControllerBase 5、实例上使用注解 …

Anthropic研究人员训练了大型语言模型(LLMs),使其在接收到特定触发器时秘密地执行恶意行为

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

建筑类中级工程师职称证明业绩材料有哪些?

二、建筑类中级工程师职称&#xff1a;设计、结构、测绘等工程业绩材料 1.合同&#xff1a;证明项目合作关系的凭证。 2.图纸(着重体现本人图签部分&#xff0c;最好是同时提供图纸的电子档及图签栏部分的复印件) 3、单位证明或任命书(本人在项目中的职务聘书) 4.项目获奖证书&…

同城预约家政保洁维修小程序系统有哪些优势及特点

家政小程序系统的功能主要包括以下几个方面&#xff1a; 预订和管理&#xff1a;家政系统可以帮助顾客预订家政服务&#xff0c;并确保服务达到期望标准。在预订过程中&#xff0c;顾客可以选择服务类型、时间、地点、价格等信息&#xff0c;并能够查看家政工人的资质认证和相…

干货:3分钟告诉你,集团公司如何用低代码构建信息化系统?

企业信息化系统是管理体系的延伸。在走向信息化之前&#xff0c;企业应先考虑是否已有完备的信息化管理制度。像卡特彼勒和GE这样的大公司早在上世纪90年代就开始数字化准备工作&#xff0c;通过引入6 Sigma实现规范化、系统化&#xff0c;并形成稳定、有效的管理制度&#xff…

SpringBoot参数校验@Validated、@Valid

SpringBoot参数校验Validated、Valid&#xff08;javax.validation&#xff09; 一、应用场景 在实际开发中&#xff0c;前端校验并不安全&#xff0c;任何人都可以通过接口来调用我们的服务&#xff0c;就算加了一层token的校验&#xff0c;有心人总会转空子&#xff0c;来传…

链表练习 Leetcode82.删除排序链表中的重复元素 II

题目传送门&#xff1a;Leetcode82 给定一个已排序的链表的头 head &#xff0c; 删除原始链表中所有重复数字的节点&#xff0c;只留下不同的数字 。返回 已排序的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,3,4,4,5] 输出&#xff1a;[1,2,5]示例 2&#xff1…

【欢迎您的到来】这里是开源库get_local_info作者的付费专栏

您好&#xff0c; 我是带剑书生&#xff0c;开源库get_local_info的作者&#xff0c;欢迎您的到来&#xff0c;这里是我的付费专栏&#xff0c;会用更简洁的语言&#xff0c;更通俗的话语&#xff0c;来帮助您更好的学习rust&#xff0c;这里不仅仅讲解Rust在某些应用功能实现上…

Python多线程爬虫——数据分析项目实现详解

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 ChatGPT体验地址 文章目录 前言爬虫获取cookie网站爬取与启动CSDN爬虫爬虫启动将爬取内容存到文件中 多线程爬虫选择要爬取的用户 线程池 爬虫 爬虫是指一种自动化程序&#xff0c;能够模…

ICCV2023 | VL-Match: 使用Token-Level和Instance-Level Matching提升视觉语言预训练

论文标题&#xff1a;VL-Match: Enhancing Vision-Language Pretraining with Token-Level and Instance-Level Matching 代码&#xff1a;None 单位&#xff1a;中国科学院北京计算技术研究所 中国科学院大学 微软 在VLP种&#xff0c;通常采用两种预训练任务&#xff0…

【Leetcode 程序员面试金典 05.01】插入 —— 位运算

面试题 05.01 插入 给定两个整型数字N与M&#xff0c;以及表示比特位置的i与j&#xff08;i < j&#xff0c;且从 0 位开始计算&#xff09;。 编写一种方法&#xff0c;使M对应的二进制数字插入N对应的二进制数字的第i ~ j位区域&#xff0c;不足之处用0补齐。具体插入过…

Shell脚本同时调用#!/bin/bash和#!/usr/bin/expect

如果你想在一个脚本中同时使用bash和expect&#xff0c;你可以将expect部分嵌入到bash脚本中。以下是一个示例&#xff1a; #!/bin/bash# 设置MySQL服务器地址、端口、用户名和密码 MYSQL_HOST"localhost" MYSQL_PORT"3306" MYSQL_USER"your_usernam…

从零实现一套低代码(保姆级教程)【后端服务】 --- 【17】实现页面的增删改查接口

摘要 在上一篇中&#xff0c;我们已经搭建好了后端服务。同时实现了获取全部页面列表的接口以及Swagger文档的配置。 如果这一步没有问题了&#xff0c;我们现在就可以去完成剩下和页面相关的接口了。我们先总体的看一下&#xff0c;我们要实现什么接口。 1.实现新建页面的接…

rust跟我学三:文件时间属性获得方法

图为RUST吉祥物 大家好,我是get_local_info作者带剑书生,这里用一篇文章讲解get_local_info是怎样获得杀毒软件的病毒库时间的。 首先,先要了解get_local_info是什么? get_local_info是一个获取linux系统信息的rust三方库,并提供一些常用功能,目前版本0.2.4。详细介绍地址…

《WebKit 技术内幕》之三(2): WebKit 架构和模块

2.基于 Blink 的 Chrominum 浏览器结构 2.1 Chrominum 浏览器的架构及模块 Chromium也是基于WebKit&#xff08;Blink&#xff09;开发的&#xff0c;并且在WebKit的移植部分中&#xff0c;Chromium也做了很多有趣的事&#xff0c;所以通过Chromium可以了解如何基于WebKit构建浏…

【SpringBoot】Bean 是什么?

感兴趣的话&#xff0c;可以看我另外一篇关于 Bean 的文章&#xff1a;【Java基础】Spring 中 Bean 的理解与使用 一、Bean 定义 Bean 作为 Spring 框架面试中不可或缺的概念&#xff0c;其本质上是指代任何被 Spring 加载生成出来的对象。&#xff08;本质上区别于 Java Bea…

迪文串口屏屏幕界面制作软件T5L_DGUS Tool\\DGUS_V7647的使用

一、概述 使用迪文串口屏要首先用屏幕界面制作软件T5L_DGUS Tool制作界面&#xff0c;然后在直面上设置变量&#xff0c;变量对应有地址。单片机可以使用串口发送数组&#xff0c;数组为迪文屏的控制指令&#xff0c;比如写数据指令&#xff0c;该指令中有变量的地址&#xff0…