python实现免疫算法,并绘制训练过程

news2024/12/26 21:38:47

免疫算法同遗传算法相似,不过子代是克隆出来的,而不是交叉,并且引入了抗体间亲和度的概念,算出抗体适应度之后,我们还需要减去抗体间亲和度,从而使得结果不容易陷入局部最优。

注意代码里的n是仅仅x的位数,基因里有x有y,所以基因型实际长度是2n

fitness_weight和concentration_weight这两个参数有兴趣的可以自己调调大小,看看变化

主要公式:激励度 = a*适应度+b*浓度

激励度是抗体克隆时,谁激励度大谁就能更容易被克隆

适应度就是抗体带入函数的结果归一化后的值

浓度这里时抗体间亲和度,用的海明距离。

a = fitness_weight,b = concentration_weight,注意一般b为负数,

采用抗体间亲和度可以给一些离群的抗体更多机会。

代码如下,训练结果建议自己运行,此处不放置结果视频

import numpy as np
import matplotlib.pyplot as plt
import random
import time  # 暂停用的,方便我录像,你们不需要


# 所用的函数
def Function(x_data, y_data):
    """
    :param x_data: x数值
    :param y_data: y数值
    :return: 输出表达式计算出的z
    """
    # 本来想找个能可视化捏函数,给表达式的方法,在matlab绘图中发现这个表达式长得不错,就直接用了。
    return 3 * (1 - x_data) ** 2 * np.exp(-x_data ** 2 - (y_data + 1) ** 2) - 10 * (
            x_data / 5 - x_data ** 3 - y_data ** 5) * np.exp(
        -x_data ** 2 - y_data ** 2) - np.exp(-(x_data + 1) ** 2 - y_data ** 2)


def Get_Grid():  # 生成坐标网格
    """
    :return: 返回Function的x,y,z
    """
    # 生成坐标网格
    x = np.linspace(-4, 4, 100)  # 坐标轴是-3~3,100个均匀分布,为了个体不跑到图片外,修改至-4~4
    y = np.linspace(-4, 4, 100)
    x, y = np.meshgrid(x, y)  # 按刚刚的坐标轴生成二维矩阵
    z = np.array(Function(x, y))  # 调用生成函数,获得y值
    return x, y, z


def Get_Random_gene(number, n):  # 随机生成基因型
    """
    :param number: 生成个数
    :param n: x的总位数
    :return: 生成的族群
    """
    return np.random.randint(0, 2, size=(number, n + n))


def Plot_Draw_F(fig, x, y, z):  # 绘图,重新绘制F的图像,返回引用
    """
    :param fig:     窗口的引用
    :param x:
    :param y:
    :param z:
    :return:    axes_3d,画布引用
    """
    fig.clf()
    axes_3d = fig.add_subplot(111, projection='3d')
    cmap = plt.cm.viridis  # 设定变色的颜色,可选项:viridis, plasma, inferno, magma, cividis 等
    norm = plt.Normalize(vmin=-5, vmax=5)  # 颜色变化范围,不设置就是按z轴最大最小,
    img_f = axes_3d.plot_surface(x, y, z, rstride=1, cstride=1, alpha=0.75, cmap=cmap, norm=norm)  # 绘制3D图
    # 长得还是有点抽象,一会发一下三视图,就能知道函数大概形状了
    # 添加颜色条
    cbar = fig.colorbar(img_f, ax=axes_3d)
    cbar.set_label('Color')
    # 设置坐标轴范围和标签
    axes_3d.set_xlim(-4, 4)
    axes_3d.set_ylim(-4, 4)
    axes_3d.set_zlim(-10, 10)
    axes_3d.set_xlabel('X')
    axes_3d.set_ylabel('Y')
    axes_3d.set_zlabel('Z')
    return axes_3d


def Plot_Scatter(ax, plot_gene_data, plot_z, colour):  # 根据解码后数据绘制种群的散点图
    """
    :param ax: 画布引用
    :param plot_z: 计算出的z值
    :param plot_gene_data: 全部基因型转码后的数据
    """
    for i in range(len(plot_z)):
        ax.scatter(plot_gene_data[i][0], plot_gene_data[i][1], plot_z[i], c=colour, marker='o')
    # 刷新图形
    plt.draw()
    plt.pause(1e-3)


# 解码,将全部二进制基因型数据转换为数值
def Decoding(data, n, point):  # 输入的分别是要解码的列表,x,y,的位数,小数位数
    """
    :param data: 要解码的列表,[[x符号,x整数部分,x整数部分,x整数部分,x小数部分,x小数部分,······y符号,y整数部分,x整数部分,x整数部分,y小数部分,y小数部分,],]
    :param n: x的总位数
    :param point: 小数位数
    :return: 二进制基因型数据转换的数值
    """
    # 在这个例子中,x,y的取值范围为-3~3,整数刚好整2位,加一位符号位,加上小数部分就-4~4了(为了不跑到图像外,修改一下图像范围),
    # 小数部分不用太多,整个8位,就差不多够了,所以前11位x,后11位y,正负只看第一个符号,1正0负
    # [x符号,x整数部分,x整数部分,x整数部分,x小数部分,x小数部分,······y符号,y整数部分,x整数部分,x整数部分,y小数部分,y小数部分,]
    decode_data = []
    for i in data:  # 遍历每个个体,转码
        x = Decoding_to_decimal(i[0:n], n, point)
        y = Decoding_to_decimal(i[n:], n, point)
        decode_data.append([x, y])
    return decode_data


def Decoding_to_decimal(data, n, point):
    # 仅一个x或y的转换
    integer_len = n - point
    decimal_data = 0
    for i in range(1, integer_len):  # 整数部分 2^n n=0,1,2···
        decimal_data += data[i] * 2 ** (integer_len - i - 1)
    for i in range(point):  # 小数部分 1/2^n n = 1,2,3···
        decimal_data += data[i + integer_len] / 2 ** (i + 1)
    return (data[0] * 2 - 1) * decimal_data


def Get_gene_z(data):  # 根据解码后数据,计算z值
    """
    :param data: 全部基因型转码后的数据
    :return: z值,z最大值,z最小值
    """
    data_z = []
    max_z = -float("inf")
    min_z = float("inf")
    for i in range(len(data)):
        data_z.append(Function(data[i][0], data[i][1]))
        if data_z[i] > max_z:
            max_z = data_z[i]
        if data_z[i] < min_z:
            min_z = data_z[i]
    return data_z, max_z, min_z


def Get_Fitness(data, max_data, min_data, maximum):  # 计算适应度,这里用z的归一化加次方
    """
    :param data: 需要计算的z值列表
    :param max_data: z最大值
    :param min_data: z最小值
    :param maximum: 数值较大适应度高?
    :return: 适应度列表
    """
    gap = max_data - min_data  # 最大最小值的差距
    if (maximum):
        fitness = [((i - min_data) / gap) for i in data]  # 归一化
    else:
        fitness = [((max_data - i) / gap) for i in data]  # 归一化
    return fitness


def Get_Concentration(data, n):  # 计算抗体间亲和度,这里用海明距离
    # 海明距离: 看所有位上的值,一样亲和度+1,
    lendata = len(data)
    concentration = []
    for i in range(lendata):
        concentration.append(0)
        for j in data:
            for k in range(n + n):
                if data[i][k] == j[k]:
                    concentration[i] += 1
        concentration[i] /= lendata * (n + n)
    return concentration


def Get_Incentive(fitness, concentration, fitness_weight, concentration_weight):  # 计激励,激励=a*适应度-b*浓度
    lenfitness = len(fitness)
    data_array = [(fitness[i] * fitness_weight + concentration[i] * concentration_weight) for i in range(lenfitness)]
    min_value = np.min(data_array)
    max_value = np.max(data_array)
    return (data_array - min_value) / (max_value - min_value)


def Inheritance(parents, n):  # 克隆时,变异
    child = []  # 生出的孩子
    for i in range(n + n):  # 遍历每个基因点
        child.append(parents[0][i])  # 继承一个基因
        # 较高概率突变
        if random.random() < 0.05:
            child[i] = random.randint(0, 1)
    if random.random() < 0.01:  # 小概率全逆置
        child.reverse()
    return child


def Clone(number, data, n, incentive):  # 让抗体克隆到原先族群大小
    """
    :param number: 族群大小
    :param data:生育前的抗体基因
    :param n: x的总位数
    :param point: 小数位数
    :param incentive:激励度
    :return: 克隆完成的抗体
    """
    new_data = []
    initial_len = len(data)  # 初始个数
    if initial_len < 1:
        print("种族没人")
    for i in range(number):  # 克隆够了就停下
        parents = random.choices(data, weights=incentive)  # 根据激励随机选择一个抗体克隆
        new_data.append(Inheritance(parents, n))  # 克隆的抗体添加进族群
    return new_data


def Immunity_train(fig, gene_data, number, n, point, loop, x, y, z, fitness_weight=1, concentration_weight=-0.1,
                   maximum=True, ):  # 免疫算法训练,带过程绘制
    """
    :param fig: 窗口引用
    :param gene_data: 基因型
    :param number: 族群大小
    :param n: x的总位数
    :param point: 小数位数
    :param fitness_weight 相似度系数
    :param concentration_weight 浓度系数
    :param maximum: 是否求函数最大值,默认是
    :return: 最终的族群
    """
    new_gene = gene_data  # 开始的输入就是新族群
    for i in range(loop):  # 最大训练loop轮
        #
        gene_data = new_gene
        decode_data = Decoding(gene_data, n, point)  # 解码
        data_z, max_z, min_z = Get_gene_z(decode_data)  # 计算z
        fitness = Get_Fitness(data_z, max_z, min_z, maximum)
        concentration = Get_Concentration(gene_data, n)
        incentive = Get_Incentive(fitness, concentration, fitness_weight, concentration_weight)  # 求适应度
        ax = Plot_Draw_F(fig, x, y, z)  # 绘画出函数
        Plot_Scatter(ax, decode_data, data_z, "blue")  # 绘制全部个体
        if max_z - min_z < 1e-2:  # 认为训练完毕
            break
        # 开始克隆
        new_gene = Clone(number, gene_data, n, incentive)  # 抗体根据激励克隆到原先数目
    return new_gene


if __name__ == "__main__":
    # 建立窗口
    fig = plt.figure()
    # 生成坐标网格
    x, y, z = Get_Grid()
    plt.pause(1)  # 方便录像用,开窗口后等1秒再出图,你们建议删去
    # 参数设置
    number = 100  # 种群初始大小
    point = 15  # 小数位数
    n = point + 3  # x或y长度
    loop = 100  # 最大训练轮数
    gene_data = Get_Random_gene(number, n)  # 获得初始抗体基因
    gene_end = Immunity_train(fig, gene_data, number, n, point, loop, x, y, z,maximum=True)  # 免疫训练
    # 显示图形,完成后不消失
    plt.show()

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1098062.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华为云云耀云服务器L实例评测|企业项目最佳实践之docker部署及应用(七)

华为云云耀云服务器L实例评测&#xff5c;企业项目最佳实践系列&#xff1a; 华为云云耀云服务器L实例评测&#xff5c;企业项目最佳实践之云服务器介绍(一) 华为云云耀云服务器L实例评测&#xff5c;企业项目最佳实践之华为云介绍(二) 华为云云耀云服务器L实例评测&#xff5…

注册大量短视频矩阵账号很简单,这个方法教会你,还有这个批量剪辑神器帮你完成矩阵分发

一个人一天就能注册上百个抖音实名账号&#xff0c;那么是如何做到的呢&#xff1f;其实很简单&#xff0c;只需要一个营业执照就能办到。 一个营业执照可以点亮两个蓝v号&#xff0c;每个蓝v账号可以注册50个员工账号。 员工账号和个人号的实名是不冲突的&#xff0c;所以之前…

关闭VS Code中的鼠标悬停时的提示框(MDN Reference)

在使用VS Code编辑器写html文件时&#xff0c;鼠标悬停在写的某些内容时会弹出一个提示框&#xff0c;如下图&#xff1a; 这个提示是比较烦人的&#xff0c;接下来分享关闭它的教程&#xff1a; 这里是以Win10版的Visual Studio Code为例 1.打开VS Code 的设置界面 2.在扩展…

历史上最愚蠢的代码

目录 1. 马赛勒航天飞机坠毁&#xff1a; ​2. 2000年问题&#xff08;Y2K Bug&#xff09;&#xff1a; ​3. 阿里亚5号火箭爆炸&#xff1a; 4. Knight Capital Group的交易错误&#xff1a; 在编程历史上&#xff0c;有一些代码错误导致了严重的后果&#xff0c;可以被视…

旧手机热点机改造成服务器方案

如果你也跟我一样有这种想法, 那真的太酷了!!! ok,前提是得有root,不然体验大打折扣 目录 目录 1.做一个能爬墙能走百度直连的热点机(做热点机用) 2.做emby视频服务器 3.做文件服务, 存取文件 4.装青龙面板,跑一些定时任务 5.做远程摄像头监控 6.做web服务器 7.内网穿…

REF615 REU615 RED615 人工智能在工业中的第一步

REF615 REU615 RED615 人工智能在工业中的第一步 工业必须面对广泛的挑战:从气候变化和能源短缺到不稳定的供应链和技能短缺。成功应对这些挑战需要创新技术和明智的经济政策战略。 汉诺威工业博览会2023提供了两者:不仅是工业、立法者、学术界和社会代表之间交流的独特平台&a…

企业如何凭借软文投放实现营销目标?

数字时代下&#xff0c;软文投放成为许多企业营销的主要方式&#xff0c;因为软文投放成本低且效果持续性强&#xff0c;最近也有不少企业来找媒介盒子进行软文投放&#xff0c;接下来媒介盒子就来给大家分享下&#xff0c;企业在软文投放中需要掌握哪些技巧&#xff0c;才能实…

微信小程序开发之入门级02(带你进一步了解微信小程序开发)

目录 ​编辑 前言 一、 微信小程序的生命周期 1. 概述 2. 全局与页面的生命周期函数 2.1 全局的生命周期函数&#xff1a; 2.2 页面的生命周期函数&#xff1a; 3. 常用的生命周期函数和对应的应用场景 3.1 onLaunch&#xff08;小程序启动&#xff09; 3.2 onShow&am…

Mac卸载微信输入法方法

陪伴着「微信输入法」更新了N多个beta版本之后&#xff0c;最终还是选择卸载。 至今&#xff0c;微信输入法也没有来到1.0。 本来&#xff0c;每次期望着它能有更大的提升&#xff0c;但是最后发现&#xff0c;搞输入法确实也需要技术沉淀的。 但也必须承认&#xff0c;这个绿色…

【oceanbase】centos7/kylinv10部署oceanbase(x86版本)

1. 修改系统​ vim /etc/sysctl.conf fs.file-max 102400 net.nf_conntrack_max 1024000 net.netfilter.nf_conntrack_max 1024000 2. 修改 ulimit 的 open file&#xff0c;系统默认的 ulimit 对文件打开数量的限制是 1024 vim /etc/security/limits.conf # 加入以下…

消防应急疏散指示系统在某生物制药工厂项目的应用

安科瑞 华楠 摘要 消防应急照明和疏散指示系统由控制器、集中电源和灯具&#xff08;疏散指示灯具、应急照明灯具&#xff09;等几部分组成。系统采用17寸工业平板电脑、Windonws7系统&#xff0c;可支持联动报警、系统监控、故障报警、自检、备电、记录存储与查询、导光流、…

物流行业案例 | 甄知猪齿鱼助力构建高效研发体系,搭建统一的研发管理平台

随着全球经济的发展和电子商务的兴起&#xff0c;物流行业正经历着快速的变革和发展&#xff0c;作为支撑我国经济发展的重要基础设施&#xff0c;近年来社会物流总额一直保持着平稳增长的趋势。根据中国物流与采购联合会数据&#xff0c;2012-2022年&#xff0c;我国社会物流总…

Improving Generalization with Domain Convex Game

文章目录 AbstractIntroductionContributions Related WorkDomain GeneralizationConvex GameMeta Learning Domain Convex Game 使用域凸策略改进领域泛化 Abstract Domain generalization (DG) tends to alleviate the poor generalization capability of deep neural netwo…

在自己的摄像头上测试ORB_SLAM3

文章目录 硬件相机标定IMU标定依赖编译可能遇到的问题 硬件 x86电脑realsense d435i相机 相机标定 IMU标定 依赖 Ceres # CMake sudo apt-get install cmake # google-glog gflags sudo apt-get install libgoogle-glog-dev libgflags-dev # BLAS & LAPACK sudo apt…

STM32 外部中断

STM32 外部中断 中断系统 中断&#xff1a;在主程序运行过程中&#xff0c;出现了特定的中断触发条件&#xff08;中断源&#xff09;&#xff0c;使得CPU暂停当前正在运行的程序&#xff0c;转而去处理中断程序&#xff0c;处理完成后又返回原来被暂停的位置继续运行 中断就是…

ABeam ESG News | 深化校企合作,ABeam中国ESG与可持续发展负责人做客上海财经大学ESG主题讲座回顾

ABeam上海财经大学 近日&#xff0c;ABeam中国ESG与可持续发展负责人杨丽楠女士受邀来到上海财经大学&#xff0c;作为外语学院30周年院庆系列学术活动的分享嘉宾&#xff0c;为近200名学生开展了ESG主题专场讲座。本次讲座探讨了ESG&#xff08;环境、社会和治理&#xff09;因…

使用CFimagehost源码搭建无需数据库支持的PHP免费图片托管私人图床

文章目录 1.前言2. CFImagehost网站搭建2.1 CFImagehost下载和安装2.2 CFImagehost网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1 Cpolar临时数据隧道3.2 Cpolar稳定隧道&#xff08;云端设置&#xff09;3.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 4.公网访问测…

前端实现锥形渐变

锥形渐变 使用conic-gradient即可解决 渐变效果 width: 150px 和 height: 150px 设置元素的宽度和高度为 150 像素&#xff0c;使其呈现为一个正方形。border-radius: 50% 设置元素的圆角半径为 50%&#xff0c;使其呈现为一个圆形。border: 2px solid #000 设置元素的边框为…