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

智能优化课,老师让实现遗传算法,每行加注释,略感无语。。。我发现我正好有现成的,加了下注释。

import numpy as np
import random
from matplotlib import pyplot as plt

mutation_rate = 0.001           # 变异率
max_iter = 500                  # 最大迭代次数
m = 20                          # 总基因个数
n = 4                           # 单个基因长度

def func(x):                    # 目标函数
    return 15 * x - x ** 2

class Gene():
    def __init__(self, n, func: 'function'):
        '''
        ## 基因类
        ---
        n: 基因长度
        func: 用于计算适应度的函数
        '''
        self.n = n                              # 基因长度
        self.func = func                        # 适应度计算函数
        self.gene = [0 for i in range(self.n)]  # 用一个数组表示基因

    def mutation(self):                         # 变异
        for i in range(self.n):                 # 对每一位基因进行变异判断
            if random.uniform(0, 1) <= mutation_rate:   # 如果随机数小于变异概率
                self.gene[i] ^= 1               # 和1异或变成想法值

    def cal_fitness(self):                      # 计算适应度
        num = 0                                 # 基因所表示数字的和(二进制转十进制)
        for i in self.gene:                     # 对于每位基因
            num *= 2                            # 前面所有位左移一位
            num += i                            # 加上此位
        return self.func(num)                   # 函数值作为适应度

def cross(n, g1: Gene, g2: Gene):
    '''
    ## 基因交叉函数
    ---
    n: 最大切断位置
    g1: 基因1
    g2: 基因2
    '''
    pos = random.randint(0, n)      # 随机选择一个位置切断
    # 交换操作
    g1_r = g1.gene[pos:]            # 暂存g1断点右边
    g2_r = g2.gene[pos:]            # 暂存g2断点右边
    g1.gene[pos:] = g2_r            # g2断点右边替换g1断点右边
    g2.gene[pos:] = g1_r            # g1断点右边替换g2断点右边

def next_gene(genes: list[Gene]):   # 轮盘赌法选择下一代基因
    '''
    ## 求下一代基因
    ---
    genes: 当前所有基因
    '''
    select_prob = []
    total_prob = 0.0                # 总概率值
    for g in genes:                 # 根据适应度计算选择每个基因的概率
        prob = g.cal_fitness()      # 求出此基因概率(适应度)
        select_prob.append(prob)    # 保存起来
        total_prob += prob          # 求总概率(适应度)
    
    new_genes: list[Gene] = []      # 保存新基因
    for i in range(len(genes)):     # 上一代有多少个,下一代就选多少个
        prob = random.randint(0, total_prob)    # 随机生成一个概率(位置)
        c = -1                      # 循环控制变量
        while prob > 0:             # 当prob没减完,说明还没到随机生成的位置
            c += 1                  # 循环变量加一
            prob -= select_prob[c]  # 按顺序减掉概率
        new_genes.append(genes[i])  # 到了就将此处的基因作为下一代的一个基因
    for i in range(int(len(genes) / 2)):     # 每两个子代基因进行交叉和变异
        cross(new_genes[i].n, new_genes[i], new_genes[i + 1])    # 交叉
        new_genes[i].mutation()     # 变异
        new_genes[i + 1].mutation() # 变异
    return new_genes                # 返回新基因

def best_gene(genes: list[Gene]):   
    '''
    ## 求一代中最好的基因
    ---
    genes: 所有基因
    '''
    best = 0                        # 保存最佳值
    for gene in genes:              # 对于每个基因
        fit = gene.cal_fitness()    # 计算适应度
        if fit > best:              # 如果比目前最好的好
            best = fit              # 替换最好的
    return best                     # 返回最好的基因


if __name__ == '__main__':          # 主函数
    genes = [Gene(n, func) for i in range(m)]   # 生成初始基因
    value = []                      # 保存每次迭代的最佳基因适应度
    i = 0                           # 循环控制变量
    while i < max_iter:             # 大于最大迭代次数退出
        genes = next_gene(genes)    # 生成下一代基因
        value.append(best_gene(genes))  # 保存最佳基因适应度
        i += 1                      # 循环变量加一
    print(max(value))               # 输出最大值
    ax1 = plt.subplot(1, 2, 1)
    x = np.arange(-30, 30)
    plt.plot(x, func(x))
    ax2 = plt.subplot(1, 2, 2)
    plt.plot(value)                 # 画图
    plt.show()                      # 显示图像
    
        

有问题请大佬指正。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值