差分进化算法DE

news2024/11/16 11:49:16

此算法是一种基于贪心的并行直接搜索算法。

1.过程

(1)初始化种群

NP个D维的参数向量x_{i,g}(i=1,2,...,NP)作为每一代G种群,种群规模必须>=4

(2)变异

使用种群中两个不同向量来干扰一个现有向量,进行差分操作,实现变异。变异时需要确保变异向量不会超出边界,若超出则需要进行修正。F为变异因子∈[0,2],控制差分变化的放大倍数。

对于每个目标向量x_{i,G}都要根据三个不同向量生成一个变异向量v_{i,G+1}

(3)交叉

每个个体和它生成的子代变异向量进行交叉,每个分量按一定的概率选择子代变异向量来生成试验个体,若没有选择子代变异向量则此分量为原个体的分量。按照上述方法生成试验向量u_{i,j}(g)。CR为交叉概率因子;jrand是[1,...,D]中随机选择的索引,确保u从v获得至少一个分量。

(4)选择

根据贪婪原则,如果试验向量成本函数值<目标向量成本函数值,则下一代的种群个体设置为试验向量,否则保留上一代的目标向量。

2、流程图

3、代码

from random import random
from random import sample
from random import uniform
import matplotlib.pyplot as plt
import matplotlib
matplotlib.use('TkAgg')

# 向量维度的平方求和
def sphere(x):
    total = 0
    for i in range(len(x)):
        total += x[i]**2
    return total

# 确保变异向量不超出边界
def ensure_bounds(vec, bounds):
    vec_new = []
    # 遍历变异向量的每个维度
    for i in range(len(vec)):
        # 变量比边界最小值还小,赋值为边界最小值
        if vec[i] < bounds[i][0]:
            vec_new.append(bounds[i][0])
        # 变量比边界最大值还大,赋值为边界最大值
        if vec[i] > bounds[i][1]:
            vec_new.append(bounds[i][1])
        # 变量满足边界条件,不进行操作
        if bounds[i][0] <= vec[i] <= bounds[i][1]:
            vec_new.append(vec[i])
    return vec_new


# ——————————————————————————DE————————————————————————————————

def minimize(bounds, popsize, mutate, recombination, maxiter):
    # 种群初始化

    population = []     # 空的种群
    gen_avg_record = []     # 适应度平均值
    gen_best_record = []        #适应度最优值
    for i in range(0, popsize):
        indv = []
        for j in range(len(bounds)):    # D=2,所以j取0,1
            indv.append(uniform(bounds[j][0], bounds[j][1]))     # uniform 均匀分布
        population.append(indv)     # append 追加

    # 进行迭代

    for i in range(1, maxiter+1):
        print("generation:", i)     #输出种群
        gen_scores = []

        for j in range(0, popsize):
            # 变异
            candidates = list(range(0, popsize))
            candidates.remove(j)    # 去除目标向量的序号
            random_index = sample(candidates, 3)    # 从candidates中随机抽取除3个元素
            x_1 = population[random_index[0]]   # 抽到2,则选取种群中第二个个体作为x_r1g
            x_2 = population[random_index[1]]
            x_3 = population[random_index[2]]
            x_t = population[j]     # 目标向量

            # x_r2g减x_r3g,生成新向量 x_diff
            # zip(numbers, letters) 生成 (x, y) 形式的元组的迭代器,x取自数字.y取自字母
            x_diff = [x_2_i - x_3_i for x_2_i,x_3_i in zip(x_2, x_3)]

            # 变异向量 v_ig+1 = x_r1g +F * (x_r2g - x_r3g)
            v_donor = [x_1_i + mutate * x_diff_i for x_1_i, x_diff_i in zip(x_1, x_diff)]
            # 确保变异向量在边界内
            v_donor = ensure_bounds(v_donor, bounds)

            # 交叉
            v_trial = []    # 试验向量
            for k in range(len(x_t)):
                crossover = random()    # 生成[0,1]内的随机数
                if crossover <= recombination:
                    v_trial.append(v_donor[k])
                else:
                    v_trial.append(x_t[k])

            # 选择
            score_trial = sphere(v_trial)   # sphere:向量各个维度的平方和
            score_target = sphere(x_t)

            if score_trial < score_target:
                population[j] = v_trial
                gen_scores.append(score_trial)
                print(">", score_trial, v_trial)
            else:
                print(">", score_target, x_t)
                gen_scores.append(score_target)

        gen_avg = sum(gen_scores) / popsize
        gen_best = min(gen_scores)
        gen_avg_record.append(gen_avg)
        gen_best_record.append(gen_best)
        gen_sol = population[gen_scores.index(min(gen_scores))]

        print(",种群平均值:", gen_avg)
        print(",种群最优值:", gen_best)
        print(",最好结果:", gen_sol)

        pass

    # 画图
    plt.plot([i for i in range(len(gen_best_record))], gen_best_record, 'b')
    plt.plot([i for i in range(len(gen_avg_record))], gen_avg_record, 'r')
    plt.ylabel('fitness')
    plt.xlabel('generation')
    plt.yticks([0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6])  # 设置y轴刻度
    plt.xticks([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20])  # 设置x轴刻度
    plt.legend(['gen_best', 'gen_avg'])
    plt.show()

#设置参数
bounds = [(-1,1),(-1,1)]    # 维度D=2,搜索空间范围也叫约束边界
popsize = 10    # 种群规模NP
mutate = 0.5    # 变异因子 F
recombination = 0.7    # 交叉概率 CR [0,1]
maxiter = 20    # 最大迭代次数
# DE/rand/1/bin
minimize(bounds, popsize, mutate, recombination, maxiter)

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

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

相关文章

生活是自己的,请尽情打扮,尽情可爱

端庄大气又尽显GAO级感 的明制汉服处处都是是惊喜 领口袖口拼接仿貂毛环保毛条 保暖又精致 袖子贴民族风珠片刺绣织带 门襟搭配金属子母扣 前胸欧根纱刺绣圆形布贴 每一处都是用心制作 红色喜庆&#xff0c;用来做拜年服来穿再合适不过啦

[C语言]大小端及整形输出问题

假设在一个32位little endian 的机器上运行下面的程序&#xff0c;结果是多少 ? 1.1先看以下三个程序 #include <stdio.h> int main() {long long a 1, b 2, c 3;printf("%lld %lld %lld\n", a, b, c); // 1 2 3printf("%d %d %d %d %d %d\n&quo…

AXB外呼系统怎样提高工作效率呼叫系统

AXB 外呼系统是一种帮助企业提高外呼效率的解决方案&#xff0c;它结合了自动拨号&#xff08;A&#xff09;和人工坐席&#xff08;X&#xff09;&#xff0c;使企业能够更快速、高效地与潜在客户进行沟通。以下是提高工作效率的一些方法&#xff1a; 预设任务和脚本&#xff…

【Linux】fork()函数详解

什么是fork&#xff1f; fork&#xff08;&#xff09;函数通过系统调用并创建 一个与原来进程几乎完全相同的进程 此进程叫做子进程&#xff0c;两个进程做一样的事 但初始参数或者传入的变量不同&#xff0c;两个 进程便可以做不同的事 fork的返回值 在父进程中&#xff0…

05进程间通信-学习笔记

进程间通信&#xff08;IPC&#xff09; 概念 进程信技术简称IPC,可以利用此技木让多个进程相传建消数据&#xff0c;有大量的进程间通信方案 pipe 匿名管道fifo 命名管简单理解&#xff0c;管道文件是一个指向内核管道缓冲区的指针&#xff0c;所有向管道文件读写的操作&am…

Mybatis 拦截器实现单数据源内多数据库切换

大家好&#xff0c;我是 方圆。物流的分拣业务在某些分拣场地只有一个数据源&#xff0c;因为数据量比较大&#xff0c;将所有数据存在一张表内查询速度慢&#xff0c;也为了做不同设备数据的分库管理&#xff0c;便在这个数据源内创建了多个不同库名但表完全相同的数据库&…

阿昌教你如何使用通义灵码

阿昌教你如何使用通义灵码 Hi&#xff0c;我是阿昌&#xff0c;今天教你如何使用通义灵码。 一、通义灵码是什么 在使用前&#xff0c;肯定要知道通义灵码是个啥东西&#xff1b; 通义灵码&#xff0c;是阿里云出品的一款基于通义大模型的智能编码辅助工具&#xff0c;提供…

三大维度解码剑南春“高质量发展”丨年度盘点

执笔 | 洪大大 编辑 | 扬 灵 2023年即将画上句点&#xff0c;当我们回首这一年为行业带来惊喜的品牌&#xff0c;剑南春是其中之一。 回顾剑南春今年一整年的动作&#xff0c;从新品频发到双节&#xff08;618、双11&#xff09;热销&#xff0c;从全国巡展到荣誉满载&…

经纬恒润以太网网关,智能时代网络通关

汽车产业新四化步伐持续加速&#xff0c;智能网联逐渐成为整车标配&#xff0c;随着近年来相关政策频出以及对网联需求和功能的深度挖掘与发展&#xff0c;中国本土市场及本土供应商在这场新浪潮中逐渐走向C位。经纬恒润深耕智能网联领域多年&#xff0c;先后推出四代网关产品&…

UE Niagara - Bean 制作闪电

开启Beam的四个前提条件 Jitter Position可以使得Bean弯曲&#xff0c;但是是有曲线的弯曲&#xff0c;没有硬度 所以得调这个 把该值设置为1 Mode改为Custom

程序员月经焦虑 :如何成为高级工程师

高级工程师意味着什么&#xff1f; ChatGPT的回复&#xff1a;高级工程师对编程语言、软件设计原则和开发方法有深刻的理解。 开发方法 开发方法学是旨在使团队有效的组织方法。这些对我们来说可能很无聊&#xff0c;但我们希望你在这方面有专业知识。 我已经对非敏捷开发方法…

学生上课犯困怎么办

当你作为学生上课犯困时&#xff0c;首先不要过于自责或沮丧&#xff0c;因为这是很常见的情况。以下是一些建议&#xff0c;帮助你克服这个问题&#xff0c;保持专注并提高学习效率。 保持良好的作息习惯 睡眠对于大脑的健康和功能至关重要。确保每晚获得足够的睡眠&#xff…

《PySpark大数据分析实战》-07.Spark本地模式安装

&#x1f4cb; 博主简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是wux_labs。&#x1f61c; 热衷于各种主流技术&#xff0c;热爱数据科学、机器学习、云计算、人工智能。 通过了TiDB数据库专员&#xff08;PCTA&#xff09;、TiDB数据库专家&#xff08;PCTP…

C语言数据结构-----二叉树(2)堆的深入理解及应用、链式二叉树的讲解及代码实现

前言 本篇文章讲述的内容有部分是上一节写过的。重复内容不会再进行说明&#xff0c;大家可以看上一节内容 链接: C语言数据结构-----二叉树(1)认识数、二叉树、堆及堆的代码实现 文章目录 前言1.使用堆解决TOP-K问题2.向下调整堆的时间复杂度与向上调整堆的时间复杂度对比3.堆…

Android多进程和跨进程通讯方式

前言 我们经常开发过程中经常会听到线程和进程&#xff0c;在讲述Android进程多进程前我打算先简单梳理一下这俩者。 了解什么是进程与线程 进程&#xff1a; 系统中正在运行的一个应用程序&#xff0c;某个程序一旦运行就是一个进程&#xff0c;是资源分配的最小单位&#…

HarmonyOS--基础组件Text

Text组件 可以包含Span子组件。 接口 Text(content? : string | Resource) string: Text(我是ttttt) Resource: Text($r(app.string.aaaaaa)) 先找限定词目录&#xff0c;找不到内容 找base目录 属性 除支持通用属性外&#xff0c;还支持以下属性&#xff1a; 名称 参数…

玄关柜和鞋柜是一回事吗?福州中宅装饰,福州装修

玄关柜和鞋柜虽然都用于存放鞋子&#xff0c;但它们在概念上有所不同。玄关柜是一个更大的概念&#xff0c;它包括鞋柜和其他功能区域&#xff0c;可以说鞋柜是玄关柜的一部分。 1️⃣概念上的不同 玄关柜是一种集成了鞋柜、挂衣架、换鞋凳等多种功能于一体的家居家具&#xf…

大数据安全 | 【实验】Diffie-Hellman密钥交换算法

文章目录 &#x1f4da;关于DH密钥交换算法&#x1f4da;实验目的&#x1f4da;流程梳理&#x1f407;Step1&#xff1a;实现快速幂取模运算&#x1f407;Step2&#xff1a;根据算法原理分别定义公钥和共享密钥的计算&#x1f407;Step3&#xff1a;求解问题一&#x1f407;Ste…

LeetCode-2487. 从链表中移除节点【栈 递归 链表 单调栈】

LeetCode-2487. 从链表中移除节点【栈 递归 链表 单调栈】 题目描述&#xff1a;解题思路一&#xff1a;可以将链表转为数组&#xff0c;然后从后往前遍历&#xff0c;遇到大于等于当前元素的就入栈&#xff0c;最终栈里面的元素即是最终的答案。解题思路二&#xff1a;递归&am…

uniapp使用vue3的ref获取dom元素出现undefined

在我的代码里面&#xff0c;已经通过ref来定义想要获取的dom了&#xff0c;但是最后在页面渲染完之后&#xff0c;打印这个dom发现竟然是undefined&#xff1a; 获取不到dom元素&#xff1a; 最后查资料发现&#xff1a; 小程序中&#xff0c;uniapp的ref要绑定在子组件中才能…