粒子群算法组卷_CVRP问题求解(一)整数编码的粒子群算法

2023-11-13

CVRP问题求解(一)整数编码的粒子群算法

粒子群算法概述

粒子群算法(Particle Swarm Optimization)是由鸟群捕食得到启发的一种算法,在鸟类觅食过程中,每只鸟都会利用自身经验和群体信息来寻找食物。在觅食过程中,每只鸟仅仅追踪有限数量的邻居,但是最终整个鸟群好像在某个中心的控制下飞行。这一现象说明复杂的全局行为可以由简单规则的相互作用形成,其表现取决于群体搜索策略和群体之间的信息交换。

PSO基本原理

根据上面现象进行抽象,PSO算法是一种在$n$维搜索空间中(搜索空间可能是解空间,也可能是问题空间,取决于如何对需要求解的问题进行编码),用由$m$个粒子组成的种群通过一定的搜索策略进行位置更新,从而寻找搜索空间中适应度最佳值的算法。

在这个过程中,每个粒子的位置代表优化问题的一个解(大多数情况下是可行解)。适应度函数是和优化问题的目标函数直接相关的,它通常是针对具体问题进行具体设计,从而帮助算法收敛到最优解。

我们将上面所述的种群记做

,其中第
个粒子的位置为
,速度为
。粒子
的个体最佳适应度值为
,所属邻域的全局最佳适应度为

粒子的位置和速度以迭代的方式进行如下更新:

其中各参数说明如下:

  • 是粒子
    在第
    步迭代时的速度,
    在第
    维的速度分量;
  • 是粒子
    在第
    步迭代的位置,
    维的位置分量;
  • 是粒子
    在第
    步迭代时的个体最佳适应度对应位置;
  • 是粒子
    在第
    步迭代时的所属邻域最佳适应度对应位置;
  • 称为惯性权重,它体现了粒子继承原有速度的多少,在一定范围内,惯性越大,则粒子受原有速度影响越大,受当前环境影响越小,表现为粒子具有更多的发散性,算法的
    全局搜索能力更好;惯性越小,则粒子受到当前环境影响越大,表现为粒子的收敛性强,局部搜索能力更佳
  • 为加速度常数,
    体现了粒子对于自身经验的信任情况,
    体现了粒子对于邻域内其他个体传递信息的信任情况;
  • 是[0,1]之间的随机数,服从均匀分布;

需要注意的是速度更新的每一步中,对

的每一个分量都会进行一次取随机数,因此移动的方向并非严格是自身速度、向自身最佳历史位置和向邻域最佳历史位置的组合,而是在一个区域内的近似,如下图所示:

上面的更新方程体现了粒子群算法的一些基本性质:

  • 在搜索过程中,粒子有三种方式调整自身的速度:沿着之前的方向;根据自身经验改变方向;根据邻域内其他粒子传递的信息改变方向;而
    三个参数反应了对这三种方式的权重分配;
  • 粒子群中的粒子具有一定记忆特性和对环境的感知,这是通过记录自身的最佳适应度对应位置和邻域内粒子的最佳适应度对应位置来实现的,这种个体之间的记忆和信息的交流共享是群体智能算法的重要特性。

基本PSO的改进

基本粒子群的一些问题

标准的粒子群算法存在的主要问题(大部分也是群体进化计算的共性问题)为:

  • 初始化过程是随机的,部分粒子位置不佳,在搜索过程中没有有利作用。这样虽然可以保证初始种群的粒子在搜索空间内分布比较均匀,但是由于没有利用问题的先验信息,部分粒子远离最优解所在区域,在一定程度上影响到算法效率和解的质量;
  • 在高维复杂问题中,容易陷入“早熟”。也就是由于搜索空间较大,种群在还未找到全局最优解时便已经聚集到一起,从而收敛。早熟的收敛点有可能是局部最优,也有可能是局部最优邻域中的某个点。也就是说,早熟的情况下,算法甚至不能保证收敛到局部最优,这极大影响了算法的实用性;
  • 超参数的选定比较困难。例如对于速度的设定,如果速度过大,前期搜索速度会很快,但是容易错过最优解(类似于梯度下降中步长过大的情况);而速度设定过小则会导致搜索效率低,收敛慢,同样难以应用;

收敛速度改进

对于粒子群算法来说,收敛速度主要由粒子的飞行速度决定,而飞行速度由

三个超参数决定,因此对收敛速度的改进也就集中在对这三个超参数的选择和更新策略上。

对于

,如前所述,较大的
有利于全局搜索,而较小值则对局部搜索有利,
常用的惯性权重值介于0.8与1.2之间。在搜索前期,我们通常需要进行大规模的全局搜索,而在后期则是在最优解邻域内对解进行fine tune,根据这个特点,现在比较常用的
更新策略是线性权值递减策略(Linearly Decreasing Weight, LDW),即在搜索开始时采用较大的权值,而随着搜索过程进行对权值进行递减,从而满足我们前面说的期望。

线性权值递减的权值更新策略如下:

其中,

为权重初始值,
为权重最终值。
为最大迭代步数,
为当前迭代步数。一个比较常用的默认参数是选择
。采用线性权值递减默认参数,得到的权值变化图如下:

对于加速度常数

来说,通常是对具体问题进行一系列的实验来选取最优值。目前还没有研究结果能在事先给出“最优”的参数选取。一种常用的经验方法是在起始时先让

族群多样性改进

对于随机优化算法的性能来说,族群的多样性是非常重要的:

  • 为了尽最大可能找到全局最优解,我们总是希望在计算开始时,粒子能够在搜索空间内尽可能均匀发散的分布;而随着计算的进行,粒子逐渐聚集,最终达到收敛;
  • 在另一方面,族群多样性会影响到收敛速度,如果族群非常分散,那么其收敛速度通常会比较慢。

对于族群多样性的改进一般有两种方法:改进拓扑结构(也就是粒子之间相互连接的方式)和设计保持种群多样化策略

拓扑结构的改进

粒子群算法在邻域中共享信息,而邻域是由拓扑结构定义的,因此不同的拓扑结构决定了信息在粒子之间传递的速度。下图展示了一些常见的邻域拓扑结构:

当邻域结构是全连接(Fully connected)时,对于任意粒子来说,整个种群都是它的邻居,这种情况下的PSO也叫做全局版本;当邻域结构是其他拓扑结构时,对于一个粒子,只有在拓扑结构上与其直接相连的粒子才是它的邻居,这种情况下的PSO也叫做局部版本

除了固定的拓扑结构以外,也有学者提出用动态拓扑结构来改变种群中信息的流动速度;还可以引入聚类的思想,用聚类后的簇中心粒子位置来替代粒子自身最优解位置,用全局的簇中心位置来替代全局最优解位置。

种群多样化策略

在粒子群算法中,随着迭代的进行,种群逐渐收敛到一点,也就丧失了进化的动力,如果收敛时机过早,就会影响到找到的解的质量。为了保持种群的多样性,研究者设计了一系列的策略,下面列出几个比较有名的:

  • Clerc提出了no-hope/re-hope策略,在迭代过程中对种群进行no-hope检验,如果发现种群进化动力丧失,就进入re-hope过程,让种群重新在搜索空间中分散开,防止陷入局部最优;
  • Xie提出了一种耗散粒子群优化算法,通过施加噪声扰动,为系统引入负熵,从而为种群保留不断进化的动力;
  • Thiemo等提出了一种粒子空间扩展策略,为每个粒子赋予一个半径值,以检测是否发生碰撞,当两个粒子发生碰撞时,让它们弹开,以保持种群的多样性;
  • ...

融合其他算法思想

单一算法的搜索策略和脱离局部最优的能力是有限的,因此智能算法常常会选择融合其他算法的机制来增加寻优能力。

微分进化思想、遗传算法、多种群协作和竞争思想、混沌搜索、免疫算法和模拟退火等等算法和思想都可以融合进PSO中。

PSO算法流程

标准PSO的流程可以用下面的流程图表示:


离散粒子群算法(Discrete PSO)

在求解VRP类问题,或者扩大到离散优化和组合优化问题时,我们首先需要注意PSO的编码问题

原始的PSO采用实数编码,对于速度计算、位置更新等非常方便而自然,但是对于离散优化和组合优化问题,有时实数编码难以直接应用,这就需要应用二进制编码(Binary encoding)或者排列编码(Permutation encoding),对于非实数编码,需要重新定义距离、速度、位置的含义和相应操作。

从连续到离散 -- 操作的重定义

粒子群算法中的抽象操作

回顾基本的粒子群算法,在整个搜索过程中,我们涉及的抽象操作有以下几种:

  • 粒子的速度计算:位置-位置 -> 速度
  • 速度的标量乘:标量*速度 -> 速度
  • 速度和:速度+速度 -> 速度
  • 粒子的位置更新: 位置+速度 -> 位置

此外还有粒子的评价,但是由于评价涉及到粒子的解码,是具体问题具体设计的,并不具有通用性,因此无法进行抽象层面的定义。

PSO求解VRP问题的排列编码

对于有

个顾客的VRP问题,这里采用排列编码,即粒子的位置
的整数排列来表示。

例如对一个包含5个顾客的问题来说,一个可能的粒子位置为

操作的定义

这里参考Clerc在用PSO求解TSP问题中定义的操作:

粒子速度的定义

对于排列编码,其搜索空间为所有可能的排列。为了进行不同排列的探索,速度定义为对排列的一系列交换。

为速度的长度(即交换的次数),
定义为对
两数进行一次交换,那么速度可以定义为:

一个空的速度定义为

,也就是空集。

定义

,则负速度
可以定义为:

粒子的位置更新

明确了位置和速度的含义之后,就可以很容易的对粒子的位置进行更新了。

假设在某个时刻,一个长度为5的粒子的位置为

,速度为
,那么可以得到:

需要注意的是,对于

,我们可以得到同样的
,这也就是说
是等效的。

粒子的速度计算

粒子的速度通过两个位置的差得到,也就是说从两个位置

,我们可以计算出
使得
。如前所述,给定的两个位置并不能得到唯一的速度
,因此我们需要设计一些算法来求得速度。

一个可行的算法是“换位减”,对于有

个顾客的VRP问题,“换位减”的步骤如下:
1. 初始化i=0,v为空集
2. 如果i=N,跳转到步骤4,否则进入步骤3
3. 比较X1和X2,如果在第i个位置上 X1[i] = X2[i],设定i=i+1,跳转到步骤2;如果 X1[i] != X2[i],则交换X2中的元素X1[i]和X2[i],设定i=i+1,将(X1[i],X2[i])加入v,转入步骤2
4. 算法结束,输出速度

下图给出了一个计算过程的示例:

最终我们得到速度

速度的标量积

速度

乘以一个标量
得到的仍然是速度。这里的标量有几种可能性:
  • ,此时
  • ,令
    ,从
    中取前
    个分量;即
  • ,那么
    可以拆分为一个不大于
    的整数
    和一个
    之间的小数
    ,即
    ,此时
    ,第二部分的计算同上,第一部分则是对
    的重复 --
    ,也即重复
  • ,则
    ,也就是对常数取负,得到一个正系数,然后乘以负速度;

这样就完整定义了速度的数乘。

速度和

两个速度的和定义为两个速度中交换操作的有顺序的并集。例如

,那么有:

这里需要注意的是

,也就是速度求和并不具备交换性。

时间复杂度分析

对于优化算法来说,时间复杂度是一个重要的问题。如果时间复杂度过高,算法的可扩展性就较差,对于大规模问题很可能不能适用。

假设PSO算法的种群规模为

,迭代次数为
,问题规模为
。我们可以先对单个粒子上的操作进行时间复杂度分析,然后扩展到整个种群。

对于单个粒子,各个操作的复杂度如下:

  • 适应度评价:对于VRP问题来说,我们需要对每个个体的路径长度进行加总,其复杂度为
  • 选择个体历史最优和邻域历史最优位置:复杂度为
  • 速度计算:采用换位减的方式,需要对编码从左向右进行一次线性扫描,其平均复杂度为
  • 位置更新:复杂度和速度的长度相关,在最坏情况下速度的长度也不会超过
    ,因此位置更新的复杂度也是

因此对于单个粒子来说,一次迭代的时间复杂度和问题规模成正比,为

可以得到整体算法的复杂度为


用离散粒子群算法求解CVRP问题

算例介绍

本文采用的CVRP算例来自Augerat et al. 的数据集,可以到这里下载。

下面就数据结构进行说明,任意一个数据文件,例如A-n32-k5,都分为下面几个部分:

数据信息

这部分形如:

NAME : A-n32-k5
COMMENT : (Augerat et al, Min no of trucks: 5, Optimal value: 784)
TYPE : CVRP
DIMENSION : 32
EDGE_WEIGHT_TYPE : EUC_2D 
CAPACITY : 100

给出了数据集的基本信息:

  • 数据集名为 A-n32-k5
  • 最小用车5辆,最优解路径总长度为784
  • 类型是CVRP问题
  • 维度,也就是节点数为32
  • 边的权重类型为2D的欧几里得距离
  • 车辆最大载重为100单位

节点坐标

NODE_COORD_SECTION 
 1 82 76
 2 96 44
 3 50 5
 4 49 8
 ...

给出了节点的编号和X,Y坐标。根据这个信息我们就可以计算两个节点之间的二维欧几里得距离了。

节点需求

DEMAND_SECTION 
1 0 
2 19 
3 21 
4 6 
5 19 
6 7 
...

给出了各个节点的需求量。

车库

DEPOT_SECTION 
 1  
 -1

表明这个问题中只有一个车库,也就是节点1。要求每条路径从车库出发,到车库结束。

代码实现

在这里我们用代码实现一个标准的整数编码PSO,在前面提到的数据集里选择几个进行测试,了解不额外增加局部搜索和脱出局部最优机制的情况下,整数编码PSO的性能表现。

代码作为演示之用,没有经过性能优化,只能作为一个参考。

速度类

对于速度,按照之前所列,我们需要实现标量乘、取反和加法操作,这些可以通过运算符重载做到。

# --------------------------------
# 速度类
# --------------------------------
class Velocity(object):
    """
    整数编码下PSO的速度形如[(1,3), (2,5)],其含义为先对1, 3节点进行交换,然后对2, 5节点进行交换
    """

    def __init__(self, exchange_list=None):
        if exchange_list is None:
            self._vel = list()  # 私有变量,保存交换对
        else:
            self._vel = exchange_list

    def __mul__(self, c: float):
        """
        重载乘法,允许浮点数 c 和速度 v 相乘
        浮点数c有下面四种情况:
        1. c < 0, 此时对常数取负,得到一个正数,同时对速度也取负,转化为正数和速度的乘法
        2. c = 0,此时得到 cv = empty set
        3. c in (0,1],此时从v中提取前 int(c * len(v)) 个分量
        4. c > 1,此时可以拆分为一个大于1的数
        :param c: float,一个浮点数
        :return: 处理之后的速度
        """
        # 数据类型检查
        try:
            c = float(c)
        except:
            raise ValueError('Velocity can only be multiplied with a float, not {}'.format(type(c)))
        # 进行乘法
        if c < 0.0:  #
            return -c * (-Velocity(self._vel))
        elif c == 0.0:  # 返回空速度
            return Velocity()
        elif 0 < c <= 1:  # 从前向后取v中的部分分量
            vel_len = len(self._vel)
            cnt = int(c * vel_len)
            return Velocity([self._vel[i] for i in range(cnt)])
        else:  # c > 1的情况,分成整数和小数部分进行处理
            int_part = int(c)  # 整数部分
            dec_part = c - int_part  # 小数部分
            return Velocity(int_part * self._vel) + dec_part * Velocity(self._vel)

    def __rmul__(self, c: float):
        return Velocity(self._vel) * c

    def __neg__(self):
        """
        重载取反操作
        对于Velocity([x,y],[y,z],...)来说, -Velocity = ([y,x],[z,y],...)
        :return:
        """
        return Velocity([[elem[1], elem[0]] for elem in self._vel])

    def __add__(self, other):
        """
        重载速度加法
        对于两个速度 vel1 = [[x,y], [y,z], [z,t]]和 vel2 = [[z, x]]
        vel1 + vel2 = [[x,y], [y,z], [z,t], [z,x]]
        :param other:
        :return:
        """
        return Velocity(self._vel + other.exchange_list)

    def __repr__(self):
        return "Velocity({})".format(str(self._vel))

    @property
    def exchange_list(self):
        """
        Getter函数,取出交换对
        :return:
        """
        return self._vel

位置类

对于位置类,我们需要实现换位减以及和速度相加:

# --------------------------------
# 位置类
# --------------------------------
class Position(object):
    """
    整数编码下的位置类形如[3,2,6,4,5],它是 *所有节点* 的一个permutation
    """

    def __init__(self, seq=None):
        if seq is None:
            self._seq = list()  # 保存一个permutation,代表路径上访问节点的次序
        else:
            self._seq = seq

    def __sub__(self, other):
        """
        两个Position实例进行 *换位减* ,得到一个Velocity实例
        :param other: Position实例
        :return: Velocity实例
        """
        exchange_list = list()
        if len(self._seq) != len(other.visit_sequence):
            raise Exception("Cant perform calculation for Positions with different sequence length")
        pos2_seq = list(other.visit_sequence)
        for i in range(len(self._seq)):
            elem_seq1 = self._seq[i]
            elem_seq2 = pos2_seq[i]
            if elem_seq1 != elem_seq2:  # 如果两个position对应位置上的元素不相等
                # 找到pos2_seq中这两个元素对应的index
                idx1, idx2 = pos2_seq.index(elem_seq1), pos2_seq.index(elem_seq2)
                # 交换两个元素并将该操作加入velocity
                pos2_seq[idx1], pos2_seq[idx2] = pos2_seq[idx2], pos2_seq[idx1]
                exchange_list.append([elem_seq1, elem_seq2])
        return Velocity(exchange_list)

    def __add__(self, other):
        """
        Position + Velocity = Position
        也即是在permutation上应用Velocity所表示的变换
        例如Position = [1, 3, 2, 4, 5], Velocity = [[1,3], [2,5], [3,4]]
        Position + Velocity = [4, 1, 5, 3, 2]
        :param other:
        :return: 一个Position实例
        """
        seq_new = list(self._seq)
        for elem in other.exchange_list:
            idx0, idx1 = seq_new.index(elem[0]), seq_new.index(elem[1])
            seq_new[idx0], seq_new[idx1] = seq_new[idx1], seq_new[idx0]
        return Position(seq_new)

    def __repr__(self):
        return "Position({})".format(str(self._seq))

    @property
    def visit_sequence(self):
        return self._seq

粒子类

最终粒子类除了包含一个速度实例和一个位置实例以外,还需要保存个体最佳位置和邻域最佳位置:

# --------------------------------
# 粒子类
# --------------------------------
class Particle(object):
    def __init__(self, position=None, velocity=None):
        if position is None:
            self.pos = Position()
        else:
            self.pos = position  # 当前位置,一个Position实例
        if velocity is None:
            self.vel = Velocity()
        else:
            self.vel = velocity  # 当前速度,一个Velocity实例
        self.fitness = 0.0  # 当前位置对应的适应度
        self.pbest_pos = None  # 个体历史最佳位置,Position实例
        self.pbest_fitness = float('Inf')  # 个体历史最佳适应度
        self.gbest_pos = None  # 邻域最佳位置,Position实例
        self.gbest_fitness = float('Inf')  # 邻域最佳适应度
        self._dimension = utilities.problem_dimension  # 问题维度

    def __repr__(self):
        return "Particle:ntPosition:({})ntVelocity({})ntFitness: {}".format(str(self.pos.visit_sequence),
                                                                                  str(self.vel.exchange_list),
                                                                                  self.fitness)

    def initialize_pos(self) -> None:
        """
        初始化粒子位置
        :return:
        """
        perm = [i for i in range(2, self._dimension + 1)]
        random.shuffle(perm)
        self.pos = Position(perm)

    def __update_velocity(self, omega: float, c1: float, c2: float) -> None:
        """
        根据gbest_pos和pbest_pos更新速度
        :return:
        """
        inertia = omega * (self.pbest_pos - self.pos)
        individual_experience = (c1 * random.random()) * (self.pbest_pos - self.pos)
        social_experience = (c2 * random.random()) * (self.gbest_pos - self.pos)
        self.vel = inertia + individual_experience + social_experience

    def update_pos(self, omega: float, c1: float, c2: float):
        """
        根据速度更新粒子的位置
        :param omega:
        :param c1:
        :param c2:
        :return:
        """
        self.__update_velocity(omega, c1, c2)
        self.pos = self.pos + self.vel

算法性能测试

超参数

作为简单测试,并没有对超参数进行特别调优,按照经验选取超参数如下:

测试结果

这里我选择了4个不同点数的问题进行测试,对每个数据集,运行5次算法,下表中列出了最佳值和平均值,计算gap时使用的是5次平均结果:

结果讨论

在所有的计算中,算法都已经达到了收敛,对于A-32-k5数据集的一次计算中的迭代过程如下:

对应的路径图如下:

可以看到,即使对于这样一个节点数比较少的问题,从图像上看得到的路径也和最有路径相去甚远,可以看到不少的路径交叉出现,这也是因为我们没有在算法中加入opt这样的local search机制。

总结

  • 整数编码的PSO提供了一套对速度和位置以及其相关运算的定义,拓展了PSO的可用范围,看着还是比较有意思的
  • 虽然编码方式比较简单,但是由于定义了一整套的相关运算,其实现还是相对复杂的,而且换位减的时间复杂度也比较高,从效率上并不是非常好的选择
  • 仅从编码方式看,也存在一定的问题,例如说[3,2,1,4][4,1,2,3],虽然在定义上是两个不同的位置,但是实际上代表的路径的总距离是相同的(symmetric edge的情况下);这可能会让解在两个局部最优之间摆动,尽管这两个局部最优实际上是同一回事
  • 从结果上看,总体上整数编码的PSO在不添加额外搜索机制的情况下,只能说可以用于求解,但是其相对于最优结果的gap是较大的,也就是说单独这套方法的实用性并不高,甚至比不上一些简单的启发式方法
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

粒子群算法组卷_CVRP问题求解(一)整数编码的粒子群算法 的相关文章

  • 数据结构---AVL树

    AVL树 AVL树的概念 AVL树节点的定义 AVL树的插入 源代码 AVL树的概念 二叉搜索树虽然可以缩短查找的效率 但是 如果数据有序或接近有序二叉搜索树将退化为单支树 查找元素相当于在顺序表中搜索元素 效率就会变低 因此 两位俄罗斯的
  • 基于NI_TestStand的智能驾驶自动化测试

    在汽车产业不断发展的今天 智能驾驶已经成为了汽车中必不可少的一部分 虽然目前真正的无人驾驶技术还未广泛应用于我们的日常生活中 但各式各样的驾驶辅助系统 如碰撞预警 自动刹车 自适应巡航等功能已经在为我们的驾驶员保驾护航 今天小编就带大家一起
  • deepin v23

    deepin v23虚拟机windows远程控制 仅限内网 解决deepin在虚拟机中鼠标卡顿延迟问题 需要安装x11vnc和xrdp 1 安装ssh 2 安装x11vnc 2 1 x11vnc配置开机自启 3 安装xrdp 3 1 打开终
  • ffmpeg rtsp 推流_RTSP网络摄像头 WEB端播放 并实时人脸检测

    彩色视频为摄像头的原始数据 灰色视频 灰度化 缩放 用来检测人脸 人脸图片为比对成功后回显 项目地址 https github com 15225845996 rtsp face 功能描述 1 浏览器实时播放摄像头信息 2 实时人脸检测 圈
  • Window主机加固

    win r 输入cmd进入命令提示符 用dir调出所有任务 cd 可以进入一个指定目录 cd 穿越或返回上一层 文件名有空格不连贯就是蓝标 箭头所指 没有空格的就是红色所指 它们的区别在于有空格是有双引号的 没有空格是没有的 切换盘的话 直
  • [数据分析与可视化] Python绘制数据地图2-GeoPandas地图可视化

    本文主要介绍GeoPandas结合matplotlib实现地图的基础可视化 GeoPandas是一个Python开源项目 旨在提供丰富而简单的地理空间数据处理接口 GeoPandas扩展了Pandas的数据类型 并使用matplotlib进
  • Excel单元格数值统计

    Excel单元格数值统计 Excel 工作表中对选定区域的数值进行统计的功能非常实用 仿照Excel的这个功能 请对给定表格中选中区域中的单元格进行求和统计 并输出统计结果 为简化计算 假设当前输入中每个单元格内容仅为数字或公式两种 如果为
  • 2021-08-02

    触发器 查询 删除 修改 一 什么是触发器 触发器 trigger 是SQL server 提供给程序员和数据分析员来保证数据完整性的一种方法 它是与表事件相关的特殊的存储过程 它的执行不是由程序调用 也不是手工启动 而是由事件来触发 二
  • 分割2021算法合集

    魔改nnU Net夺冠 2021 BraTS 脑肿瘤分割竞赛第一名解决方案 魔改nnU Net夺冠 2021 BraTS 脑肿瘤分割竞赛第一名解决方案 代码 https github com rixez Brats21 KAIST MRI
  • 电子信息工程考研:12大专业方向解读

    导读 模式识别与智能系统专业解读 通信与信息系统专业解读 电路与系统专业解读 信号与信息处理专业解读 电子与通信工程专业解读 电力电子与电力传动专业解读 光电信息工程专业解读 物理电子学专业解读 控制工程专业解读 集成电路工程专业解读 精密
  • mysql row()函数_详解mysql数据库binlog三种模式的区别(row,statement,mixed)

    概述 Mysql binlog日志有三种格式 分别为Statement MiXED 以及ROW 这三种格式之间有什么区别呢 下面先介绍下各自的优缺点 ROW 日志中会记录成每一行数据被修改的形式 然后在slave端再对相同的数据进行修改 只
  • 5.12 树和森林的遍历

    一 树的遍历 1 先根遍历 根左右 深度优先遍历 若树非空 先访问根节点 再依次对每棵子树进行先根遍历 树的先根遍历 void PreOrder TreeNode R if R NULL visit R 访问根结点 while R还有下一棵
  • 动态图分类:DySAT算法及其Python实现

    动态图分类 DySAT算法及其Python实现 动态图分类是计算机视觉领域的一个重要任务 其目标是对动态图像序列进行分类 DySAT算法是一种基于结构Self Attention和时域Self Attention的深度学习模型 用于解决动态
  • 在阿里云里面服务器怎么样可以更好的链接数据库

    环境 阿里云ubuntu服务器 阿里云RDS数据库 问题 如何在阿里云服务器的终端使用shell命令连接RDS云数据库 解决方法 1 阿里云服务器安装MySQL sudo apt get install mysql server 如果出现u
  • 非标准包 game.rgss3a 的打开方法

    写在前面 最近在玩 RPG 游戏 想拆一个 Game rgss3a 包 在网上找了很久的拆包方法 感觉写的比较凌乱 我来给大家整理一下吧 不过我本人的技术能力也很差 不确定说的是不是对的 就当是给大家提供几个方法 大家都自己试一下吧 先说
  • 近源渗透学习

    一 近源渗透 近源渗透测试是网络空间安全领域逐渐兴起的一种新的安全评估手段 它是一种集常规网络攻防 物理接近 社会工程学及无线电通信攻防等能力于一体的高规格网络安全评估行动 网络安全评估小组在签订渗透测试授权协议后 通过乔装 社工等方式实地
  • git 常用命令---修改Git默认编辑器为vim

    1 配置 git config global user email you example com 配置git用户名 git config global user name Your Name 配置git邮件 git config glob
  • C++类使用未定义类型 use undefined class

    a h file include
  • [论文笔记]AutoAssign 阅读笔记

    AutoAssign 阅读笔记 AutoAssign Differentiable Label Assignment for Dense Object Detection 摘要 1 引言 2 相关工作 固定标签分配 Fixed Label

随机推荐

  • Vue.js 生命周期函数

    系列文章目录 Vue js基础简答题 文章目录 系列文章目录 前言 一 创建阶段 1 beforeCreate 2 created 3 beforeMount 4 mounted 二 运行阶段 1 beforeUpdate 2 update
  • 字符设备驱动详解(主次设备号、注册/卸载字符设备驱动、创建设备节点、地址映射)

    1 主次设备号 1 主次设备号是内核用来索引设备的 每个主次设备号在内核中都是唯一的 每个注册的设备都有一个分配的主次设备号 2 同一个主设备号可以有多个从设备号 主设备是对应的驱动程序 次设备号对应设备文件所指的设备 一个Soc可能接同样
  • Odoo进销存(采购、销售、仓库)入门教程 - 上

    运行环境 Ubuntu14 04 Odoo8 0 作者 苏州 微尘 0 前言 Odoo OpenERP 作为一款优秀的开源ERP软件 开发历史已有10年之久 随着系统的发展成熟 已有越来越多的公司借助Odoo管理日常业务的方方面面 本文以一
  • undo表空间故障特殊恢复(一)

    author skate time 2010 09 09 undo表空间故障特殊恢复 一 这个测试的是instance recover 单实例里就是crash recovery 的恢复不需要故障undo里的数据 一般的情况instance
  • python修改字典内key对应的值的代码

    下面代码段是关于python修改字典内key对应的值的代码 希望对码农有用 d2 spam 2 ham 1 eggs 3 make a dictionary print d2 order is scrambled d2 ham grill
  • python爬虫网页编码问题——网页gbk编码

    爬虫的时候遇到一个网页的编码是有问题 添加了这句 没问题了 20210124 21 34 response encoding gbk
  • 基于Linux开发python项目

    在某些公司要求中 我们不会直接在Windows系统上做项目的开发 有时候会采用在linux系统上开发 而这分为两种情况 1 直接在本地搭建虚拟机 虚拟机上面装centos镜像 项目运行在本地虚拟机上 大部分原因都是项目的某些依赖包在Wind
  • 4 业务分析师

    在每个软件项目中 都有人在显式或隐式地扮演业务分析师 BA 的角色 业务分析师是能够在组织中促进变化的人 他们通过定义需求和向干系人推荐有价值的解决方案来促进这些变化 分析师获取和分析他人的观点 将收集到的信息转换为需求规范说明 并于其他干
  • 如何从无序链表中移除重复项--Java版

    题目描述 给定一个没有排序的链表 去掉其重复项 并保留原顺序 如链表1 gt 3 gt 1 gt 5 gt 5 gt 7 去掉重复项变为1 gt 3 gt 5 gt 7 方法一 顺序删除 思路 通过双重循环直接在链表上执行删除操作 外层循环
  • 对习乐app的某课程的所有题目爬取

    这学期就想把习乐题库刷空 一直没时间弄 期末来了 课少了 搞起来 习乐好像是一个一个学长写的app 但是对不住了 增加了点垃圾数据 23333 思路 1 手机或模拟器抓包 分析提交自测数据包 查看试卷数据包 2 模拟上面的数据包 3 清洗数
  • Linux下ntpdate时间同步

    原文地址 http gaoxingf blog 51cto com 612518 121959 作者 高兴F Linux下ntpdate时间同步 Ntp服务器安装配置 RedHat服务器可以下载rpm安装包 然后执行 rpm ivh ntp
  • Linux安装MySQL

    Linux安装MySQL 链接 MySQL官网9 7 18的下载 查看是否已经安装了mariadb 检查linux是否安装了mariadb数据库 mariadb数据库是mysql的分支 是免费开源的 mariadb和msyql会有冲突 首先
  • vue中用echart写饼状图

    用echart饼状图实现男女比例 效果图如下 实现代码如下
  • 静态代码扫描工具汇总

    一 概述 在软件开发过程中 开发团队往往要花费大量的时间和精力发现并修改代码缺陷 传统的代码评审 同事复审 通过人工方式来检查缺陷仍然是一件耗时耗力的事情 而静态代码扫描工具能够在代码构建过程中帮助开发人员快速 有效的定位代码缺陷并及时纠正
  • Qt 设置窗口背景图片的几种方法

    1 在paintEvent事件中绘制图片 void Widget paintEvent QPaintEvent ev QPainter painter this painter drawPixmap rect QPixmap bg jpg
  • k8s集群中部署微服务项目前端代理服务 Nginx

    k8s集群中部署微服务项目前端代理服务 Nginx 一 微服务项目静态资源准备 mkdir sangomall proxy cd sangomall proxy root k8s master01 sangomall proxy ls co
  • 记录开发遇到的问题

    这里写目录标题 一 React 1 ref和wrappedComponentRef使用区别 https blog csdn net weixin 38009285 article details 119420763 2 umi中其他页面跳转
  • ctfshow web 练习记录(1,2)

    web1 查看源代码 base64解码 web2 sql注入 使用万能公式username 1 or 1 1 passwd 123 有回显 再使用order by 查询列数 username 1 or 1 1 order by 1 到4没有
  • 国内访问github速度过慢的问题解决

    1 在浏览器上输入网址 http tool chinaz com dns 2 查询http github com 3 找到TTL值最低的响应IP 比如IP20 32 253 113的TTL值最低你就选这个IP 4 打开我的电脑 进入到C W
  • 粒子群算法组卷_CVRP问题求解(一)整数编码的粒子群算法

    CVRP问题求解 一 整数编码的粒子群算法 粒子群算法概述 粒子群算法 Particle Swarm Optimization 是由鸟群捕食得到启发的一种算法 在鸟类觅食过程中 每只鸟都会利用自身经验和群体信息来寻找食物 在觅食过程中 每只