MOEA/D: A Multiobjective Evolutionary Algorithm Based on Decomposition

news2024/12/25 9:01:48

目录

  • 1 问题定义
  • 2 算法步骤
  • 3 代码
  • 4 效果

1 问题定义

本博客以最小化问题为例
f 1 = x 2 f 2 = ( x − 2 ) 2 min ⁡ f = ( f 1 ( x ) , f 2 ( x ) ) \begin{aligned} f_1 & = x ^2 \\ f_2 & = (x - 2) ^2 \\ \min f & = (f_1(x), f_2(x)) \end{aligned} f1f2minf=x2=(x2)2=(f1(x),f2(x))

代码

def func1(population):
    res = population[:, 0] ** 2
    return res


def func2(population):
    res = (population[:, 0] - 2) ** 2
    return res

2 算法步骤

在这里插入图片描述

  1. E P EP EP:外部种群,大小一般为 10 ∗ s i z e 10 * size 10size( s i z e size size是种群大小)
  2. λ \lambda λ:权重向量,本文所提到的权重向量需要均匀分布,可以用numpy正态分布产生。
  3. z z z:是当代种群,每个目标的最小值
  4. B ( i ) B(i) B(i):当前点的邻居索引,邻居的计算使用欧氏距离,可以调用sklearn中的库完成
  5. g t e ( x ∣ λ j , z ∗ ) = max ⁡ { λ i j ∣ f i ( x ) − z ∗ ∣ } g^{te}(x|\lambda ^j, z^*) = \max\{\lambda_i^j|f_i(x) - z^*|\} gte(xλj,z)=max{λijfi(x)z},其中 1 ≤ i ≤ m 1 \leq i \leq m 1im(切比雪夫)

因为本博客以最小化问题为例,而原论文则是求解最大化问题,因此上方图片中要做如下修改
Step 2.3中的 z j > f j ( y ′ ) z_j > f_j(y') zj>fj(y)

注意:当目标数m<=2时适合用切比雪夫

3 代码

import numpy as np
import pandas as pd
from geatpy.core.ndsortESS import ndsortESS  # 非支配排序
from sklearn.neighbors import NearestNeighbors   # K近邻分类器
from geatpy.operators.mutation.Mutpolyn import Mutpolyn  # 多项式变异
from geatpy.operators.recombination.Recsbx import Recsbx  # 模拟二进制交叉
from geatpy.visualization.PointScatter import PointScatter  # 画图
from untils.SCH import func1, func2

# 通过Euclidean distance产生近邻
def get_neighbor(matrix, n_neighbors = 2):
    nbrs = NearestNeighbors(n_neighbors=n_neighbors, algorithm='kd_tree', metric='euclidean').fit(matrix)
    distances, indices = nbrs.kneighbors(matrix)
    return indices   # 返回邻居索引

# 在邻居集合里挑选两个邻居, 返回邻居索引
def select_neighbor(neighbor_indexs, prob_neighbor = 0.9):
    indices = []
    for index in neighbor_indexs:
        if len(indices) > 2: break
        probability = np.random.rand()
        if probability < prob_neighbor:
            indices.append(index)
    if len(indices) == 0:
        return neighbor_indexs[0:2]
    return indices   # 返回邻居索引


# 切比雪夫方法更新邻居解
def update_neighbor(weight_vector, neighbor_func, z, y_func):
    # 第一行 对应的为y的相关值
    copy_func = np.copy(neighbor_func)
    copy_func = np.abs(copy_func - z)     # 函数值 - 参考点
    te = np.multiply(weight_vector, copy_func)    # 叉乘
    y_te = np.multiply(weight_vector, np.abs(y_func-z))

    row_max = np.max(te, axis=1)
    bad_neighbor = []
    n = row_max.shape[0]
    for i in range(n):
        if np.max(y_te) <= row_max[i]:   # 需要对邻居更新
            bad_neighbor.append(i)

    return bad_neighbor

def update_external_population(pop, func, y, y_func):  # pop: 外部种群;func: 外部种群函数值

    if pop is None:
        pop = y
        func = y_func
    else:
        pop = np.row_stack((pop, y))
        func = np.row_stack((func, y_func))

    levels, criLevel = ndsortESS(func)
    levels = levels.astype('i4')  # float -> int
    pd_levels = pd.DataFrame(levels)  # numpy -> pandas
    rank_group = pd_levels.groupby(0).groups  # 等级分组
    best_rank = rank_group[1].values  # 最好等级的所有下标
    pop = pop[best_rank, :]
    func = func[best_rank, :]

    if func.shape[0] > K * size:
        r = np.random.randint(0, K * size, 1)
        pop = np.delete(pop, r, axis=0)
        func = np.delete(func, r, axis=0)
    return pop, func




if __name__ == '__main__':
    size = 50  # 种群大小
    dim = 2     # 目标函数的个数
    n = 1      # 决策变量的个数
    n_neighbor = 50    # 权重向量近邻的个数
    lb = np.full(n, -10)   # 自变量下限
    ub = np.full(n, 10)    # 自变量上限
    varTypes = np.full(n, 0)    # 离散 or 连续
    iteration = 250   # 迭代次数
    K = 2    # 外部种群大小 = K * size
    np.random.seed(1)
    # ===================== 产生均匀分布的权重向量 =======================
    weight_vector = np.random.randn(size, dim)
    ss = np.sum(weight_vector, axis=1)
    for k in range(dim):
        weight_vector[:, k] = weight_vector[:, k] / ss
    # ===================== 产生均匀分布的权重向量 =======================

    all_neighbor = get_neighbor(weight_vector, n_neighbor)

    # ========================= 产生随机种群 ===========================
    x = np.random.uniform(lb, ub, (size, n))
    func = np.column_stack((func1(x), func2(x)))
    ideal_points = np.min(func, axis=0)  # 所有函数值的最小值,即理想点
    # ========================= 产生随机种群 ===========================

    exter_pop = None   # 外部种群
    exter_obj = None   # 外部种群函数值

    PS = PointScatter(dim, True, True, "MOEA/D", ['F1', 'F2', 'F3'], saveName=None)
    for i in range(iteration):
        print(i)
        for s in range(size):
            # =========================  挑选两个邻居  ==========================
            neighbor = all_neighbor[s, :]   # 当前个体的邻居索引
            two_neighbor = np.random.choice(neighbor, size = 2, replace=False)
            neighborsX = x[two_neighbor, :]
            # =========================  挑选两个邻居  ==========================

            # ========================  进行交叉变异操作  =========================
            recsbx = Recsbx(XOVR=1, Half_N=True, n=20, Parallel=True)  # 交叉
            y = recsbx.do(neighborsX)
            mutation = Mutpolyn(Pm=1/n, DisI=20)  # 变异
            y = mutation.do(Encoding='RI', OldChrom=y, FieldDR=np.array([lb, ub, varTypes]))
            # ========================  进行交叉变异操作  =========================

            # =============================  更新z  ==============================
            y_func = np.column_stack((func1(y), func2(y)))
            for d in range(dim):
                ideal_points[d] = np.minimum(ideal_points[d], y_func[0, d])
            # =============================  更新z  ==============================

            # ===========================  更新邻居解  ============================
            weight_vector_neighbor = weight_vector[neighbor, :]      # 邻居的权重向量
            neighborsFunc = func[neighbor, :]          # 邻居的函数矩阵

            bad_neighbor = update_neighbor(weight_vector_neighbor, neighborsFunc,ideal_points, y_func)
            x[bad_neighbor, :] = y
            func[bad_neighbor, :] = y_func
            # ===========================  更新邻居解  ============================

            # ===========================  更新外部种群  ============================
            exter_pop, exter_obj = update_external_population(exter_pop, exter_obj, y, y_func)
            # ===========================  更新外部种群  ============================

    right_label = 'size: ' + str(K * size) + '\n' + 'iteration: ' + str(iteration)
    PS.add(exter_obj, color='purple', label=right_label)
    PS.draw()

4 效果

在这里插入图片描述

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

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

相关文章

二十、常用调优工具概述与Jprofiler演示

常用调优工具 1.JDK命令行 2.Eclipse:Memory Analyzer Tool 3.Jconsole 4.VisualVM 5.Jprofiler 6.Java Flight Recorder 7.GCViewer 8.GC Easy jprofiler 简介&#xff1a; 他把CPU、执行引擎和内存的剖析组合在一个强大的应用中。JProfiler可提供许多IDE整合和应用服务器整合…

集成学习boosting、bagging、stacking

目录 一、介绍 二、三种架构学习 &#xff08;1&#xff09;boosting &#xff08;2&#xff09;bagging &#xff08;3&#xff09;stacking 一、介绍&#xff1a; 对于单个模型来说很难拟合复杂的数&#xff0c;模型的抗干扰能力较低&#xff0c;所以我们希望可以集成多…

ElasticSearch 8 学习笔记总结(五)

文章目录一、ElasticSearch 8 版本二、ES8 集群 环境安装1. 生成安全证书2. 生成http证书3. 配置第一个节点4. 配置其他节点三、ES集群 关联问题解决四、 Kibana 安装和使用五、kibana 基础操作1. 索引操作2. 文档操作3. 文档搜索4. 索引模板六、分词器七、文档评分机制1. 什么…

上拉电阻与下拉电阻总结

文章目录相关概念介绍IO引脚的三态输出之高阻态---将逻辑门与系统其他部分隔离&#xff0c;电平外部控制IO引脚输出模型 推挽电路 与 开漏电路---单独开漏无高电平驱动能力原理介绍什么是上下拉电阻&#xff1f;---把IO口用电阻拉到正压VCC&#xff08;上拉&#xff09; 或 接地…

如何使用Docker容器部署O2OA(翱途)开发平台与OnlyOffice的集成版本?

O2OA(翱途)开发平台[下称O2OA平台或者O2OA]默认可以和OnlyOffice进行集成来实现在线文档编辑以及流程集成。开发者可以直接安装O2OA官网的OnlyOfficeO2Server的Docker版本用于体验。本文将详细介绍如何安装O2OA OnlyOffice的Docker版本。OnlyOffice Docs Sever可以单独安装,O2…

aws apigateway 使用httpapi私有集成ecs服务

参考资料 https://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/http-api-private-integration.htmlhttps://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/http-api-develop-integrations-private.html 在《aws apigateway 基础概念和入门示…

Vue2.0开发之——购物车案例-Goods组件封装-把购买数量传给counter组件(52)

一 概述 Goods组件中导入Counter组件设置Counter组件的数量 二 Goods组件中导入Counter组件 2.1 Goods组件中导入Counter组件 import Counter from "/components/Counter/Counter.vue";2.2 Goods组件中注册Counter组件 components:{Counter }2.3 Goods组件中使用…

GDKOI2023游记+一周模拟赛题解

温馨提示&#xff1a; 1)有些链接需要在本校OJ上的博客里才能打开。2)没更新完。 Day -6&#xff08;3.4&#xff09; 晚上打了场AtCoder&#xff0c;rank1515rank 1515rank1515&#xff0c;切了5题&#xff0c;信心。 zswangziye的atcoder账号 打T5的时候心态不稳&#xff…

2022年MathorCup数学建模A题大规模指纹图像检索的模型与实现解题全过程文档加程序

2022年第十二届MathorCup高校数学建模 A题 大规模指纹图像检索的模型与实现 原题再现 在生物特征识别领域&#xff0c;指纹作为最具独特性与持久性的生物特征之一&#xff0c;被广泛应用于身份识别。   指纹识别过程分为特征提取和比对两个环节。其中特征提取环节会提取用于…

matplotlib: 绘制柱状图

通过matplotlib绘制柱形图 第一个例子 from matplotlib import pyplot as plty [10, 11, 12, 11, 9, 8, 13, 10] # 创建y轴坐标 x list(range(1,9)) # 创建x轴坐标# 创建x轴显示的参数&#xff08;此功能在与在图像中x轴仅显示能被10整除的刻度&#xff0c;避免刻度过多分…

比亚迪:全球最大电动汽车制造商的坎坷成长之路

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 特斯拉&#xff08;TSLA&#xff09;首席执行官埃隆马斯克表示&#xff0c;特斯拉最接近的竞争对手可能是一家中国电动汽车公司。猛兽财经认为&#xff0c;沃伦•巴菲特支持的比亚迪&#xff08;0211&#xff09;可能是马斯…

在ubuntu上部署与使用docker(python)

1.安装Docker首先&#xff0c;更新现有的包列表sudo apt update接下来安装一些允许童HTTPS才能使用的软件包&#xff1a;sudo apt install apt-transport-https ca-certificates curl software-properties-common然后将官方Docker存储库的GPG秘钥添加到您的系统curl -fsSL http…

关于 C# 引用参数和值参数

关于 C# 引用参数和值参数 C# 数据类型分为值类型和引用类型&#xff0c;两者的区别在于值类型的数据存储在栈中&#xff0c;而引用类型的数据存储在堆中&#xff0c;但是栈中会存放指向存储数据的堆的位置。 传递参数时&#xff0c;传递的是数据栈中的值&#xff0c;实参将数…

高等数学——一元函数微分学

文章目录导数与微分概念几何意义连续、可导、可微之间的关系求导法则基本初等函数的导数公式有理运算法则复合函数求导法奇偶性和周期性隐函数求导反函数求导参数方程求导对数求导法高阶导数概念常用的高阶导数公式微分中值定理和导数的应用微分中值定理导数的应用函数的单调性…

巾帼绽芬芳 一起向未来(下篇)

编者按&#xff1a;为了隆重纪念纪念“三八”国际妇女节113周年&#xff0c;快来与你全方位、多层次分享交流“三八”国际妇女节的前世今生。分上篇&#xff08;节日简介、节日发展和节日意义&#xff09;、中篇&#xff08;节日活动宗旨和世界各国庆祝方式&#xff09;和下篇&…

Linux学习第二十节-NTP网络时间协议

1.概念 NTP(Network Time Protocol&#xff09;网络时间协议基于UDP用于网络时间同步的协议&#xff0c;使网络中的计算机时钟同步到UTC(世界统一时间)&#xff0c;再配合各个时区的偏移调整就能实现精准同步对时功能。 chrony是网络时间协议NTP的实现方式&#xff0c; Chron…

three.js 纹理贴图的使用

刚刚入门的小伙伴请先查看 three.js 基础认识与简单应用 本文章中的两个注意点&#xff0c;下面也有提到&#xff0c;分别是&#xff1a; 1、 vue项目中使用的贴图路径-->需要把 static文件夹 放到 public文件夹下,并使用 static 开头的绝对路径。 2、使用环境遮挡贴图时&a…

Air780E|阿里云|AT命令|物联网|三元组|鉴权|算法|密钥生成-阿里云物联网手动接入步骤

基础资料基于Air780E开发板&#xff1a;Air780E文档中心简介&#xff1a;AT开发探讨重点本系列主要探讨MQTT手动接入腾讯云物理网平台的基本操作及手动鉴权步骤、信息订阅及发布的基本原理。参考阅读&#xff1a;物联网模组AT命令接入云平台&#xff08;1&#xff09;-MQTT基本…

移动硬盘怎么恢复数据?怎么恢复硬盘删除的数据

移动硬盘可以随时插上或拔下&#xff0c;小巧而便于携带的硬盘存储器&#xff0c;以较高的速度与系统进行数据传输。由于其存储空间较大&#xff0c;性价比较高&#xff0c;存储和传输数据快速简便&#xff0c;是很多职场人士必备的外置设备之一。移动硬盘怎么恢复数据&#xf…

cuda代码高效策略--b站看课的笔记

1.1 高效公式 要么增大数据量&#xff0c;要么减少每个线程的内存&#xff08;每个线程读取的数据量变少&#xff0c;每个线程的读取数据的速度变快&#xff08;转变存储方式&#xff0c;对读取慢的地方做优化–合并全局内存&#xff09;&#xff09; 1.2 合并全局内存 一个线…