python遗传算法(详解)

article/2025/10/2 1:24:37

学习代码来源于:遗传算法python

一.主要思想

遗传算法是根据达尔文的“适者生存,优胜劣汰”的思想来找到最优解的额,其特点是所找到的解是全局最优解,相对于蚁群算法可能出现的局部最优解还是有优势的。

二.主要名词

个体(染色体):一个染色体代表一个具体问题的一个解,一个染色体包含若干基因。

基因:一个基因代表具体问题解的一个决策变量。种群:多个个体(染色体)构成一个种群。即一个问题的多组解构成了解的种群。

我们的目的就是让种群中”优胜劣汰“,最终只剩下一个最优解。接下来介绍最基本遗传算法,只用了选择,交叉,变异三种遗传算子。

三.主要步骤

1)种群初始化。我们需要首先通过随机生成的方式来创造一个种群,一般该种群的数量为100~500,这里我们采用二进制将一个染色体(解)编码为基因型。随后用进制转化,将二进制的基因型转化成十进制的表现型。

2)适应度计算(种群评估)。这里我们直接将目标函数值作为个体的适应度。

3)选择(复制)操作。根据种群中个体的适应度大小,通过轮盘赌等方式将适应度高的个体从当前种群中选择出来。其中轮盘赌即是与适应度成正比的概率来确定各个个体遗传到下一代群体中的数量。

      具体步骤如下:

     (1)首先计算出所有个体的适应度总和Σfi。

     (2)其次计算出每个个体的相对适应度大小fi/Σfi,类似于softmax。

     (3)再产生一个0到1之间的随机数,依据随机数出现在上述哪个概率区域内来确定各个个体被选中的次数。

4)交叉(交配)运算。该步骤是遗传算法中产生新的个体的主要操作过程,它用一定的交配概率阈值(pc,一般是0.4到0.99)来控制是否采取单点交叉,多点交叉等方式生成新的交叉个体。

     具体步骤如下:

     (1)先对群体随机配对。

     (2)再随机设定交叉点的位置。

     (3)再互换配对染色体间的部分基因。 

5)变异运算。该步骤是产生新的个体的另一种操作。一般先随机产生变异点,再根据变异概率阈值(pm,一般是0.0001到0.1)将变异点的原有基因取反。

6)终止判断。如果满足条件(迭代次数,一般是200~500)则终止算法,否则返回step2。

四.代码实现

1.种群初始化     

(1)随机生成若干个数的二进制染色体。

# -*-coding:utf-8 -*-
#目标求解2*sin(x)+cos(x)最大值
import random
import math
import matplotlib.pyplot as plt
#初始化生成chromosome_length大小的population_size个个体的二进制基因型种群
def species_origin(population_size,chromosome_length):population=[[]]#二维列表,包含染色体和基因for i in range(population_size):temporary=[]#染色体暂存器for j in range(chromosome_length):temporary.append(random.randint(0,1))#随机产生一个染色体,由二进制数组成population.append(temporary)#将染色体添加到种群中return population[1:]# 将种群返回,种群是个二维数组,个体和染色体两维

(2)编码 

将二进制的染色体基因型编码成十进制的表现型。

#从二进制到十进制#input:种群,染色体长度
def translation(population,chromosome_length):temporary=[]for i in range(len(population)):total=0for j in range(chromosome_length):total+=population[i][j]*(math.pow(2,j))#从第一个基因开始,每位对2求幂,再求和# 如:0101 转成十进制为:1 * 20 + 0 * 21 + 1 * 22 + 0 * 23 = 1 + 0 + 4 + 0 = 5temporary.append(total)#一个染色体编码完成,由一个二进制数编码为一个十进制数return temporary# 返回种群中所有个体编码完成后的十进制数

2.适应度计算

个体适应度与其对应的个体表现型x的目标函数值相关联,x越接近于目标函数的最优点,其适应度越大,从而其存活的概率越大。反之适应度越小,存活概率越小。这就引出一个问题关于适应度函数的选择,本例中,函数值总取非负值(删去了。。。),以函数最大值为优化目标,故直接将目标函数作为适应度函数。这里我们直接将目标函数2*sin(x)+cos作为个体适应度。如果,你想优化的是多元函数的话,需要将个体中基因型的每个变量提取出来,分别带入目标函数。比如说:我们想求x1+lnx2的最大值。基因编码为4位编码,其中前两位是x1,后两位是x2。那么我们在求适应度的时候,需要将这两个值分别带入f(x1)=x,f(x2)=lnx。再对f(x1)和f(x2)求和得到此个体的适应度,具体的在此篇中有详解。在本篇中,虽然染色体长度为10,但是实际上只有一个变量。

# 目标函数相当于环境 对染色体进行筛选,这里是2*sin(x)+cos(x)
def function(population,chromosome_length,max_value):temporary=[]function1=[]temporary=translation(population,chromosome_length)# 暂存种群中的所有的染色体(十进制)for i in range(len(temporary)):x=temporary[i]*max_value/(math.pow(2,chromosome_length)-1)#一个基因代表一个决策变量,其算法是先转化成十进制,然后再除以2的基因个数次方减1(固定值)。function1.append(2*math.sin(x)+math.cos(x))#这里将2*sin(x)+cos(x)作为目标函数,也是适应度函数return function1

关于这里的x的生成方式,据资料说只是一个编码规则。于是,我对其进行了几种实验。

如下,这种是删了max_value的输出结果:


这种少了除号后面的结果:


这种是只保留temporay[i]的结果:


从以上结果我们可以看出,这几种结果对最后的优化结果都没有什么影响。但是对其优化速度和平滑性都有影响。这也正是适应度函数选择的意义,选的好的话就可以加快优化效果。

补充:2018.6.16

由下面的选择操作可知,适应度是选择操作的主要参考依据,适应度函数(Fitness Function)的选取直接影响到遗传算法的收敛速度以及能否找到最优解。因而适应度函数的选择问题在遗传算法中是一项很值得研究的课题。一般情况下,关于适应度与目标函数的选择有以下这两种关系:


也就是说,我们要在每一轮迭代(进化)时,要将所有个体的适应度函数值都要遍历,然后得到最/大小值。此时每一轮的适应度函数都是在变化的。之前,我们程序中的个体适应度函数是不变化的。实际上要得到更准确的结果,除了以上基本变化,还有以下的适应度变化方法:


我们对个体的适应度调整的目的有两个:

一是维持个体之间的合理差距,加速竞争。

二是避免个体之间的差距过大,限制竞争

此外,还有适应度共享等调节方式,此处不再赘述。来自于,选择和适应度函数。

另外,在这段程序中,采用一种巧妙的方式限定了表现型的大小。比如,我们这里限制最大值为30,基因长度为6,则30/(2**6-1)=0.47,我们这里取一个表现型的最大值-2**6=64,则64*0.47=30.47,大致(这个词..有点不好意思说出来)符合我们的限制范围。

3.选择操作

(1).只保留非负值的适应度/函数值(不小于0)

def fitness(function1):fitness1=[]min_fitness=mf=0for i in range(len(function1)):if(function1[i]+mf>0):temporary=mf+function1[i]else:temporary=0.0# 如果适应度小于0,则定为0fitness1.append(temporary)#将适应度添加到列表中return fitness1

(2).首先计算出所有个体的适应度总和Σfi

#计算适应度和
def sum(fitness1):total=0for i in range(len(fitness1)):total+=fitness1[i]return total#计算适应度斐波纳挈列表,这里是为了求出累积的适应度
def cumsum(fitness1):for i in range(len(fitness1)-2,-1,-1):# range(start,stop,[step])# 倒计数total=0j=0while(j<=i):total+=fitness1[j]j+=1#这里是为了将适应度划分成区间fitness1[i]=totalfitness1[len(fitness1)-1]=1

(3).再产生一个0到1之间的随机数,依据随机数出现在上述哪个概率区域内来确定各个个体被选中的次数。

#3.选择种群中个体适应度最大的个体
def selection(population,fitness1):new_fitness=[]#单个公式暂存器total_fitness=sum(fitness1)#将所有的适应度求和for i in range(len(fitness1)):new_fitness.append(fitness1[i]/total_fitness)#将所有个体的适应度概率化,类似于softmaxcumsum(new_fitness)#将所有个体的适应度划分成区间ms=[]#存活的种群population_length=pop_len=len(population)#求出种群长度#根据随机数确定哪几个能存活for i in range(pop_len):ms.append(random.random())# 产生种群个数的随机值ms.sort()# 存活的种群排序fitin=0newin=0new_population=new_pop=population#轮盘赌方式while newin<pop_len:if(ms[newin]<new_fitness[fitin]):new_pop[newin]=pop[fitin]newin+=1else:fitin+=1population=new_pop

这里需要详细解释一下轮盘赌算法,其实就是典型的几何概率问题.这里根据cumsum函数将个体的适应度[0.1,0.2,0.2,0.4.....]都划分成区间[0.1,0.3,0.5,0.9...],如下图:


然后,random产生的ms[]排序后为[0.08,0.12,0.15,0.4.....],就有如下的程序:


我们可以看出新的种群是如下分布的:


这意味着某个体适应度越大,新的种群中该个体数量越多。

4.交叉

def crossover(population,pc):
#pc是概率阈值,选择单点交叉还是多点交叉,生成新的交叉个体,这里没用pop_len=len(population)for i in range(pop_len-1):cpoint=random.randint(0,len(population[0]))#在种群个数内随机生成单点交叉点temporary1=[]temporary2=[]temporary1.extend(pop[i][0:cpoint])temporary1.extend(pop[i+1][cpoint:len(population[i])])#将tmporary1作为暂存器,暂时存放第i个染色体中的前0到cpoint个基因,#然后再把第i+1个染色体中的后cpoint到第i个染色体中的基因个数,补充到temporary2后面temporary2.extend(pop[i+1][0:cpoint])temporary2.extend(pop[i][cpoint:len(pop[i])])# 将tmporary2作为暂存器,暂时存放第i+1个染色体中的前0到cpoint个基因,# 然后再把第i个染色体中的后cpoint到第i个染色体中的基因个数,补充到temporary2后面pop[i]=temporary1pop[i+1]=temporary2# 第i个染色体和第i+1个染色体基因重组/交叉完成

5.变异

#step4:突变
def mutation(population,pm):# pm是概率阈值px=len(population)# 求出种群中所有种群/个体的个数py=len(population[0])# 染色体/个体中基因的个数for i in range(px):if(random.random()<pm):#如果小于阈值就变异mpoint=random.randint(0,py-1)# 生成0到py-1的随机数if(population[i][mpoint]==1):#将mpoint个基因进行单点随机变异,变为0或者1population[i][mpoint]=0else:population[i][mpoint]=1

6.其他

# 将每一个染色体都转化成十进制 max_value为基因最大值,为了后面画图用
def b2d(b,max_value,chromosome_length):total=0for i in range(len(b)):total=total+b[i]*math.pow(2,i)#从第一位开始,每一位对2求幂,然后求和,得到十进制数?total=total*max_value/(math.pow(2,chromosome_length)-1)return total#寻找最好的适应度和个体
def best(population,fitness1):px=len(population)bestindividual=[]bestfitness=fitness1[0]for i in range(1,px):# 循环找出最大的适应度,适应度最大的也就是最好的个体if(fitness1[i]>bestfitness):bestfitness=fitness1[i]bestindividual=population[i]return [bestindividual,bestfitness]

7.主程序

population_size=500
max_value=10
# 基因中允许出现的最大值
chromosome_length=10
pc=0.6
pm=0.01results=[[]]
fitness1=[]
fitmean=[]population=pop=species_origin(population_size,chromosome_length)
#生成一个初始的种群for i in range(population_size):#注意这里是迭代500次function1=function(population,chromosome_length,max_value)fitness1=fitness(function1)best_individual,best_fitness=best(population,fitness1)results.append([best_fitness,b2d(best_individual,max_value,chromosome_length)])#将最好的个体和最好的适应度保存,并将最好的个体转成十进制selection(population,fitness1)#选择crossover(population,pc)#交配mutation(population,pm)#变异results=results[1:]
results.sort()
X=[]
Y=[]
for i in range(500):#500轮的结果X.append(i)Y.append(results[i][0])
plt.plot(X,Y)
plt.show()
8.迭代结果

我们可以看到最后经过500轮的迭代后,其结果已经非常接近2.2了。


9.完整代码

# -*-coding:utf-8 -*-
#目标求解2*sin(x)+cos(x)最大值
import random
import math
import matplotlib.pyplot as plt
class GA(object):
#初始化种群 生成chromosome_length大小的population_size个个体的种群def __init__(self,population_size,chromosome_length,max_value,pc,pm):self.population_size=population_sizeself.choromosome_length=chromosome_length# self.population=[[]]self.max_value=max_valueself.pc=pcself.pm=pm# self.fitness_value=[]def species_origin(self):population=[[]]for i in range(self.population_size):temporary=[]#染色体暂存器for j in range(self.choromosome_length):temporary.append(random.randint(0,1))#随机产生一个染色体,由二进制数组成population.append(temporary)#将染色体添加到种群中return population[1:]# 将种群返回,种群是个二维数组,个体和染色体两维#从二进制到十进制#编码  input:种群,染色体长度 编码过程就是将多元函数转化成一元函数的过程def translation(self,population):temporary=[]for i in range(len(population)):total=0for j in range(self.choromosome_length):total+=population[i][j]*(math.pow(2,j))#从第一个基因开始,每位对2求幂,再求和# 如:0101 转成十进制为:1 * 20 + 0 * 21 + 1 * 22 + 0 * 23 = 1 + 0 + 4 + 0 = 5temporary.append(total)#一个染色体编码完成,由一个二进制数编码为一个十进制数return temporary# 返回种群中所有个体编码完成后的十进制数#from protein to function,according to its functoin value#a protein realize its function according its structure
# 目标函数相当于环境 对染色体进行筛选,这里是2*sin(x)+math.cos(x)def function(self,population):temporary=[]function1=[]temporary=self.translation(population)for i in range(len(temporary)):x=temporary[i]*self.max_value/(math.pow(2,self.choromosome_length)-10)function1.append(2*math.sin(x)+math.cos(x))#这里将sin(x)作为目标函数return function1#定义适应度def fitness(self,function1):fitness_value=[]num=len(function1)for i in range(num):if(function1[i]>0):temporary=function1[i]else:temporary=0.0# 如果适应度小于0,则定为0fitness_value.append(temporary)#将适应度添加到列表中return fitness_value#计算适应度和def sum(self,fitness_value):total=0for i in range(len(fitness_value)):total+=fitness_value[i]return total#计算适应度斐伯纳且列表def cumsum(self,fitness1):for i in range(len(fitness1)-2,-1,-1):# range(start,stop,[step])# 倒计数total=0j=0while(j<=i):total+=fitness1[j]j+=1fitness1[i]=totalfitness1[len(fitness1)-1]=1#3.选择种群中个体适应度最大的个体def selection(self,population,fitness_value):new_fitness=[]#单个公式暂存器total_fitness=self.sum(fitness_value)#将所有的适应度求和for i in range(len(fitness_value)):new_fitness.append(fitness_value[i]/total_fitness)#将所有个体的适应度正则化self.cumsum(new_fitness)#ms=[]#存活的种群population_length=pop_len=len(population)#求出种群长度#根据随机数确定哪几个能存活for i in range(pop_len):ms.append(random.random())# 产生种群个数的随机值# ms.sort()# 存活的种群排序fitin=0newin=0new_population=new_pop=population#轮盘赌方式while newin<pop_len:if(ms[newin]<new_fitness[fitin]):new_pop[newin]=population[fitin]newin+=1else:fitin+=1population=new_pop#4.交叉操作def crossover(self,population):
#pc是概率阈值,选择单点交叉还是多点交叉,生成新的交叉个体,这里没用pop_len=len(population)for i in range(pop_len-1):if(random.random()<self.pc):cpoint=random.randint(0,len(population[0]))#在种群个数内随机生成单点交叉点temporary1=[]temporary2=[]temporary1.extend(population[i][0:cpoint])temporary1.extend(population[i+1][cpoint:len(population[i])])#将tmporary1作为暂存器,暂时存放第i个染色体中的前0到cpoint个基因,#然后再把第i+1个染色体中的后cpoint到第i个染色体中的基因个数,补充到temporary2后面temporary2.extend(population[i+1][0:cpoint])temporary2.extend(population[i][cpoint:len(population[i])])# 将tmporary2作为暂存器,暂时存放第i+1个染色体中的前0到cpoint个基因,# 然后再把第i个染色体中的后cpoint到第i个染色体中的基因个数,补充到temporary2后面population[i]=temporary1population[i+1]=temporary2# 第i个染色体和第i+1个染色体基因重组/交叉完成def mutation(self,population):# pm是概率阈值px=len(population)# 求出种群中所有种群/个体的个数py=len(population[0])# 染色体/个体基因的个数for i in range(px):if(random.random()<self.pm):mpoint=random.randint(0,py-1)#if(population[i][mpoint]==1):#将mpoint个基因进行单点随机变异,变为0或者1population[i][mpoint]=0else:population[i][mpoint]=1#transform the binary to decimalism
# 将每一个染色体都转化成十进制 max_value,再筛去过大的值def b2d(self,best_individual):total=0b=len(best_individual)for i in range(b):total=total+best_individual[i]*math.pow(2,i)total=total*self.max_value/(math.pow(2,self.choromosome_length)-1)return total#寻找最好的适应度和个体def best(self,population,fitness_value):px=len(population)bestindividual=[]bestfitness=fitness_value[0]# print(fitness_value)for i in range(1,px):# 循环找出最大的适应度,适应度最大的也就是最好的个体if(fitness_value[i]>bestfitness):bestfitness=fitness_value[i]bestindividual=population[i]return [bestindividual,bestfitness]def plot(self, results):X = []Y = []for i in range(500):X.append(i)Y.append(results[i][0])plt.plot(X, Y)plt.show()def main(self):results = [[]]fitness_value = []fitmean = []population = pop = self.species_origin()for i in range(500):function_value = self.function(population)# print('fit funtion_value:',function_value)fitness_value = self.fitness(function_value)# print('fitness_value:',fitness_value)best_individual, best_fitness = self.best(population,fitness_value)results.append([best_fitness, self.b2d(best_individual)])# 将最好的个体和最好的适应度保存,并将最好的个体转成十进制,适应度函数self.selection(population,fitness_value)self.crossover(population)self.mutation(population)results = results[1:]results.sort()self.plot(results)if __name__ == '__main__':population_size=400max_value=10chromosome_length=20pc=0.6pm=0.01ga=GA(population_size,chromosome_length,max_value,pc,pm)ga.main()

10.参考文献:

1.西安电子科学技术大学, 尚荣华. 选择和适应度函数[EB/OL].

https://wenku.baidu.com/view/d4fd8ab20129bd64783e0912a216147917117e11.html.

2.百度百科. 适应度函数[EB/OL]. https://baike.baidu.com/item/适应度函数/20593164?fr=aladdin.

希望有志同道合的小伙伴关注我的公众平台,欢迎您的批评指正,共同交流进步。



http://chatgpt.dhexx.cn/article/BAYgYH9r.shtml

相关文章

DH算法、DHE算法、ECDHE算法演进

ECDHE 算法解决了 RSA 算法不具备前向安全的性质 和 DH 算法效率低下的问题。 ECDHE 算法具有前向安全。所以被广泛使用。 由什么演变而来 DH 算法 -- > DHE 算法 -- > ECDHE 算法 DH 算法是非对称加密算法&#xff0c;该算法的核心数学思想是离散对数。 核心数学思…

DH 算法思想 SSH解决内容篡改问题

DH算法用于交换密钥 交换密钥的目的是生成仅双方共享的密钥 交换密钥的基本过程&#xff1a; 双方确定公开的内容用各自的私钥分别对公共内容加密&#xff08;加密本质就是数学运算&#xff09;并发送给对方这时双方使用自己的密钥对收到的内容加密&#xff08;要设计运算保证…

ECDH算法详解

ECDH算法详解 ECDH算法详解DH密钥交换原理结合ECC椭圆曲线算法ECDSA签名算法 参考资料 ECDH算法详解 DH密钥交换原理 进一步解释&#xff1a; 两端&#xff08;Alice 和 Bob&#xff09;想要安全的交换信息并且第三方不能获取到该信息。当然这也是TLS协议中的目的之一&#xf…

DH算法(密钥交换算法)

一 对称加密缺点 密钥传递过程复杂&#xff0c;这是对称加密带来的困扰。 二 DH密钥交换算法特点 构建本地密钥 双方密钥一致 三 DH相关参数 四 DH算法实现过程 1、初始化发送方的密钥&#xff08;KeyPairGenerator、KeyPair、PublicKey&#xff09; 2、初始化接受方的密钥&…

SSL/TLS中的DH算法、DHE算法、 ECDHE算法介绍

❤️SSL/TLS专栏导航页❤️ 文章目录 1. DH算法简介2. DH算法协商流程3. DH算法证明4. SSL/TLS中的DH算法 1. DH算法简介 Diffie-Hellman密钥交换算法是在1976年由这两个人发明的算法。它可以在不安全的网络中&#xff0c;通过交换一些公开的信息协商出共享密钥&#xff0c;使…

一文读懂DH密钥交换算法

DH 算法是 Diffie和Hellman于1976年提出了一种的密钥交换协议。这种加密算法主要用于密钥的交换&#xff0c;可以在非安全信道下为双方创建通信密钥&#xff0c;通讯双方可以使用这个密钥进行消息的加密、解密&#xff0c;并且能够保证通讯的安全。 换而言之&#xff0c;算法希…

密钥协商算法的演变 —— RSA算法 - DH算法 - DHE算法 - ECDHE算法

文章目录 1. RSA算法RSA握手过程RSA秘钥协商算法最大的缺陷 2. DH算法3. DHE算法4. ECDHE算法ECDHE秘钥协商算法的TSL握手&#xff1a; 1. RSA算法 传统的 TLS 握⼿基本都是使⽤ RSA 算法来实现密钥交换的。在 RSA 密钥协商算法中&#xff0c;客户端会⽣成随机密钥&#xff0c…

openswan中DH算法说明

Author :Email : vip_13031075266163.comDate : 2021.01.11Copyright : 未经同意不得转载&#xff01;&#xff01;&#xff01;Version &#xff1a; openswan-2.6.51.5Reference&#xff1a;https://download.openswan.org/openswan/ 目录 1. ope…

DH法理解

旋转关节机器人 四个参数&#xff1a;a&#xff0c;α&#xff0c;d&#xff0c;θ 四个参数实际上是两组&#xff0c;先有a&#xff0c;α&#xff0c;再有d&#xff0c;θ。 a是两个转轴之间的距离&#xff08;Z轴&#xff09;&#xff0c;异面直线公垂线的长度&#xff0c;也…

DH算法及源码解读

【主流的密钥交换方式】 敏感数据信息安全传输需要对敏感信息加密&#xff0c;加密的密钥涉及到传输两端的密钥协商和交换&#xff0c;目前主要两种密钥交换的机制有&#xff1a; 1. 基于非对称密钥的实现&#xff1a;请求方用接收方的公钥加密自己的密钥&#xff0c;接收方用…

DH 加密算法的使用

DH 算法的介绍 上面介绍的 DES,3DES,AES 算法都是对称密码算法&#xff0c;所谓对称&#xff0c;在上面也解释了&#xff0c;就是加密和解密的过程中使用相同的密钥 。而现在将要介绍的是 DH 算法&#xff0c;属于非对称密码算法&#xff0c;根据对称密码的概念&#xff0c;很…

非对称加密 DH算法

DH算法简介 迪菲-赫尔曼密钥交换&#xff08;Diffie–Hellman key exchange&#xff0c;缩写为D-H&#xff09; 是一种安全协议。 它可以让双方在完全没有对方任何预先信息的条件下通过不安全信道创建起一个密钥。 这个密钥可以在后续的通讯中作为对称密钥来加密通讯内容。 迪…

DH算法 | Diffie-Hellman 密钥交换

概述&#xff1a; DH 算法又称“Diffie–Hellman 算法”&#xff0c;像往常的算法名字一样&#xff0c;这是用俩个数学牛人的名字来命名的算法&#xff0c;实现安全的密钥交换&#xff0c;通讯双方在完全没有对方任何预先信息的条件下通过不安全信道创建起一个密钥。 优点&am…

DH算法原理

DH算法原理 DH 是 Diffie-Hellman的首字母缩写&#xff0c;是Whitefield与Martin Hellman在1976年提出了一个的密钥交换协议。我个人倾向于称DH算法为 密钥协商协议而RSA算法是密钥交换算法。 本篇分为几个部分&#xff0c;第一个部分介绍一下密钥交换的场景&#xff1b;第二部…

DH、DHE、ECDHE加密算法

DH算法 离散对数 DH 算法是非对称加密算法&#xff0c; 因此它可以用于密钥交换&#xff0c;该算法的核心数学思想是离散对数。 对数运算&#xff1a; i l o g a b i log_{a}b iloga​b 离散对数是在对数运算的基础上加了「模运算」&#xff0c;也就说取余数&#xff0c;…

DH 算法原理

一、DH算法 DH 算法其实也叫作 Diffie - Hellman 密钥交换协议&#xff0c;是一个不安全的秘钥共享网络协议&#xff0c;无法避免中间人攻击。 二、DH算法的原理 假设 Ali 和 Bob 需要互相通信并共享秘钥 Ali 先给 Bob 一个明文共享参数 、 &#xff0c;此信息可以被任何人…

DH算法图解+数学证明

前几天和同事讨论IKE密钥交换流程时&#xff0c;提到了Diffie-Hellman交换。DH算法最主要的作用便是在不安全的网络上成功公共密钥(并未传输真实密钥)。但由于对于DH算法的数学原理则不清楚&#xff0c;因此私下对DH算法进行一个简单学习。 1. DH算法的交互流程&#xff1a; Al…

卷积神经网络(Convolutional Neural Networks,CNNS/ConvNets)

本文翻译自 Convolutional Neural Networks(CNNs / ConvNets)&#xff0c;更多内容请访问&#xff1a;http://cs231n.github.io/。 原来译文&#xff1a;https://blog.csdn.net/Consu_Yasin/article/details/78052411 卷积神经网络非常类似于普通的神经网络&#xff1a;它们都…

卷积神经网络CNNs的理解与体会

孔子说过&#xff0c;温故而知新&#xff0c;时隔俩月再重看CNNs&#xff0c;当时不太了解的地方&#xff0c;又有了新的理解与体会&#xff0c;特此记录下来。文章图片及部分素材均来自网络&#xff0c;侵权请告知。 卷积神经网络&#xff08;Convolutinal Neural Networks&a…

Gated-SCNN: Gated Shape CNNs for Semantic Segmentation论文笔记

论文介绍 作者认为之前的semantic segmentation的工作将所有信息都放入到了CNN的网络之中(这其中包含了颜色、边界、纹理等信息)&#xff0c;这不太理想&#xff0c;所以作者在regular stream的基础之上增加了一个shape stream的分支&#xff0c;通过利用门控卷积来控制使得sh…