精华内容
下载资源
问答
  • 遗传算法python代码

    2019-04-01 15:34:50
    解决的例子y=10*sin(5x)+7*cos(4x) 代码python3.6可以运行
  • 遗传算法python代码(附详细注释)

    千次阅读 2020-08-28 14:53:28
    遗传算法python代码(附详细注释) #代码参考:https://blog.csdn.net/ha_ha_ha233/article/details/91364937 import numpy as np #用于数据操作:【X = np.linspace(*X_BOUND, 100) #将列表传入收集参数,完成解包...

    遗传算法python代码(附详细注释)

    #代码参考:https://blog.csdn.net/ha_ha_ha233/article/details/91364937
    import numpy as np #用于数据操作:【X = np.linspace(*X_BOUND, 100)  #将列表传入收集参数,完成解包】【 Y = np.linspace(*Y_BOUND, 100)】【X, Y = np.meshgrid(X, Y)  #生成网格点坐标矩阵,每个二维矩阵表示一个维度】
    import matplotlib.pyplot as plt #用于画图,可画二维【fig = plt.figure()】、三维【ax = fig.add_subplot(111, projection='3d')】;亦可上色【ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap = plt.get_cmap('rainbow'))】
    from matplotlib import cm   #绘制3d曲面时用于给图上色:【ax.plot_surface(X, Y, Z, rstride = 1, cstride = 1, cmap = cm.coolwarm)】
    from mpl_toolkits.mplot3d import Axes3D #用于画三维图,将二维图变换为三维图: 【fig = plt.figure()】  【ax = Axes3D(fig)】
    
    
    DNA_SIZE = 24
    POP_SIZE = 200
    CROSSOVER_RATE = 0.8
    MUTATION_RATE = 0.005
    N_GENERATIONS = 50
    X_BOUND = [-3, 3]
    Y_BOUND = [-3, 3]
    
    
    def F(x, y):
        return 3 * (1 - x) ** 2 * np.exp(-(x ** 2) - (y + 1) ** 2) - 10 * (x / 5 - x ** 3 - y ** 5) * np.exp(
            -x ** 2 - y ** 2) - 1 / 3 ** np.exp(-(x + 1) ** 2 - y ** 2)
    
    
    def translateDNA(pop):  # pop表示种群矩阵,一行表示一个二进制编码表示的DNA,矩阵的行数为种群数目
        x_pop = pop[:, 1::2]  # 奇数列表示X
        y_pop = pop[:, ::2]  # 偶数列表示y
        '''
        dot()表示矩阵相乘;*表示点积与MATLAB.*相似
        '''
        # pop:(POP_SIZE,DNA_SIZE)*(DNA_SIZE,1) --> (POP_SIZE,1)
        x = x_pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) / float(2 ** DNA_SIZE - 1) * (X_BOUND[1] - X_BOUND[0]) + X_BOUND[0]   #dot()表示矩阵相乘;*表示点积与MATLAB.*相似
        y = y_pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) / float(2 ** DNA_SIZE - 1) * (Y_BOUND[1] - Y_BOUND[0]) + Y_BOUND[0]
        return x, y
    
    
    
        '''
        #最小值适应度函数
        def get_fitness(pop): 
    	    x,y = translateDNA(pop)
    	    pred = F(x, y)
    	    return -(pred - np.max(pred)) + 1e-3
        '''
    #最大值适应度函数
    def get_fitness(pop):
        x, y = translateDNA(pop)
        pred = F(x, y)
        '''
        #np.min用法
        import numpy as np  
        a = np.array([[1,5,3],[4,2,6]])  
        print(a.min()) #无参,所有中的最小值   print(min(a))
        print(a.min(0)) # axis=0; 每列的最小值  print(min(a, axis = 0))
        print(a.min(1)) # axis=1;每行的最小值  print(min(a, axis = 1))
        '''
        return (pred - np.min(pred)) + 1e-3  # 减去最小的适应度是为了防止适应度出现负数,通过这一步fitness的范围为[0, np.max(pred)-np.min(pred)]
    
    def select(pop, fitness):  # nature selection wrt pop's fitness
        idx = np.random.choice(np.arange(POP_SIZE), size=POP_SIZE, replace=True,p=(fitness) / (fitness.sum()))
        '''
        #np.random.choice()用法
        1、参数意思分别 是从a 中以概率P,随机选择3个, p没有指定的时候相当于是一致的分布,a为一维数组或int,如果是int,则生成随机样本,就好像a是np.arange(N)一样。
            a1 = np.random.choice(a=5, size=3, replace=False, p=None)
        2、非一致的分布,会以多少的概率提出来
            a2 = np.random.choice(a=5, size=3, replace=False, p=[0.2, 0.1, 0.3, 0.4, 0.0])
        replacement 代表的意思是抽样之后还放不放回去,如果是False的话,那么出来的三个数都不一样,如果是True的话, 有可能会出现重复的,因为前面的抽的放回去了。
        '''
        return pop[idx]
    
    
    def crossover_and_mutation(pop, CROSSOVER_RATE=0.8):
        new_pop = []
        for father in pop:  # 遍历种群中的每一个个体,将该个体作为父亲
            child = father  # 孩子先得到父亲的全部基因(这里我把一串二进制串的那些0,1称为基因)
            '''
            【1】 np.random.rand()
                注:使用方法与np.random.randn()函数相同 
                作用: 通过本函数可以返回一个或一组服从“0~1”均匀分布的随机样本值。随机样本取值范围是[0,1),不包括1。
            【2】np.random.randn(d0,d1,d2……dn) 
                1)当函数括号内没有参数时,则返回一个浮点数; 
                2)当函数括号内有一个参数时,则返回秩为1的数组,不能表示向量和矩阵; 
                3)当函数括号内有两个及以上参数时,则返回对应维度的数组,能表示向量或矩阵; 
                4)np.random.standard_normal()函数与np.random.randn()类似,但是np.random.standard_normal()
                的输入参数为元组(tuple). 
                5)np.random.randn()的输入通常为整数,但是如果为浮点数,则会自动直接截断转换为整数。
                作用:通过本函数可以返回一个或一组服从标准正态分布的随机样本值。
            【3】np.random.randint()
                numpy.random.randint(low, high=None, size=None, dtype=’l’) 
                输入: 
                low—–为最小值 
                high—-为最大值 
                size—–为数组维度大小 
                dtype—为数据类型,默认的数据类型是np.int。 
                返回值: 
                返回随机整数或整型数组,范围区间为[low,high),包含low,不包含high; 
                high没有填写时,默认生成随机数的范围是[0,low)
            更多详情:https://www.cnblogs.com/fpzs/p/10288239.html
            '''
            if np.random.rand() < CROSSOVER_RATE:  # 产生子代时不是必然发生交叉,而是以一定的概率发生交叉
                mother = pop[np.random.randint(POP_SIZE)]  # 再种群中选择另一个个体,并将该个体作为母亲
                cross_points = np.random.randint(low=0, high=DNA_SIZE * 2)  # 随机产生交叉的点
                child[cross_points:] = mother[cross_points:]  # 孩子得到位于交叉点后的母亲的基因
            mutation(child)  # 每个后代有一定的机率发生变异
            new_pop.append(child)
        return new_pop
    
    
    def mutation(child, MUTATION_RATE=0.003):
        if np.random.rand() < MUTATION_RATE:  # 以MUTATION_RATE的概率进行变异
            mutate_point = np.random.randint(0, DNA_SIZE*2)  # 随机产生一个实数,代表要变异基因的位置
            '''
            ^1表示异或(不同为1),实现反转
            '''
            child[mutate_point] = child[mutate_point] ^ 1  # 将变异点的二进制为反转
    
    
    def plot_3d(ax):
        X = np.linspace(*X_BOUND, 100)  #将列表传入收集参数,完成解包
        Y = np.linspace(*Y_BOUND, 100)
        X, Y = np.meshgrid(X, Y)  #生成网格点坐标矩阵,每个二维矩阵表示一个维度
        Z = F(X, Y)
        '''
        绘制3D曲面
        
        rstride:行之间的跨度  cstride:列之间的跨度
        rcount:设置间隔个数,默认50个,ccount:列的间隔个数  不能与上面两个参数同时出现
        
        cmap是颜色映射表
        # from matplotlib import cm
        # ax.plot_surface(X, Y, Z, rstride = 1, cstride = 1, cmap = cm.coolwarm)
        # cmap = "rainbow" 亦可
        我的理解的 改变cmap参数可以控制三维曲面的颜色组合, 一般我们见到的三维曲面就是 rainbow 的
        你也可以修改 rainbow 为 coolwarm, 验证我的结论
        '''
        ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap = plt.get_cmap('rainbow'))
        '''
        # 绘制从3D曲面到底部的投影,zdir 可选 'z'|'x'|'y'| 分别表示投影到z,x,y平面
        # zdir = 'z', offset = -2 表示投影到z = -2上
        ax.contour(X, Y, Z, zdir = 'z', offset = -2, cmap = plt.get_cmap('rainbow'))
        '''
        ax.contour(X, Y, Z, zdir='z', offset=-10, cmap=plt.get_cmap('rainbow'))
        # 设置z轴的维度,x,y类似
        ax.set_zlim(-10, 10)
        ax.set_xlabel('x')
        ax.set_ylabel('y')
        ax.set_zlabel('z')
        '''
        plt.pause(time)函数也能实现窗口绘图(不需要plt.show),但窗口只停留time时间便会自动关闭,然后再继续执行后面代码;
        plt.pause()会把它之前的所有绘图都绘制在对应坐标系中,而不仅仅是在当前坐标系中绘图;
        特别要注意的是,plt.pasue(0)将绘制之前的所有图像,且图像窗口不会自动关闭,但程序会停止在该语句所在位置,即使手动关闭窗口也不会继续执行后面的代码。
        '''
        #plt.pause(3) #显示图片,但最后会停顿一会儿后关闭
        '''
        这里的plt.show()主要与后面的plt.ioff()配合使用,否则最后的图会一闪而过不会停留
        '''
        plt.show()  #一直显示图片;最后不关闭图,代码不会结束运行
    
    
    def print_info(pop):
        fitness = get_fitness(pop)
        max_fitness_index = np.argmax(fitness)
        print("max_fitness:", fitness[max_fitness_index])
        x, y = translateDNA(pop)
        print("最优的基因型:", pop[max_fitness_index])
        print("(x, y):", (x[max_fitness_index], y[max_fitness_index]))
    
    
    if __name__ == "__main__":
        #定义figure
        fig = plt.figure()
        #创建3d图形的两种方式
        #将figure变为到3d
        #ax = Axes3D(fig)
        ax = fig.add_subplot(111, projection='3d')  #111表示1x1网格,第一子图
        plt.ion()  # 将画图模式改为交互模式,程序遇到plt.show不会暂停,而是继续执行
        plot_3d(ax)
    
        pop = np.random.randint(2, size=(POP_SIZE, DNA_SIZE * 2))  # matrix (POP_SIZE, DNA_SIZE)
        #numpy.random.randint(low, high=None, size=None, dtype='l')  函数的作用是,返回一个随机整型数,范围从低(包括)到高(不包括),即[low, high)。如果没有写参数high的值,则返回[0,low)的值。
        for _ in range(N_GENERATIONS):  # 迭代N代
            x, y = translateDNA(pop)
            if 'sca' in locals():  #当你定义了一堆变量,locals()就能看见里面有你定义的变量表
                sca.remove()
            sca = ax.scatter(x, y, F(x, y), c='black', marker='o');  #画散点图   https://blog.csdn.net/qiu931110/article/details/68130199/
            plt.show();
            plt.pause(0.1)
            pop = np.array(crossover_and_mutation(pop, CROSSOVER_RATE))
            # F_values = F(translateDNA(pop)[0], translateDNA(pop)[1])#x, y --> Z matrix
            fitness = get_fitness(pop)
            pop = select(pop, fitness)  # 选择生成新的种群
    
        print_info(pop)
        plt.ioff()  #如果在脚本中使用ion()命令开启了交互模式,没有使用ioff()关闭的话,则图像会一闪而过,并不会常留。要想防止这种情况,需要在plt.show()之前加上ioff()命令。
        plot_3d(ax)
    
    

    运行结果
    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • 遗传算法详解 附python代码实现

    万次阅读 多人点赞 2019-06-10 11:14:59
    遗传算法 遗传算法是用于解决最优化问题的一种搜索算法。从名字来看,遗传算法借用了生物学里达尔文的进化理论:”适者生存,不适者淘汰“,将该理论以算法的形式表现出来就是遗传算法的过程。 问题引入 上面提到...

    遗传算法

    遗传算法是用于解决最优化问题的一种搜索算法。从名字来看,遗传算法借用了生物学里达尔文的进化理论:”适者生存,不适者淘汰“,将该理论以算法的形式表现出来就是遗传算法的过程。

    问题引入

    上面提到遗传算法是用来解决最优化问题的,下面我将以求二元函数:

    def F(x, y):
    	return 3*(1-x)**2*np.exp(-(x**2)-(y+1)**2)- 10*(x/5 - x**3 - y**5)*np.exp(-x**2-y**2)- 1/3**np.exp(-(x+1)**2 - y**2)
    

    x[3,3],y[3,3]x\in[-3, 3], y\in[-3, 3]范围里的最大值为例子来详细讲解遗传算法的每一步。该函数的图像如下图:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    通过旋转视角可以发现,函数在这个局部的最大值大概在当x0,y1.5x \approx 0,y\approx1.5时,函数值取得最大值,这里的x,yx,y的取值就是我们最后要得到的结果。

    算法详解

    先直观看一下算法过程:

    寻找最小值:

    在这里插入图片描述

    寻找最大值
    在这里插入图片描述

    首先我们生成了200个随机的(x,y)对,将(x, y)坐标对带入要求解的函数F(x,y)中,根据适者生存,我们定义使得函数值F(x,y)越大的(x,y)对越适合环境,从而这些适应环境的(x,y)对更有可能被保留下来,而那些不适应该环境的(x,y)则有很大几率被淘汰,保留下来的点经过繁殖产生新的点,如此进化下去最后留下的大部分点都是试应环境的点,即在最高点附近。下图为算法执行结果,和上面的分析x0,y1.5x \approx 0,y\approx1.5相近。

    在这里插入图片描述

    种群和个体的概念

    遗传算法启发自进化理论,而我们知道进化是由种群为单位的,种群是什么呢?维基百科上解释为:在生物学上,是在一定空间范围内同时生活着的同种生物的全部个体。显然要想理解种群的概念,又先得理解个体的概念,在遗传算法里,个体通常为某个问题的一个解,并且该解在计算机中被编码为一个向量表示! 我们的例子中要求最大值,所以该问题的解为一组可能的(x,y)(x, y)的取值。比如(x=2.1,y=0.8),(x=1.5,y=2.3)...(x=2.1,y=0.8), (x=-1.5, y=2.3)...就是求最大值问题的一个可能解,也就是遗传算法里的个体,把这样的一组一组的可能解的集合就叫做种群 ,比如在这个问题中设置100个这样的x,yx,y的可能的取值对,这100个个体就构成了种群。

    编码、解码与染色体的概念

    在上面个体概念里提到个体(也就是一组可能解)在计算机程序中被编码为一个向量表示,而在我们这个问题中,个体是x,yx,y的取值,是两个实数,所以问题就可以转化为如何将实数编码为一个向量表示,可能有些朋友有疑惑,实数在计算机里不是可以直接存储吗,为什么需要编码呢?这里编码是为了后续操作(交叉和变异)的方便。实数如何编码为向量这个问题找了很多博客,写的都是很不清楚,看了莫烦python的教学代码,终于明白了一种实数编码、解码的方式。


    生物的DNA有四种碱基对,分别是ACGT,DNA的编码可以看作是DNA上碱基对的不同排列,不同的排列使得基因的表现出来的性状也不同(如单眼皮双眼皮)。在计算机中,我们可以模仿这种编码,但是碱基对的种类只有两种,分别是0,1。只要我们能够将不同的实数表示成不同的0,1二进制串表示就完成了编码,也就是说其实我们并不需要去了解一个实数对应的二进制具体是多少,我们只需要保证有一个映射
    y=f(x),x is decimal system,y is binary system y=f(x), x \ is\ decimal \ system, y \ is \ binary\ system
    能够将十进制的数编码为二进制即可,至于这个映射是什么,其实可以不必关心。将个体(可能解)编码后的二进制串叫做染色体染色体(或者有人叫DNA)就是个体(可能解)的二进制编码表示。为什么可以不必关心映射f(x)f(x)呢?因为其实我们在程序中操纵的都是二进制串,而二进制串生成时可以随机生成,如:

    #pop表示种群矩阵,一行表示一个二进制编码表示的DNA,矩阵的行数为种群数目,DNA_SIZE为编码长度,不理解乘2的看后文
    pop = np.random.randint(2, size=(POP_SIZE, DNA_SIZE*2)) #matrix (POP_SIZE, DNA_SIZE*2)
    

    实际上是没有需求需要将一个十进制数转化为一个二进制数,而在最后我们肯定要将编码后的二进制串转换为我们理解的十进制串,所以我们需要的是y=f(x)y=f(x)逆映射,也就是将二进制转化为十进制,这个过程叫做解码(很重要,感觉初学者不容易理解),理解了解码编码还难吗?先看具体的解码过程如下。

    首先我们限制二进制串的长度为10(长度自己指定即可,越长精度越高),例如我们有一个二进制串(在程序中用数组存储即可)
    [0,1,0,1,1,1,0,1,0,1] [0,1,0,1,1,1,0,1,0,1]
    ,这个二进制串如何转化为实数呢?不要忘记我们的x,y[3,3]x,y\in[-3,3]这个限制,我们目标是求一个逆映射将这个二进制串映射到x,y[3,3]x,y\in[-3,3]即可,为了更一般化我们将x,yx,y的取值范围用一个变量表示,在程序中可以用python语言写到:

    X_BOUND = [-3, 3] #x取值范围
    Y_BOUND = [-3, 3] #y取值范围
    

    为将二进制串映射到指定范围,首先先将二进制串按权展开,将二进制数转化为十进制数,我们有029+128+027+...+020+120=3730*2^9+1*2^8+0*2^7+...+0*2^0+1*2^0=373,然后将转换后的实数压缩到[0,1][0,1]之间的一个小数373/21010.36461388074373 / (2^{10}-1) \approx 0.36461388074,通过以上这些步骤所有二进制串表示都可以转换为[0,1][0,1]之间的小数,现在只需要将[0,1][0,1] 区间内的数映射到我们要的区间即可。假设区间[0,1][0,1]内的数称为num,转换在python语言中可以写成:

    #X_BOUND,Y_BOUND是x,y的取值范围 X_BOUND = [-3, 3], Y_BOUND = [-3, 3],
    x_ = num * (X_BOUND[1] - X_BOUND[0]) + X_BOUND[0] #映射为x范围内的数
    y_ = num * (Y_BOUND[1] - Y_BOUND[0]) + Y_BOUND[0] #映射为y范围内的数
    

    通过以上这些标记为蓝色的步骤我们完成了将一个二进制串映射到指定范围内的任务(解码)。

    现在再来看看编码过程。不难看出上面我们的DNA(二进制串)长为10,10位二进制可以表示2102^{10}种不同的状态,可以看成是将最后要转化为的十进制区间x,y[3,3]x,y\in[-3,3](下面讨论都时转化到这个区间)切分成2102^{10},显而易见,如果我们增加二进制串的长度,那么我们对区间的切分可以更加精细,转化后的十进制解也更加精确。例如,十位二进制全1按权展开为1023,最后映射到[-3, 3]区间时为3,而1111111110(前面9个1)按权展开为1022,1022/(2101)0.9990221022/(2^{10}-1) \approx 0.9990220.999022(3(3))+(3)2.9941340.999022*(3 - (-3)) + (-3)\approx2.994134;如果我们将实数编码为12位二进制,111111111111(12个1)最后转化为3,而111111111110(前面11个1)按权展开为4094,4094/(2121=4095)0.9997564094/(2^{12}-1=4095)\approx0.9997560.999755(3(3))+(3)2.9985340.999755*(3-(-3))+(-3)\approx2.998534;而32.994134=0.0058663-2.994134=0.00586632.998534=0.0014663-2.998534=0.001466,可以看出用10位二进制编码划分区间后,每个二进制状态改变对应的实数大约改变0.005866,而用12位二进制编码这个数字下降到0.001466,所以DNA长度越长,解码为10进制的实数越精确。

    以下为解码过程的python代码:

    这里我设置DNA_SIZE=24(一个实数DNA长度),两个实数x,yx,y一共用48位二进制编码,我同时将x和y编码到同一个48位的二进制串里,每一个变量用24位表示,奇数24列为x的编码表示,偶数24列为y的编码表示。

    def translateDNA(pop):#pop表示种群矩阵,一行表示一个二进制编码表示的DNA,矩阵的行数为种群数目
    	x_pop = pop[:,1::2]#奇数列表示X
    	y_pop = pop[:,::2] #偶数列表示y
        #pop:(POP_SIZE,DNA_SIZE)*(DNA_SIZE,1) --> (POP_SIZE,1)完成解码
        x = x_pop.dot(2**np.arange(DNA_SIZE)[::-1])/float(2**DNA_SIZE-1)*(X_BOUND[1]-X_BOUND[0])+X_BOUND[0]	
        y = y_pop.dot(2**np.arange(DNA_SIZE)[::-1])/float(2**DNA_SIZE-1)*(Y_BOUND[1]-Y_BOUND[0])+Y_BOUND[0]
        return x,y
    

    适应度和选择

    我们已经得到了一个种群,现在要根据适者生存规则把优秀的个体保存下来,同时淘汰掉那些不适应环境的个体。现在摆在我们面前的问题是如何评价一个个体对环境的适应度?在我们的求最大值的问题中可以直接用可能解(个体)对应的函数的函数值的大小来评估,这样可能解对应的函数值越大越有可能被保留下来,以求解上面定义的函数F的最大值为例,python代码如下:

    def get_fitness(pop): 
        x,y = translateDNA(pop)
    	pred = F(x, y)
    	return (pred - np.min(pred)) + 1e-3 #减去最小的适应度是为了防止适应度出现负数,通过这一步fitness的范围为[0, np.max(pred)-np.min(pred)],最后在加上一个很小的数防止出现为0的适应度
    

    pred是将可能解带入函数F中得到的预测值,因为后面的选择过程需要根据个体适应度确定每个个体被保留下来的概率,而概率不能是负值,所以减去预测中的最小值把适应度值的最小区间提升到从0开始,但是如果适应度为0,其对应的概率也为0,表示该个体不可能在选择中保留下来,这不符合算法思想,遗传算法不绝对否定谁也不绝对肯定谁,所以最后加上了一个很小的正数。

    有了求最大值的适应度函数求最小值适应度函数也就容易了,python代码如下:

    def get_fitness(pop): 
    	x,y = translateDNA(pop)
    	pred = F(x, y)
    	return -(pred - np.max(pred)) + 1e-3
    

    因为根据适者生存规则在求最小值问题上,函数值越小的可能解对应的适应度应该越大,同时适应度也不能为负值,先将适应度减去最大预测值,将适应度可能取值区间压缩为[np.min(pred)np.max(pred),0][np.min(pred)-np.max(pred), 0],然后添加个负号将适应度变为正数,同理为了不出现0,最后在加上一个很小的正数。

    有了评估的适应度函数,下面可以根据适者生存法则将优秀者保留下来了。选择则是根据新个体的适应度进行,但同时不意味着完全以适应度高低为导向(选择top k个适应度最高的个体,容易陷入局部最优解),因为单纯选择适应度高的个体将可能导致算法快速收敛到局部最优解而非全局最优解,我们称之为早熟。作为折中,遗传算法依据原则:适应度越高,被选择的机会越高,而适应度低的,被选择的机会就低。 在python中可以写做:

    def select(pop, fitness):    # nature selection wrt pop's fitness
        idx = np.random.choice(np.arange(POP_SIZE), size=POP_SIZE, replace=True,
                               p=(fitness)/(fitness.sum()) )
        return pop[idx]
    

    不熟悉numpy的朋友可以查阅一下这个函数,主要是使用了choice里的最后一个参数p,参数p描述了从np.arange(POP_SIZE)里选择每一个元素的概率,概率越高约有可能被选中,最后返回被选中的个体即可。

    交叉、变异

    通过选择我们得到了当前看来“还不错的基因”,但是这并不是最好的基因,我们需要通过繁殖后代(包含有交叉+变异过程)来产生比当前更好的基因,但是繁殖后代并不能保证每个后代个体的基因都比上一代优秀,这时需要继续通过选择过程来让试应环境的个体保留下来,从而完成进化,不断迭代上面这个过程种群中的个体就会一步一步地进化。

    具体地繁殖后代过程包括交叉和变异两步。交叉是指每一个个体是由父亲和母亲两个个体繁殖产生,子代个体的DNA(二进制串)获得了一半父亲的DNA,一半母亲的DNA,但是这里的一半并不是真正的一半,这个位置叫做交配点,是随机产生的,可以是染色体的任意位置。通过交叉子代获得了一半来自父亲一半来自母亲的DNA,但是子代自身可能发生变异,使得其DNA即不来自父亲,也不来自母亲,在某个位置上发生随机改变,通常就是改变DNA的一个二进制位(0变到1,或者1变到0)。

    需要说明的是交叉和变异不是必然发生,而是有一定概率发生。先考虑交叉,最坏情况,交叉产生的子代的DNA都比父代要差(这样算法有可能朝着优化的反方向进行,不收敛),如果交叉是有一定概率不发生,那么就能保证子代有一部分基因和当前这一代基因水平一样;而变异本质上是让算法跳出局部最优解,如果变异时常发生,或发生概率太大,那么算法到了最优解时还会不稳定。交叉概率,范围一般是0.6~1,突变常数(又称为变异概率),通常是0.1或者更小。

    python实现如下:

    def crossover_and_mutation(pop, CROSSOVER_RATE = 0.8):
    	new_pop = []
    	for father in pop:		#遍历种群中的每一个个体,将该个体作为父亲
    		child = father		#孩子先得到父亲的全部基因(这里我把一串二进制串的那些0,1称为基因)
    		if np.random.rand() < CROSSOVER_RATE:			#产生子代时不是必然发生交叉,而是以一定的概率发生交叉
    			mother = pop[np.random.randint(POP_SIZE)]	#再种群中选择另一个个体,并将该个体作为母亲
    			cross_points = np.random.randint(low=0, high=DNA_SIZE*2)	#随机产生交叉的点
    			child[cross_points:] = mother[cross_points:]		#孩子得到位于交叉点后的母亲的基因
    		mutation(child)	#每个后代有一定的机率发生变异
    		new_pop.append(child)
    
    	return new_pop
    
    def mutation(child, MUTATION_RATE=0.003):
    	if np.random.rand() < MUTATION_RATE: 				#以MUTATION_RATE的概率进行变异
    		mutate_point = np.random.randint(0, DNA_SIZE)	#随机产生一个实数,代表要变异基因的位置
    		child[mutate_point] = child[mutate_point]^1 	#将变异点的二进制为反转
    

    上面这些步骤即为遗传算法的核心模块,将这些模块在主函数中迭代起来,让种群去进化

    	pop = np.random.randint(2, size=(POP_SIZE, DNA_SIZE*2)) #生成种群 matrix (POP_SIZE, DNA_SIZE)
    	for _ in range(N_GENERATIONS):	#种群迭代进化N_GENERATIONS代
    		crossover_and_mutation(pop, CROSSOVER_RATE)	#种群通过交叉变异产生后代
    		fitness = get_fitness(pop)	#对种群中的每个个体进行评估
    		pop = select(pop, fitness) 	#选择生成新的种群
    

    附录

    完整代码

    
    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib import cm
    from mpl_toolkits.mplot3d import Axes3D
    
    DNA_SIZE = 24
    POP_SIZE = 200
    CROSSOVER_RATE = 0.8
    MUTATION_RATE = 0.005
    N_GENERATIONS = 50
    X_BOUND = [-3, 3]
    Y_BOUND = [-3, 3]
    
    
    def F(x, y):
    	return 3*(1-x)**2*np.exp(-(x**2)-(y+1)**2)- 10*(x/5 - x**3 - y**5)*np.exp(-x**2-y**2)- 1/3**np.exp(-(x+1)**2 - y**2)
    
    def plot_3d(ax):
    
    	X = np.linspace(*X_BOUND, 100)
    	Y = np.linspace(*Y_BOUND, 100)
    	X,Y = np.meshgrid(X, Y)
    	Z = F(X, Y)
    	ax.plot_surface(X,Y,Z,rstride=1,cstride=1,cmap=cm.coolwarm)
    	ax.set_zlim(-10,10)
    	ax.set_xlabel('x')
    	ax.set_ylabel('y')
    	ax.set_zlabel('z')
    	plt.pause(3)
    	plt.show()
    
    
    def get_fitness(pop): 
        x,y = translateDNA(pop)
    	pred = F(x, y)
    	return (pred - np.min(pred)) + 1e-3 #减去最小的适应度是为了防止适应度出现负数,通过这一步fitness的范围为[0, np.max(pred)-np.min(pred)],最后在加上一个很小的数防止出现为0的适应度
    
    
    def translateDNA(pop): #pop表示种群矩阵,一行表示一个二进制编码表示的DNA,矩阵的行数为种群数目
    	x_pop = pop[:,1::2]#奇数列表示X
    	y_pop = pop[:,::2] #偶数列表示y
    	
    	#pop:(POP_SIZE,DNA_SIZE)*(DNA_SIZE,1) --> (POP_SIZE,1)
    	x = x_pop.dot(2**np.arange(DNA_SIZE)[::-1])/float(2**DNA_SIZE-1)*(X_BOUND[1]-X_BOUND[0])+X_BOUND[0]
    	y = y_pop.dot(2**np.arange(DNA_SIZE)[::-1])/float(2**DNA_SIZE-1)*(Y_BOUND[1]-Y_BOUND[0])+Y_BOUND[0]
    	return x,y
    
    def crossover_and_mutation(pop, CROSSOVER_RATE = 0.8):
    	new_pop = []
    	for father in pop:		#遍历种群中的每一个个体,将该个体作为父亲
    		child = father		#孩子先得到父亲的全部基因(这里我把一串二进制串的那些0,1称为基因)
    		if np.random.rand() < CROSSOVER_RATE:			#产生子代时不是必然发生交叉,而是以一定的概率发生交叉
    			mother = pop[np.random.randint(POP_SIZE)]	#再种群中选择另一个个体,并将该个体作为母亲
    			cross_points = np.random.randint(low=0, high=DNA_SIZE*2)	#随机产生交叉的点
    			child[cross_points:] = mother[cross_points:]		#孩子得到位于交叉点后的母亲的基因
    		mutation(child)	#每个后代有一定的机率发生变异
    		new_pop.append(child)
    
    	return new_pop
    
    def mutation(child, MUTATION_RATE=0.003):
    	if np.random.rand() < MUTATION_RATE: 				#以MUTATION_RATE的概率进行变异
    		mutate_point = np.random.randint(0, DNA_SIZE*2)	#随机产生一个实数,代表要变异基因的位置
    		child[mutate_point] = child[mutate_point]^1 	#将变异点的二进制为反转
    
    def select(pop, fitness):    # nature selection wrt pop's fitness
        idx = np.random.choice(np.arange(POP_SIZE), size=POP_SIZE, replace=True,
                               p=(fitness)/(fitness.sum()) )
        return pop[idx]
    
    def print_info(pop):
    	fitness = get_fitness(pop)
    	max_fitness_index = np.argmax(fitness)
    	print("max_fitness:", fitness[max_fitness_index])
    	x,y = translateDNA(pop)
    	print("最优的基因型:", pop[max_fitness_index])
    	print("(x, y):", (x[max_fitness_index], y[max_fitness_index]))
    
    
    if __name__ == "__main__":
    	fig = plt.figure()
    	ax = Axes3D(fig)	
    	plt.ion()#将画图模式改为交互模式,程序遇到plt.show不会暂停,而是继续执行
    	plot_3d(ax)
    
    	pop = np.random.randint(2, size=(POP_SIZE, DNA_SIZE*2)) #matrix (POP_SIZE, DNA_SIZE)
    	for _ in range(N_GENERATIONS):#迭代N代
    		x,y = translateDNA(pop)
    		if 'sca' in locals(): 
    			sca.remove()
    		sca = ax.scatter(x, y, F(x,y), c='black', marker='o');plt.show();plt.pause(0.1)
    		pop = np.array(crossover_and_mutation(pop, CROSSOVER_RATE))
    		#F_values = F(translateDNA(pop)[0], translateDNA(pop)[1])#x, y --> Z matrix
    		fitness = get_fitness(pop)
    		pop = select(pop, fitness) #选择生成新的种群
    	
    	print_info(pop)
    	plt.ioff()
    	plot_3d(ax)
    
    展开全文
  • python遗传算法代码

    2018-11-05 13:52:00
    python遗传算法代码python遗传算法代码python遗传算法代码
  • 遗传算法python库Genetic algorithms (GA) are an optimization and search technique based on the principles of genetics and natural selection, in essence mimicking the natural evolution process that we ...

    遗传算法python库

    Genetic algorithms (GA) are an optimization and search technique based on the principles of genetics and natural selection, in essence mimicking the natural evolution process that we observe in life. Their general principle is based on the concept of having an initial population composed of several individuals — with each representing a particular solution to the problem — and allow it to evolve to a state that maximizes its overall fitness, using three main operators: selection, crossover and mutation. We’ll look into these aspects a bit more in detail below.

    遗传算法(GA)是一种基于遗传和自然选择原理的优化和搜索技术,实质上模仿了我们在生活中观察到的自然进化过程。 他们的一般原则基于以下概念: 初始人口由几个人组成,每个人代表一个特定的问题解决方案,并使用三个主要运算符将其发展为最大化整体适应性的状态: 选择交叉突变 。 我们将在下面更加详细地研究这些方面。

    Genetic Algorithms are nothing short of fantastic, as they can be applied to many kinds of optimization problems and find solutions to complex functions for which we do not have a mathematical expression. This comes at a cost of computational complexity though, as, for large populations, we’ll have to evaluate the fitness of all individuals at every generation. If the fitness function is expensive, the algorithm run will be slow.

    遗传算法简直就是太神奇了,因为它们可以应用于多种优化问题并找到我们没有数学表达式的复杂函数的解。 但是,这是以计算复杂性为代价的,因为对于大量人口,我们必须评估每一代所有个体的适应性。 如果适应度函数昂贵,则算法运行会很慢。

    GA’s can be divided into Binary and Continuous, depending on the type of problem we’re optimizing for. Potentially all problems could be broken down as having their variables (genes) represented by binary strings, but in general, if the input space is real-valued, it makes more sense to use a continuous GA.

    GA可以分为BinaryContinuous ,具体取决于我们要优化的问题类型。 可能所有问题都可以通过用二进制字符串表示其变量( 基因)来分解,但是总的来说,如果输入空间是实值,则使用连续 GA更有意义。

    As there are fewer examples for continuous GA out there, the examples shown here will be for that version of GA.

    由于那里连续GA的示例较少,因此此处显示的示例适用于该版本的GA。

    Initialization

    初始化

    The search starts with a random population of N individuals. Each of those individuals corresponds to a chromosome, which encodes a sequence of genes representing a particular solution to the problem we’re trying to optimize for. Depending on the problem at hand, the genes representing the solution could be bits (0’s and 1’s) or continuous (real valued). An example of a real-valued chromosome representing a solution to a given problem with 9 variables (genes) is shown below.

    搜索从N个个体的随机种群开始。 这些个体中的每一个都对应一条染色体 ,该染色体编码表示代表我们要优化的问题的特定解决方案的一系列基因。 根据当前的问题,代表解决方案的基因可以是位(0和1)或连续(实值)。 下面显示了一个实值染色体的示例,该染色体代表具有9个变量( 基因 )的给定问题的解决方案。

    Image for post
    Example of an individual’s chromosome
    个人染色体的例子

    Fitness

    适合度

    The fitness of each individual is what defines what we are optimizing for, so that, given a chromosome encoding a specific solution to a problem, its fitness will correspond to how well that particular individual fares as a solution to the problem. Therefore, the higher its fitness value, the more optimal that solution is.

    每个人的健康状况 是什么定义了我们要优化的内容,因此,给定染色体编码的问题的特定解决方案,其适应性将对应于特定个体解决问题的能力。 因此,其适用性值越高,该解决方案越理想。

    After all, individuals have their fitness score calculated, they are sorted, so that the fittest individuals can be selected for crossover.

    毕竟,已经计算了个人的健身得分,并对他们进行了排序,以便可以选择最适合的个人进行交叉。

    Selection

    选拔

    Selection is the process by which a certain proportion of individuals are selected for mating between each other and create new offsprings. Just like in real-life natural selection, individuals that are fitter have higher chances of surviving, and therefore, of passing on their genes to the next generation. Though versions with more individuals exist, usually the selection process matches two individuals, creating pairs of individuals. There are four main strategies:

    选择是选择特定比例的个体以使其彼此交配并产生新后代的过程。 就像现实中的自然选择一样,更健康的个体有更高的生存机会,因此可以将其基因传给下一代。 尽管存在更多个人的版本,但通常选择过程会匹配两个个人,从而创建成对的个人。 有四种主要策略:

    pairing: This is perhaps the most straightforward strategy, as it simply consists of pairing the top fittest chromosomes two-by-two (pairing odd rows with even ones).

    配对 :这可能是最直接的策略,因为它仅包括将最合适的染色体两两配对(将奇数行与偶数行配对)。

    random: This strategy consists of randomly selecting individuals from the mating pool.

    随机 :此策略包括从交配池中随机选择个体。

    roulette wheel: This strategy also follows a random principle, but fitter individuals have higher probabilities of being selected.

    轮盘赌 :这种策略也遵循随机原则,但是更健康的人被选中的可能性更高。

    tournament: With this strategy, the algorithm first selects a few individuals as candidates (usually 3), and then selects the fittest individual. This option has the advantage that it does not require the individuals to be sorted by fitness first.

    比赛 :采用这种策略时,算法首先选择一些个人作为候选者(通常为3个人),然后选择最适合的个人。 该选项的优点是它不需要先按适合度对个人进行分类。

    A python implementation for the roulette wheel strategy is shown on the snippet below.

    下面的代码段显示了轮盘策略的python实现。

    Crossover

    交叉

    This is the step where new offsprings are generated, which will then replace the least fit individuals in the population. The idea behind crossing over individuals is that, by combining different genes, we might produce even fitter individuals, which will be better solutions to our problem. Or not, and in that case, those solutions won’t survive to the next generations.

    这是生成新后代的步骤,然后将替换种群中最不适合的个体。 跨越个体​​背后的想法是,通过组合不同的基因,我们甚至可以生产出更健康的个体,这将是解决我们问题的更好方法。 不管是不是,在那种情况下,这些解决方案都无法延续到下一代。

    In order to perform the actual crossover, each of the pairs coming from the selection step are combined to produce two new individuals each, which will both have genetic material from each of the parents. There are several different strategies for performing the crossover, so for brevity, we’ll only discuss one of them.

    为了进行实际的杂交,将来自选择步骤的每对配对以产生两个新个体,每个个体都具有来自每个亲本的遗传物质。 执行交叉有几种不同的策略,为简便起见,我们仅讨论其中一种。

    Supposing we have a problem defined by 9 variables, if we have 2 parents and we choose randomly the crossover gene as index 3, then each of the offsprings will be a combination of each parent, as shown in the diagram below.

    假设我们有一个由9个变量定义的问题,如果我们有2个父母,并且我们随机选择交叉基因作为索引3,那么每个后代将是每个父母的组合,如下图所示。

    Image for post
    Diagram showing how parents are crossed over to generate new offspring
    该图显示了父母如何过渡以产生新的后代

    The crossover gene of each offspring is calculated according to the rule given by:

    每个后代的交叉基因根据以下规则计算:

    Image for post
    Equation for calculating new crossover genes
    计算新交叉基因的方程式

    Where β will be a random number between 0 and 1. The python code for the crossover is given below.

    其中β是0到1之间的随机数。下面给出了交叉的python代码。

    Mutation

    突变

    Mutation is the process by which we introduce new genetic material in the population, allowing the algorithm to search a larger space. If it were not for mutation, the existing genetic material diversity in a population would not increase, and, due to some individuals “dying” between generations, would actually be reduced, with individuals tending to become very similar quite fast.

    突变是我们在种群中引入新遗传物质的过程,从而使算法可以搜索更大的空间。 如果不是为了突变,则种群中现有的遗传物质多样性将不会增加,而且由于某些个体在世代之间“垂死”,实际上会减少,而个体趋于变得非常相似。

    In terms of the optimization problem, this means that without new genetic material the algorithm can converge to local optima before it explores an enough large size of the input space to make sure that we can reach the global optimum. Therefore, mutation plays a big role in maintaining diversity in the population and allowing it to evolve to fitter solutions to the problem.

    就优化问题而言,这意味着在没有新的遗传材料的情况下,该算法可以先收敛到局部最优,然后再探索足够大的输入空间,以确保我们可以达到全局最优。 因此,突变在维持种群多样性并使其进化以适应问题的解决方案中起着重要作用。

    The most simple way we can do this is, given a certain mutation rate, to randomly choose some individuals and some genes and assign a new random number to those positions. This is exemplified in the diagram and code snippet below.

    我们可以执行此操作的最简单方法是,在确定突变率的情况下 ,随机选择一些个体和某些基因,并为这些位置分配一个新的随机数。 下面的图和代码段中对此进行了举例说明。

    Image for post
    Mutation of two genes in an individual
    个体中两个基因的突变

    Solver

    解算器

    Now it’s time to tie it all together. Using the operators that we defined above, the algorithm can now solve the problem, with the actual main cycle of the algorithm being implemented in just a few lines of code. The flowchart of the algorithm, as well as an example implementation in python are shown below.

    现在是时候将它们捆绑在一起了。 使用上面定义的运算符,该算法现在可以解决问题,该算法的实际主循环仅用几行代码即可实现。 该算法的流程图以及python中的示例实现如下所示。

    Image for post
    Flowchart of the Genetic Algorithm
    遗传算法流程图

    介绍GeneAl (Introducing GeneAl)

    GeneAl is a python library implementing Genetic Algorithms, which can be used and adapted to solve many optimization problems. One can use the provided out-of-the-box solver classes — BinaryGenAlgSolver and ContinuousGenAlgSolver — , or create a custom class which inherits from one of these, and implements methods that override the built-in ones. It also has support for solving the (in)famous Travelling Salesman Problem.

    GeneAl是实现遗传算法的python库,可用于解决许多优化问题。 可以使用提供的现成的求解器类BinaryGenAlgSolverContinuousGenAlgSolver ,或者创建一个自定义类继承自其中的类,并实现覆盖内置方法的方法。 它还支持解决著名的旅行推销员问题

    For brevity, we’ll only see how to use the continuous version — keeping in line with this post — , but for more details, check out the README of this project.

    为简便起见,我们只会看到如何使用连续版本-与本文保持一致-,但是要了解更多详细信息,请查看该项目的自述文件。

    The first thing would be to install the package, which can be made through pip, as such:

    首先是要安装软件包,可以通过pip进行安装,如下所示:

    pip install geneal 

    After the installation completes, one is ready to use it. So let’s see how we can use the ContinuousGenAlgSolver class.

    安装完成后,就可以使用了。 因此,让我们看看如何使用ContinuousGenAlgSolver类。

    As a bare minimum, the class requires the user to provide the number of genes present in the problem, as well as to provide the custom defined fitness function. For convenience, the library provides some default fitness functions that can be used for testing.

    至少,该类别要求用户提供问题中存在的基因数量,并提供自定义的适应度函数。 为了方便起见,该库提供了一些可用于测试的默认适应性函数。

    With the initialization done above, the class will solve the problem using default values for all the parameters. If we wish to have more control over the algorithm run, we will want to adjust these, and that can be done as shown below:

    通过上面的初始化,该类将使用所有参数的默认值解决问题。 如果我们希望对算法的运行有更多的控制,我们将希望对其进行调整,如下所示:

    Finally, this class allows the user to specify the type of problem — if the possible values are integers or floats — , as well as the variables’ limits, in order to limit the search space.

    最后,该类允许用户指定问题的类型(如果可能的值是整数或浮点数)以及变量的限制,以限制搜索空间。

    This completes this short introduction to the library. If you want to know more, check out the GitHub repository, which has more information :)

    这样就完成了对库的简短介绍。 如果您想了解更多信息,请查看GitHub存储库 ,其中包含更多信息:)

    Thanks for reading!

    谢谢阅读!

    翻译自: https://towardsdatascience.com/introducing-geneal-a-genetic-algorithm-python-library-db69abfc212c

    遗传算法python库

    展开全文
  • 遗传算法Python实现

    千次阅读 2019-05-25 17:23:13
    遗传算法Python实现遗传算法Python实现导入库以及参数设置目标函数生成C行R列的值在0-1的数组混沌函数二进制转十进制个体按值从大到小排序交叉变异适应度函数主函数 遗传算法Python实现 导入库以及参数设置 import ...

    瞎BB

    代码

    导入库以及参数设置

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    import math
    import random
    
    #range of variable
    bounds = np.array([-2,2])
    #begin of variable
    boundsbegin = bounds[0]
    #end of variable
    boundsend = bounds[1]
    precision = 0.0001
    #calc the BitLength
    BitLength = math.ceil(np.log2((boundsend - boundsbegin) / precision))
    #init
    popsize = 100
    Generationmax = 100
    pmut = 0.09
    

    目标函数

    def targetfun(x):
        value = 200 * math.exp(-0.05 * x) * math.sin(x)
        return value
    

    生成C行R列的值在0-1的数组

    def random_random(C,R):
        rand=[]
        for i in range(C*R):
            rand.append(random.random())
        rand=np.array(rand)
        return rand.reshape(C,R)
    

    混沌函数

    def chaos(size):
        chaos_cro = np.zeros(size)
        chaos_cro[0] = random.random()
        for j in range(1,size):
                chaos_cro[j] = 4 * chaos_cro[j - 1] * (1 - chaos_cro[j - 1])
        return chaos_cro[-1]
    

    二进制转十进制

    def transform2to10(sample):
        BitLength = len(sample)
        x=sample[-1]
        for i in range(1,BitLength):
            x=x+sample[-i-1]*np.power(2,i)
        return x
    

    个体按值从大到小排序

    def rank(population):
        popsize = population.shape[0]
        BitLength = population.shape[1]
        fitvalue = np.zeros(popsize).reshape(popsize,1)
        for i in range(popsize):
            x = transform2to10(population[i])
            #tansform to range of variable
            xx=boundsbegin + x * (boundsend - boundsbegin) / (np.power(boundsend,BitLength)-1)
            fitvalue[i,0]=targetfun(xx)
        #make fitvalue(j)<fitvalue(j+1)
        res = np.concatenate((population,fitvalue),axis = 1)
        res=pd.DataFrame(res)
        population = res.sort_values(by=BitLength)
        population = np.array(population)
        population = population[:,0:BitLength]
        return population
    

    交叉变异

    def cro_mut_improve(population,rate_mut):
        #seln:two individuals
        popsize = population.shape[0]
        BitLength = population.shape[1]
        population = rank(population)
        #crossover
        pop=popsize
        chaos_cro = np.zeros(BitLength)
        
        if popsize % 2 == 1:
            pop = popsize - 1
            
        for i in range(0,pop,2):
            chaos_cro = chaos(BitLength)
            chao = math.floor(chaos_cro * BitLength)
            temp = population[i,chao]
            population[i,chao] = population[i+1,chao]
            population[i + 1,chao] = temp
        
        #mutation
        by = np.array([])
        n = len(by)
        #generate random individuals to mutate
        while n == 0:
            by = random_random(1,popsize)<rate_mut
            for i in by[0]:
                if i:
                    n+=1
        num_mut = n
        for k in range(popsize):
            if by[0,k] == True:
                chaos_mut = np.zeros(BitLength)
                chaos_mut[0] = random.random()
                for t in range(1,BitLength):
                    chaos_mut[t] = 4 * chaos_mut[t - 1] * (1 - chaos_mut[t - 1])
                position = np.floor(BitLength * random_random(1,2))
                position.astype(np.int16)
                population[k,int(position[0,0])] = np.round(chaos(BitLength))
                population[k,int(position[0,1])] = np.round(chaos(BitLength))
        return population
    

    适应度函数

    def fitness(population):
        #population=pd.DataFrame(population)
        popsize = population.shape[0]
        BitLength = population.shape[1]
        cumsump = np.zeros(popsize).reshape(1,popsize)
        fitvalue = np.zeros(popsize).reshape(1,popsize)
        for i in range(popsize):
            x = transform2to10(population[i])
            #tansform to range of variable
            xx = boundsbegin + x * (boundsend - boundsbegin) / (np.power(boundsend,BitLength) - 1)
            fitvalue[0,i] = targetfun(xx)
        #ensure fitvalue>0
        fitvalue = fitvalue+230
        fsum = fitvalue.sum(1)[0]
        Pperpopulation = fitvalue / fsum
        cumsump[0] = Pperpopulation[0]
        for i in range(1,popsize):
            cumsump[0,i] = cumsump[0,i-1] + Pperpopulation[0,i]
        res = np.concatenate((fitvalue,cumsump),axis = 0)
        return res
    

    主函数

    ymax=np.zeros(Generationmax+1)
    ymean=np.zeros(Generationmax+1)
    xmax=np.zeros(Generationmax+1)
    #generate random population
    population = np.round(random_random(popsize,BitLength))
    #calc fitness return fitvalue and sum of probability
    res=fitness(population)
    fitvalue = res[0]
    cumsump = res[1]
    #main code
    Generation=1
    while Generation<Generationmax+1:
        population=cro_mut_improve(population,pmut)
        res=fitness(population)
        fitvalue = res[0]
        cumsump = res[1]
        fmax = np.max(fitvalue)
        for i in range(popsize):
            if fitvalue[i]==fmax:
                nmax = i
                break
        fmean = np.mean(fitvalue,axis = 0)
        ymax[Generation] = fmax
        ymean[Generation] = fmean
        x = transform2to10(population[nmax])
        xx = boundsbegin + x * (boundsend-boundsbegin) / (pow(boundsend,BitLength)-1)
        xmax[Generation] = xx
        Generation += 1
    #Generation=Generation-1;
    Bestpopulation = np.max(xmax)
    BestValue = targetfun(Bestpopulation)
    print(Bestpopulation)
    print(BestValue)
    
    x=[]
    y=[]
    for i in range(400):
        t=-2+0.01*i
        x.append(t)
        y.append(targetfun(t))
    plt.scatter(x, y)
    
    展开全文
  • 遗传算法python

    2019-01-05 16:15:42
    最基础的遗传算法,使用python实现。
  • 遗传算法python

    2020-12-24 13:19:36
    本文实例为大家分享了python遗传算法的具体代码,供大家参考,具体内容如下 1、基本概念 遗传算法(GA)是最早由美国Holland教授提出的一种基于自然界的“适者生存,优胜劣汰”基本法则的智能搜索算法。该法则很好...
  • 遗传算法python(含例程代码与详解)

    千次阅读 多人点赞 2020-10-24 11:00:57
    遗传算法1.算法简介2.算法流程3.算法示例4.算法实现5.算法应用
  • 遗传算法python实现

    2021-01-14 17:56:54
    遗传算法python实现一、问题引入二、遗传算法的步骤1.初始化2.个体评价3.选择运算4.交叉运算5.变异运算6.终止条件判断三、实现思路1.编码的设计2.适应度函数3.选择函数4.交叉函数5.变异函数6.迭代四、具体实现1.编码...
  • Python遗传算法主函数 我的思想是,创建一个染色体的类,其中包括了两个变量:染色体chrom与适应度fitness。因此我们就可以通过直接建立对象来作为种群中的个体。 #染色体的类 class Chrom: chrom = [] fitness...
  • 遗传算法python代码

    2020-04-16 15:45:16
      遗传算法 GA—模拟自然界遗传机制和生物进化论而成的一种并行随机搜索最优化方法。它的过程分为种群初始化、计算适应度、交叉、变异,然后进行多代的迭代后得到比较好的个体。   下面是我的参考代码。 首先...
  • 遗遗传传算算法法python版版 这篇文章主要为大家详细介绍了python实现遗传算法具有一定的参考价值感兴趣的小伙伴们可以参考一下 本文实例为大家分 了python遗传算法的具体代码供大家参考具体内容如下 1基基本本概...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,197
精华内容 2,478
关键字:

遗传算法python代码

python 订阅