python实现遗传算法求解函数极值问题

python实现遗传算法求解函数极值问题

import random
import numpy as np
#定义染色体类
class chromosome:
    def __init__(self,chrom,decode,fitness):
        self.chrom = chrom
        self.decode = decode
        self.fitness = fitness
#解码函数
def decode(chom):
    chom.reverse()
    x = 0
    for i in range(len(chom)):
        x = x + chom[i]*(pow(2,i))
        x1 = x * (10/pow(2,10)-1)
    return x1
#适应度值(就是函数的y)
def fitness(x):
    return x + 10 * np.sin(5 * x) + 7 * np.cos(4 * x)
#初始化种群
import random
def initPopulation(N):
    pop = []
    for i in range(N):
        L=[random.randint(0,1) for i in range(10)]
        this_decode = decode(L)
#         print(this_decode)
        this_fitness = fitness(this_decode)
        pop.append(chromosome(L,this_decode,this_fitness))
#         print(this_decode)
#         print(this_fitness)
    return pop
#交叉(两点交叉,执行基于概率Pc的两点交叉操作,采用奇偶交叉,即第1个和第2个交叉,第3个和第4个交叉,依次进行)
def crossover(pop):
    odd = pop[0::2]
    even = pop[1::2]
    new_pop = []
    a, b = np.random.choice(len(pop[0].chrom), 2)
#     print(a,b)
    for i in range(len(odd)):
        a1 = odd[i].chrom
        a2 = even[i].chrom
#         print(a1,a2,"_________")
        if a<b:
            a1_1 = a1[0:a] + a2[a:b-1] + a1[b-1:]
            a2_1 = a2[0:a] + a1[a:b-1] + a2[b-1:]
        elif a>b:
            a1_1 = a1[0:b] + a2[b:a-1] + a1[a-1:]
            a2_1 = a2[0:b] + a1[b:a-1] + a2[a-1:]
        elif a == b:
            a1_1 = a1
            a2_1 = a2
        this_decode1 = decode(a1_1)
        this_fitness1 = fitness(this_decode1)
        new_pop.append(chromosome(a1_1,this_decode1,this_fitness1))
        this_decode2 = decode(a2_1)
        this_fitness2 = fitness(this_decode2)
        new_pop.append(chromosome(a2_1,this_decode2,this_fitness2))
#         print(a1_1,a2_1)
#     print(len(new_pop))
    return new_pop
#变异操作(执行基于概率Pm的变异操作,即随机选择一个基因位置取反,若是0则变为1,若是1则变为0)
def mutation(pop):
    new_pop = []
    a = np.random.choice(len(pop[0].chrom), 1)
#     print(a[0])
    for i in range(len(pop)):
        a1 = pop[i].chrom
        if a1[a[0]] == 1:
            a1[a[0]] = a1[a[0]]-1
        else:
            a1[a[0]] = a1[a[0]]+1
        this_decode = decode(a1)
        this_fitness = fitness(this_decode)
        new_pop.append(chromosome(a1,this_decode,this_fitness))
    return new_pop
#对进化后的混合种群按适应度值排序,留下其中的适应度值高的N(此处定义的是20)个
'''

def Asort(POP):
    for i in range(len(POP)):
        for j in range(len(POP)-1):
            if POP[i].fitness>POP[j].fitness:
                POP[i],POP[j] = POP[j],POP[i]
    return POP
'''
#冒泡排序
def Asort(POP):
    for i in range(len(POP)):
        for j in range(len(POP)-1):
#             print(open_[i])
            if POP[i].fitness<POP[j].fitness:
                POP[i],POP[j] = POP[j],POP[i]
    return POP
#进行进化选择操作,以此迭代。
def implement():
    # 种群中个体数量
    N = 20
    # 种群
#     POP = []
    # 迭代次数
    iter_N = 100
    # 初始化种群
    POP = initPopulation(N)
    POP_all = []
    
#     print(POP_all)
#     print(Asort(POP_all))
    
    # 交叉概率
    Pc = 0.8
    # 变异概率
    Pm = 0.1
# 进化过程
    for i in range(iter_N):
        POP_all = POP_all+POP
        if np.random.random() < Pc:  # 以Pc的概率进行交叉结合
            POP = crossover(POP)
        if np.random.random() < Pm:  # 以Pm的概率进行变异
            POP = mutation(POP)
        POP_all = POP_all + POP
        POP_end = Asort(POP_all)
        POP = POP_end[0:N]
        POP_all = []
#         print(POP_all)
    return POP
#调用进化函数,最后结果保存在result中。
result = implement()
result
#依次输出一下,查看结果如何。
for i in range(len(result)):
    print(result[i].decode)
    print(result[i].fitness)
#最后再绘制的函数曲线看一看。
import matplotlib.pyplot as plt
def func(x):
    return x + 10 * np.sin(5 * x) + 7 * np.cos(4 * x)
x = np.linspace(-10, 10, 10000)
y = func(x)
scatter_x = np.array([ind.decode for ind in result])
scatter_y = np.array([ind.fitness for ind in result])
plt.plot(x, y)
plt.scatter(scatter_x, scatter_y, c='r')
plt.show()

最后结果:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值