遗传算法(求极值问题_Python实现)

 纯个人学习记录,如有问题,请大佬指出。
 


本例用遗传算法求解函数最优解问题 

 f(x)=x*sin(arctan(1)*4*x)+2.0   (-1.0<x<2.0)

第一步:初始化种群-----定义一个函数initgeneration 生成第一代种群群体 population[]

def initgeneration(popsize, lchrom):
    population = []  # 用来存放第一代初始化的种群
    for i in range(popsize):
        temporyary = []  # 染色体暂存器,用来储存新生成的染色体
        for j in range(lchrom):
            total = random.randint(0, 1)
            temporyary.append(total)
        population.append(temporyary)
    return population
第二步:编码----catulatefitness()---把生成的二进制转换成十进制数,求出初始种群每个个体的适应度值fitness_values[]

def caculatefitness(population, lchrom):
    decimal = []  # 存放初始种群每个个体的十进制数
    for i in range(len(population)):
        temporary = 0
        fitness_value = []
        population[i].reverse()  # 反转列表,为下面计算十进制做准备
        for j in range(lchrom):  # 二进制转换成十进制
            temporary = temporary + population[i][j] * (math.pow(2, j))
        decimal.append(temporary)
    for i in range(len(population)):
        x = -1.0 + decimal[i] * 3 / (math.pow(2, lchrom) - 1)
        fitness_value.append(x * math.atan(1) * 4 * x + 2.0)
# 判断每个个体的适应度是否存在负数,如果有则重置为0
    fitness_values = []
    for i in range(len(fitness_value)):
        if fitness_value[i] > 0:
            fitness_values.append(fitness_value[i])
        else:
            fitness_values.append(0)
    # print("适应度值为fitnesas_values为:", fitness_values)
    # print(population)
    return fitness_values
第三步:选择操作-----selectopration()---进行适应度的求和sum,然后计算每个个体的选择概率 = fitness_values[i]/sum(fitness_values),然后计算累积概率,接着产生随机数,如果小于某个累积概率,则进行选择

# 选择操作
def selectopration(population, fitness_values):
    q = []
    # 进行适应值的求和
    sum = 0
    for i in range(len(fitness_values)):
        sum += fitness_values[i]
    # print("适应值求和sum为:", sum)
    # 计算每个个体的选择概率
    for i in range(len(fitness_values)):
        q.append(fitness_values[i] / sum)
    # print("个体选择概率q为:", q)
    # 计算累计概率
    p = []
    total = 0
    for i in range(len(q)):
        total += q[i]
        p.append(total)
    # 随机选取
    new_population = []
    ms = []  # 用来存放判断存活的种群的随机数
    for i in range(len(population)):
        ms.append(random.random())
    ms.sort()
    # print("个体累计概率p为:", p)
    # print("选择操作随机生成数ms为:", ms)
    new_population = []
    i = 0
    j = 0
    while i < len(population):
        if ms[i] < p[j]:
            new_population.append(population[i])
            i += 1
        else:
            j += 1
    # print(new_population)
    population = new_population  # 存放的是选择的个体的累积概率
    # print(len(population))
    return population
第四步:杂交操作----crossoveropration()---对选择操作选下来的种群进行交叉----随机生成[0,1]之间的数与杂交概率进行比较,如果小于杂交概率,则进行杂交---单点杂交:随机相邻的两个个体,通过随机生成杂交点,进行杂交。

# 杂交操作---对选择操作选下来的种群进行交叉----随机生成[0,1]之间的数与杂交概率进行比较
# 如果小于杂交概率,则进行杂交---单点杂交
def crossoveropration(population, pc):
    for i in range(len(population) - 1):
        temporary1 = []
        temporary2 = []
        total = random.random()

        if (total <= pc):
            crosspoint = random.randint(0, len(population[i]) - 1)  # 杂交点
            temporary1.extend(population[i][0: crosspoint])
            temporary1.extend(population[i + 1][crosspoint:len(population[i])])
            temporary2.extend(population[i + 1][0:crosspoint])
            temporary2.extend(population[i][crosspoint:len(population[i])])
        else:
            temporary1 = population[i]
            temporary2 = population[i + 1]

        population[i] = temporary1
        population[i + 1] = temporary2
    # print(len(population))
    # print("交叉后种群为:", population)
    return population
第五步:变异操作----mutationopration()---随机生成一个变异点,然后根据随机生成数若小于变异概率----若基因位为0,则基因位变为1,否则为0

# 变异操作----随机生成一个变异点,然后根据随机生成数小于变异概率----若基因位为0,则基因位变为1,否则为1
def mutationopration(population, pm):
    for i in range(len(population)):
        j = 0
        while (j < 2):
            mutationpoint = random.randint(0, len(population[i]) - 1)
            if (random.random() < pm):
                if (population[i][mutationpoint] == 0):
                    population[i][mutationpoint] = 1
                else:
                    population[i][mutationpoint] = 0
                j += 1
    # print("变异后种群为:", population)
    return population
第六步:寻找最好的适应度个体---FindBestAndCurrent()---根据当前一代种群每个个体的适应度值进行比较,找出当前种群最好的适应值,和当前最佳个体,然后与全局最佳个体的适应值进行比较,判断谁是最优值,保证最优解的更新。
        ----最后输出当前个体,当前最佳个体,当前最佳个体染色体,当前最佳适应度值
        ----输出全局最佳个体,全局最佳个体染色体,全局最佳适应度值
# 寻找最好的个体
def FindBestAndCurrent(population, lchrom):
    k = gen
    m = 0  # 用来标记当代中最好适应度个体的位置
    # 先选出当代适应度最好的为
    current_best = []  # 当代最好个体
    fitness_values = caculatefitness(population, lchrom)
    fitness_values.sort()
    maxfitness = fitness_values[0]
    for i in range(len(population)):
        if (maxfitness < fitness_values[i]):
            maxfitness = fitness_values[i]
            m = i
        current_best = population[m]  # 当代最好个体
        current_best_fitness = maxfitness  # 当代最好个体适应值
    current_generation = k + 1
    print("第几代:", current_generation)

    # 进行当代与全局最好适应度个体进行比较
    global global_best_fitness
    global global_best
    # global_best = []  # 全局最好个体
    if (global_best_fitness < current_best_fitness):
        global_best_fitness = current_best_fitness
        global_best = current_best
    # 输出当前个体,当前最佳个体,当前最佳个体染色体,当前最佳适应度值
    # 输出全局最佳个体,全局最佳个体染色体,全局最佳适应度值
    print("当前种群个体:", population)
    print("当前种群最佳个体:", current_best)
    print("当前种群每个个体适应度值:", fitness_values)
    print("当前种群最佳适应度值:", current_best_fitness)
    print("-------------")
    print("全局最佳个体:", global_best)
    print("全局最佳适应度值", global_best_fitness)

    return (current_best, current_best_fitness, global_best, global_best_fitness)

第七步:利用main()函数进行迭代250次
# 总共迭代次数250
def main():
    N = 250
    global gen
    popsize = 30
    lchrom = 20
    pm = 0.01
    pc = 0.60
    population = initgeneration(popsize, lchrom)
    while (gen < N):
        print("#######################################################################################################")
        fitness_values = caculatefitness(population, lchrom)  # 求每个个体的适应值
        A = selectopration(population, fitness_values)  # 选择操作
        B = crossoveropration(A, pc)  # 交叉操作
        C = mutationopration(B, pm)  # 变异操作
        FindBestAndCurrent(C, lchrom)  # 求当前个体,当前最佳个体,当前最佳个体适应度,全局最佳个体,全局最佳个体适应值
        gen += 1

 全部代码如下:

全部代码如下:
import random
import math

global global_best_fitness  # 使用 global 声明为全局变量
global global_best  # 使用 global 声明为全局变量
global gen
global_best_fitness = 0
global_best = []
gen = 0


# 初始化种群 poplation_size = popsize = 种群大小,,chromosome_length = lchrom = 染色体长度
def initgeneration(popsize, lchrom):
    population = []  # 用来存放第一代初始化的种群
    for i in range(popsize):
        temporyary = []  # 染色体暂存器,用来储存新生成的染色体
        for j in range(lchrom):
            total = random.randint(0, 1)
            temporyary.append(total)
        population.append(temporyary)
    return population


# 编码--把二进制数转化成十进制数    计算适应度函数
def caculatefitness(population, lchrom):
    decimal = []  # 存放初始种群每个个体的十进制数
    for i in range(len(population)):
        temporary = 0
        fitness_value = []
        population[i].reverse()  # 反转列表,为下面计算十进制做准备
        for j in range(lchrom):  # 二进制转换成十进制
            temporary = temporary + population[i][j] * (math.pow(2, j))
        decimal.append(temporary)
    for i in range(len(population)):
        x = -1.0 + decimal[i] * 3 / (math.pow(2, lchrom) - 1)
        fitness_value.append(x * math.atan(1) * 4 * x + 2.0)

    # print(len(decimal))
    # 判断每个个体的适应度是否存在负数,如果有则重置为0
    fitness_values = []
    for i in range(len(fitness_value)):
        if fitness_value[i] > 0:
            fitness_values.append(fitness_value[i])
        else:
            fitness_values.append(0)
    # print("适应度值为fitnesas_values为:", fitness_values)
    # print(population)
    return fitness_values


# 选择操作
def selectopration(population, fitness_values):
    q = []
    # 进行适应值的求和
    sum = 0
    for i in range(len(fitness_values)):
        sum += fitness_values[i]
    # print("适应值求和sum为:", sum)
    # 计算每个个体的选择概率
    for i in range(len(fitness_values)):
        q.append(fitness_values[i] / sum)
    # print("个体选择概率q为:", q)
    # 计算累计概率
    p = []
    total = 0
    for i in range(len(q)):
        total += q[i]
        p.append(total)
    # 随机选取
    new_population = []
    ms = []  # 用来存放判断存活的种群的随机数
    for i in range(len(population)):
        ms.append(random.random())
    ms.sort()
    # print("个体累计概率p为:", p)
    # print("选择操作随机生成数ms为:", ms)
    new_population = []
    i = 0
    j = 0
    while i < len(population):
        if ms[i] < p[j]:
            new_population.append(population[i])
            i += 1
        else:
            j += 1
    # print(new_population)
    population = new_population  # 存放的是选择的个体的累积概率
    # print(len(population))
    return population


# 杂交操作---对选择操作选下来的种群进行交叉----随机生成[0,1]之间的数与杂交概率进行比较
# 如果小于杂交概率,则进行杂交---单点杂交
def crossoveropration(population, pc):
    for i in range(len(population) - 1):
        temporary1 = []
        temporary2 = []
        total = random.random()

        if (total <= pc):
            crosspoint = random.randint(0, len(population[i]) - 1)  # 杂交点
            temporary1.extend(population[i][0: crosspoint])
            temporary1.extend(population[i + 1][crosspoint:len(population[i])])
            temporary2.extend(population[i + 1][0:crosspoint])
            temporary2.extend(population[i][crosspoint:len(population[i])])
        else:
            temporary1 = population[i]
            temporary2 = population[i + 1]

        population[i] = temporary1
        population[i + 1] = temporary2
    # print(len(population))
    # print("交叉后种群为:", population)
    return population


# 变异操作----随机生成一个变异点,然后根据随机生成数小于变异概率----若基因位为0,则基因位变为1,否则为1
def mutationopration(population, pm):
    for i in range(len(population)):
        j = 0
        while (j < 2):
            mutationpoint = random.randint(0, len(population[i]) - 1)
            if (random.random() < pm):
                if (population[i][mutationpoint] == 0):
                    population[i][mutationpoint] = 1
                else:
                    population[i][mutationpoint] = 0
                j += 1
    # print("变异后种群为:", population)
    return population


# 寻找最好的个体
def FindBestAndCurrent(population, lchrom):
    k = gen
    m = 0  # 用来标记当代中最好适应度个体的位置
    # 先选出当代适应度最好的为
    current_best = []  # 当代最好个体
    fitness_values = caculatefitness(population, lchrom)
    fitness_values.sort()
    maxfitness = fitness_values[0]
    for i in range(len(population)):
        if (maxfitness < fitness_values[i]):
            maxfitness = fitness_values[i]
            m = i
        current_best = population[m]  # 当代最好个体
        current_best_fitness = maxfitness  # 当代最好个体适应值
    current_generation = k + 1
    print("第几代:", current_generation)

    # 进行当代与全局最好适应度个体进行比较
    global global_best_fitness
    global global_best
    # global_best = []  # 全局最好个体
    if (global_best_fitness < current_best_fitness):
        global_best_fitness = current_best_fitness
        global_best = current_best
    # 输出当前个体,当前最佳个体,当前最佳个体染色体,当前最佳适应度值
    # 输出全局最佳个体,全局最佳个体染色体,全局最佳适应度值
    print("当前种群个体:", population)
    print("当前种群最佳个体:", current_best)
    print("当前种群每个个体适应度值:", fitness_values)
    print("当前种群最佳适应度值:", current_best_fitness)
    print("-------------")
    print("全局最佳个体:", global_best)
    print("全局最佳适应度值", global_best_fitness)

    return (current_best, current_best_fitness, global_best, global_best_fitness)


# 总共迭代次数250
def main():
    N = 250
    global gen
    popsize = 30
    lchrom = 22
    pm = 0.05
    pc = 0.80
    population = initgeneration(popsize, lchrom)
    while (gen < N):
        print("##############################################################################")
        fitness_values = caculatefitness(population, lchrom)  # 求每个个体的适应值
        A = selectopration(population, fitness_values)  # 选择操作
        B = crossoveropration(A, pc)  # 交叉操作
        C = mutationopration(B, pm)  # 变异操作
        FindBestAndCurrent(C, lchrom)  # 求当前个体,当前最佳个体,当前最佳个体适应度,全局最佳个体,全局最佳个体适应值
        gen += 1


if __name__ == "__main__":
    main()

代码运行结果如下:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值