Python实现遗传算法

python实现遗传算法

原文链接

最优化问题描述

min ⁡ [ 3 − sin ⁡ 2 ( 2 x ) − sin ⁡ 2 ( 2 y ) ] \min [3 - {\sin ^2}(2x) - {\sin ^2}(2y)] min[3sin2(2x)sin2(2y)]
所对应的点(x,y)
已知最小值:1.000

代码

import matplotlib.pyplot as plt
import random
import math

class GA(object):
    def __init__(self,paras):
        self.generation = paras[0]
        self.group_size = paras[1]
        self.chrom_length = paras[2]
        self.min_value = paras[3]
        self.max_value = paras[4]
        self.pc = paras[5] # 交叉概率
        self.pm = paras[6] # 变异概率
        self.divid = [399,self.chrom_length -1]

    # 计算函数
    def f(self,args):
        return self.f1(args)

    def f1(self,args):
        return (3 - (math.sin(2 * args[0])) ** 2 - (math.sin(2 * args[1])) ** 2)

    # 适应函数
    def s(self,x):
        return self.s1(x)

    def s1(self,x):
        return math.exp(-abs(x - 1))

    # 计算二进制序列代表的数值
    def b2d(self,b):
        self.rwno = []
        for i in range(len(self.divid)):
            if i == 0:
                star = 0
                end = self.divid[i]
            else:
                star = self.divid[i - 1] + 1
                end = self.divid[i]
            t = 0
            for j in range(star, end):  # 分隔参数[1,2,3||4,5,6]
                t += b[j] * (math.pow(2, j - star))
            t = t * self.max_value / (math.pow(2, end - star + 1) - 1) - self.min_value
            self.rwno.append(t)

        return self.rwno # 这是一个list

    '''
    计算当前函数值
    group 染色体
    chrom_length 染色体长度
    max_value,min_value 最大最小值
    divid 分割
    '''
    def calobjValue(self,group):
        self.obj_value = []
        for i in range(len(group)):
            x = self.b2d(group[i])  # 这里面可能是多个变量

            self.obj_value.append(self.f(x))
        return self.obj_value

    # 获取适应值
    def calfitValue(self,obj_value):
        self.fit_value = []
        for i in range(len(obj_value)):
            temp = self.s(obj_value[i])  # 调用适应函数计算
            self.fit_value.append(temp)
        return self.fit_value

    # 累计适应值方便计算平均
    def sum_fit(self,fit_value):
        self.total = 0
        for i in range(len(fit_value)):
            self.total += fit_value[i]
        return self.total

    # 转轮盘选择法
    def selection(self,group, fit_value):
        newfit_value = []  # [ [[染色体], [锚点]],... ]
        self.newgroup = []  # [ [父], [母], [父], [母],....]

        # 适应度总和
        total_fit = self.sum_fit(fit_value)

        # 设置各个的锚点
        t = 0
        for i in range(len(group)):
            t += fit_value[i] / total_fit
            newfit_value.append([group[i], t])

        # 转轮盘选择法
        for i in range(len(newfit_value)):
            parents = len(newfit_value)  # 初始化指针
            r = random.random()  # 指针
            for j in range(len(newfit_value)):  # 看看指针指到谁了
                if newfit_value[j][1] > r:
                    parents = j
                    break
            self.newgroup.append(newfit_value[parents][0])

        return self.newgroup

    # 交叉
    def crossover(self,group, fit_value):
        parents_group = self.selection(group, fit_value)  # [ [[父], [母]],....]
        group_len = len(parents_group)
        for i in range(0, group_len, 2):
            if (random.random() < self.pc):  # 看看是否要交配
                cpoint = random.randint(0, len(parents_group[0]))  # 随机交叉点
                temp1 = []
                temp2 = []
                temp1.extend(parents_group[i][0:cpoint])
                temp1.extend(parents_group[i + 1][cpoint:len(parents_group[i])])
                temp2.extend(parents_group[i + 1][0:cpoint])
                temp2.extend(parents_group[i][cpoint:len(parents_group[i])])
                group[i] = temp1
                group[i + 1] = temp2

        return group

    # 基因突变
    def mutation(self,group):
        px = len(group)
        py = len(group[0])

        for i in range(px):  # 遍历
            if (random.random() < self.pm):
                mpoint = random.randint(0, py - 1)  # 取要变异哪个
                if (group[i][mpoint] == 1):
                    group[i][mpoint] = 0
                else:
                    group[i][mpoint] = 1

        return group

    '''
    找出最优解和最优解的基因编码
    group 种群染色去
    fit_value 种群适应
    '''

    def best(self,group, fit_value):
        px = len(group)
        best_in = group[0]
        best_fit = fit_value[0]
        for i in range(1, px):
            if (fit_value[i] > best_fit):
                best_fit = fit_value[i]
                best_in = group[i]
        # print(best_in)
        return [best_in, best_fit]

    '''
    创建初代种群
    group_size 种群大小
    chrom_length 染色体长度
    '''

    def getFisrtGroup(self):
        # print('初代种群:')
        self.group = []
        for i in range(self.group_size):
            temp = []
            for j in range(self.chrom_length):
                temp.append(random.randint(0, 1))
            self.group.append(temp)
        # print(group)

        return self.group

    def run(self):
        points = []
        results = []  # 存储每一代的最优解
        fit_value = []  # 个体适应度
        group = self.getFisrtGroup()
        for i in range(self.generation):
            print("generation{}".format(i))
            if i > 200:
                pm = 0.01
            if i > 1000:
                pm = 0.001
            obj_value = self.calobjValue(group)  # 个体评价
            fit_value = self.calfitValue(obj_value)  # 获取群体适应值
            best_individual, best_fit = self.best(group, fit_value)  # 返回最优基因, 最优适应值

            xx = self.b2d(best_individual)
            if (abs(self.f(xx) - 1) < 0.000001):  # 找到最优解
                flag = False
                for p in points:
                    if ((abs(xx[0] - p[0]) < 0.01) and (abs(xx[1] - p[1]) < 0.01)):  # 剔除重复解
                        flag = True
                        break
                if flag == False:
                    print(xx)
                    points.append(xx)

            results.append(
                [i, best_fit, self.b2d(best_individual),
                 best_individual])  # 加进坐标里
            self.crossover(group, fit_value)  # 交叉
            self.mutation(group)  # 变异

        # results.sort(key=lambda x:x[1])

        rank = sorted(results, key=lambda x: x[1])
        # print('\n', rank[-1])

        # print(results)
        x = self.b2d(rank[-1][3])
        # 最终结果
        print("f(x) = ", self.f(x), "x = ", x, " 染色体 = ", rank[-1][3], "  适应值 = ", rank[-1][1], "代数:", rank[-1][0])

        # 输出适应图
        X = []
        Y = []
        for i in range(generation):
            X.append(i)
            Y.append(results[i][1])

        plt.plot(X, Y)
        plt.show()

if __name__ == '__main__':
    generation = 500  # 繁衍代数
    group_size = 400  # 染色体数量,偶数
    max_value = 6  # 最大范围
    min_value = 0  # 最小范围
    chrom_length = 800  # 染色体长度
    pc = 0.7  # 交配概率
    pm = 0.1  # 变异概率
    paras = [generation, group_size, chrom_length, min_value, max_value, pc, pm]
    Gene = GA(paras)
    Gene.run()

结果

f(x) =  1.0000201347927486 
x =  [2.3560175849594, 2.358431102830412]

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值