matlab新手快速上手6(引力搜索算法)

news2024/11/20 8:48:10

        本文根据一个较为简单的matlab引力搜索算法框架详细分析蚁群算法的实现过程,对matlab新手友好,源码在文末给出

引力搜索算法简介:

        引力搜索算法是一种启发式优化算法,最初于2009年由伊朗的Esmat Rashedi、Hossein Nezamabadi-pour和Saeid Saryazdi提出。这种算法灵感来源于引力的物理现象,其中个体之间的相互吸引力和排斥力决定了它们的运动轨迹,进而影响到最终的优化结果。

        这个算法的核心思想是模拟物体之间的引力和排斥力,以在解空间中搜索最优解。具体来说,每个解(个体)都被视为具有质量的物体,它们之间的相互作用由引力和排斥力来描述。通过计算每个解受到的引力和排斥力,可以更新它们的位置,以期望获得更优的解。

引力搜索算法的一般步骤如下:

  1. 初始化:随机生成初始解(个体)的位置。
  2. 计算适应度:计算每个解的适应度,也就是目标函数的值。
  3. 计算引力和排斥力:根据每个解之间的距离和适应度,计算相互之间的引力和排斥力。
  4. 更新位置:根据引力和排斥力的作用,更新每个解的位置。
  5. 重复迭代:重复执行步骤2到步骤4,直到达到终止条件(如达到最大迭代次数)。
  6. 输出结果:输出最优解或者最优解对应的适应度值。

        引力搜索算法的性能取决于参数的选择、种群大小和迭代次数等因素。这种算法适用于解决各种优化问题,包括连续型和离散型优化问题。

开始编程:

参数与子函数定义:

%============================== 引力搜索算法 ==============================
function GSA
%--------------------------------- 共性参数 -------------------------------
NP=30;                             %种群规模
D=10;                              %变量个数
Max_N=1000;                        %限定代数
G0=100;                            %引力常数
alpha=20;                          %引力常数
K0=NP;                             %更新常数
K1=1;                              %更新常数
%--------------------------------- 个性参数 -------------------------------
MinX=-30; MaxX=30;
%-------------------------------- 设置随机数 -------------------------------
rand('state',round(sum(100*clock)));
%---------------------------------- 初始化 ---------------------------------
X=MinX+(MaxX-MinX)*rand(NP,D);
V=zeros(NP,D);
%子函数(目标函数)
function fun=ackley(X)
fun=20+exp(1)-20*exp(-0.2*(sum(X.^2)/length(X))^0.5)...
    -exp(sum(cos(2*pi*X))/length(X));

参数定义:

        与前几章相同,NP代表天体个数,D代表解的维度。这里rand('state',round(sum(100*clock)));这行代码表示设置随机数种子,以确保每次运行程序时生成的随机数序列是不同的。

        初始化,生成X矩阵,矩阵维度为NP行D列,元素值为(MinX,MaxX)之间的随机值。V矩阵为NP行D列的元素全为0的矩阵。

子函数(目标函数):

数学公式:

f(x_1, x_2, \ldots, x_n) = 20 + e - 20 \cdot e^{-0.2 \sqrt{\frac{1}{n} \sum_{i=1}^{n} x_i^2}} - e^{\frac{1}{n} \sum_{i=1}^{n} \cos(2\pi x_i)}

函数性质:

        由公式可知,此函数有多个极小值点,但最小值点在原点处,也就是当x(i)都为0时函数最小,为0。 此算法的目标是找到函数的全局最小值点,即找到使函数值最接近0的变量取值。

主函数:

%--------------------------------- 优化开始 -------------------------------
for gen=1:1:Max_N
    G=G0*exp(-alpha*gen/Max_N);
    K=round(K0+(K1-K0)*gen/Max_N);
    for i=1:1:NP
        F(i)=ackley(X(i,:));
    end
    [bestF,bestNo]=sort(F);
    best=min(F);
    worst=max(F);
    if best<worst
        m=(F-worst-eps)/(best-worst);
    else
        m=ones(1,NP);
    end
    M=m/sum(m);
%-------开始引力搜索-------
    for i=1:1:NP
        for k=1:1:D
            Ft(i,k)=0;
            for j=1:1:K
                if bestNo(j)~=i
                    tF(i,bestNo(j),k)=G*M(i)*M(bestNo(j))*...
                      (X(bestNo(j),k)-X(i,k))/norm(X(i,:)-X(bestNo(j),:));
                    Ft(i,k)=Ft(i,k)+rand*tF(i,bestNo(j),k);
                end
            end
        end
    end
    for i=1:1:NP
        a(i,:)=Ft(i,:)/M(i);
    end
    V=rand(NP,D).*V+a;
    X=X+V;
    %----------------------------- 记录结果 -------------------------------
    GlobalMin_itr(gen)=best;
    if mod(gen,100)==0
        disp(['代数:',num2str(gen),'----最优:',num2str(best),...
            '----中值:',num2str(median(F)),'----均值:',...
            num2str(mean(F)),'----方差:',num2str(var(F))]);
    end
end
GlobalMin=best;
GlobalParams=X(bestNo(1),:);
plot([1:Max_N],GlobalMin_itr);
title('收敛曲线');

         第一个for循环表示循环迭代次数。

        G表示引力常数,公式为:G = G_0 \cdot e^{-\frac{alpha \cdot gen}{MaxN}}可知这是一个递减函数,也就是随着gen的增加,G值越小,也就是迭代次数越多,引力越小。

        K表示更新常数,公式为:K = \text{round}\left(K0 + \frac{(K1 - K0) \cdot gen}{MaxN}\right),round函数表示四舍五入取整,这个公式表示通过线性插值的方式,将K在迭代过程中逐步从K0变为K1。也就是K0是初始更新常数,K1是最终的更新常数。

        接下来的for循环计算每个个体的适应度的值,存储在F对应的元素中。best存储最好的适应度的值,worst存储最差的,当最小值小于最差值时,计算归一化因子m对适应度的值进行归一化,也就是最好的个体对应的m为1,最差的对应为0。

        M为整体归一化过程,M中所有元素加起来为1,这个框架中的M的计算过程有点繁琐,可以直接采用M = ((1./F)/sum(1./F))来计算,效果是一样的,下面开始引力搜索,两个for循环遍历所有个体的所有元素,先让此元素为0。再次根据K更新常数进行遍历其他天体对此天体的引力影响。

        为什么根据K更新常数进行遍历呢,由上面可知,K是随着遍历次数增多而减少,线性地从NP减少到1,也就意味着在循环开始时,遍历所有个体对当前个体的引力,随着循环次数增多,K就能舍去最小的天体引力,也就是适应度最差的个体,在循环快到最后时,将只计算前几个引力强的个体对当前天体的影响。这就是K的作用。

        接下来是代码的核心部分

        首先先了解一下引力公式:F = G\frac{Mm}{r^{2}}由引力公式可得出引力与M和m质量成正比,与r呈反比,因此下面实现通过引力更新位置的代码:

        if控制自身天体不会受自身引力影响,接下来就是计算当前天体受到前K个最优天体的引力影响后的方向与位置。tF矩阵中存储三个元素,表示第i个天体受到第bestNo(j)个天体在第k个维度的变化。G表示引力常数,G*M(i)*M(bestNo(j))表示对应上面引力公式的GMm,通过适应度表示质量,因此这个代码就实现了两个引力相互影响下的引力,这部分就实现了公式中的G\frac{Mm}{}部分。

        接下来实现r^{2}部分,由于引力与距离也有关系,距离越大引力越小那么继续编写代码

首先先理解norm函数,再matlab中,norm([3,4])将返回 5,做这个运算: \sqrt{3^2 + 4^2} = 5 。norm函数就是计算得出两个天体的欧几里得距离.

*(X(bestNo(j),k)-X(i,k))/norm(X(i,:)-X(bestNo(j),:));这里是难点 原代码中使用的是直接除以距离,虽然这样也可以,但是对比引力公式,这样这不便于理解,但是似乎效果更好,我在这里将源代码更改为此形式:

(X(bestNo(j),k)-X(i,k))/norm(X(i,:)-X(bestNo(j),:))^2;

来看此公式,/norm(X(i,:)-X(bestNo(j),:))^2;实现了/r^{2}这一部分,难点在于X(bestNo(j),k)-X(i,k)如何理解,为什么要乘以这个值呢?答案是控制引力方向。如下图所示,当不乘上这个值时,这样我们只计算出了具体的引力值大小F,但是我们需要的是将引力F映射到对应维度的力上,为了使F方向不改变,那么对应的F1和F2就要等比例缩放,因此再乘以X(bestNo(j),k)-X(i,k)这个差值就实现了将力分解到对应的维度上。

如图表示:二维状态下的力:

        继续通过Ft(i,k)更新第i个天体的第k个维度的受力,用当前维度的力加上tF,tF(i, bestNo(j), k)表示是第i个天体再第bestNo(j)个引力影响下第k维的力。再乘以随机值增加多样性,这样就得到了某个天体在前K个天体的引力影响下,在所有维度的的引力大小。

        继续看下面的代码,a(i,:)=Ft(i,:)/M(i)表示第i个天体的加速度,将时间设为单位时间,那么v = \frac{\Delta s}{\Delta t}a = \frac{\Delta v}{\Delta t},就变为v = \Delta sa = \Delta v,因此V=rand(NP,D).*V+a;就表示速度的变化,X=X+V;就表示经过距离的变化后的X。这样就实现了在引力作用下,一个单位时间的天体位置更新。后续就是结果处理,绘制图像等过程。

norm函数:

在 MATLAB 中,norm函数用于计算向量的范数。它可以计算向量的不同类型的范数,包括:

  1. 二范数(默认):向量元素的平方和的平方根。
  2. 一范数:向量元素的绝对值之和。
  3. 无穷范数:向量元素的绝对值的最大值。

语法通常是norm(X)其中X是一个向量。例如,norm([3,4])将返回 5,因为这个向量的二范数是 \sqrt{3^2 + 4^2} = 5 ,norm([3,4,5]) = \sqrt{3^2 + 4^2 + 5^2} = 7.0711

源代码:

%============================== 引力搜索算法 ==============================

%                  一个伊朗人2009年提出的一个非常漂亮的算法

%============================== 引力搜索算法 ==============================
function GSA
%--------------------------------- 共性参数 -------------------------------
NP=30;                             %种群规模
D=10;                              %变量个数
Max_N=10000;                        %限定代数
G0=100;                            %引力常数
alpha=20;                          %引力常数
K0=NP;                             %更新常数
K1=1;                              %更新常数
%--------------------------------- 个性参数 -------------------------------
MinX=-30; MaxX=30;
%-------------------------------- 设置随机数 -------------------------------
rand('state',round(sum(100*clock)));
%rng(round(sum(100*clock)));
%---------------------------------- 初始化 ---------------------------------
X=MinX+(MaxX-MinX)*rand(NP,D);
V=zeros(NP,D);
%--------------------------------- 优化开始 -------------------------------
for gen=1:1:Max_N
    G=G0*exp(-alpha*gen/Max_N);
    K=round(K0+(K1-K0)*gen/Max_N);
    for i=1:1:NP
        F(i)=ackley(X(i,:));
    end
    [bestF,bestNo]=sort(F);
    best=min(F);
    worst=max(F);
    if best<worst
        m=(F-worst-eps)/(best-worst);
        %if gen == 10000
        %    disp(X(bestNo,:));
        %end
        
    else
        m=ones(1,NP);
    end
    %M=m/sum(m);
    M = ((1./F)/sum(1./F));
   %-------开始引力搜索-------
    for i=1:1:NP
        for k=1:1:D
            Ft(i,k)=0;
            for j=1:1:K
                if bestNo(j)~=i
                    tF(i,bestNo(j),k)=G*M(i)*M(bestNo(j))*...
                    (X(bestNo(j),k)-X(i,k))/norm(X(i,:)-X(bestNo(j),:));
                    %tF(i,bestNo(j),k)=G*M(i)*M(bestNo(j))*...
                    %(X(bestNo(j),k)-X(i,k))/norm(X(i,:)-X(bestNo(j),:))^2;
                    Ft(i,k)=Ft(i,k)+rand*tF(i,bestNo(j),k);
                end
            end
        end
    end
    for i=1:1:NP
        a(i,:)=Ft(i,:)/M(i);
    end
    V=rand(NP,D).*V+a;
    X=X+V;
    %----------------------------- 记录结果 -------------------------------
    GlobalMin_itr(gen)=best;
    if mod(gen,100)==0
        disp(['代数:',num2str(gen),'----最优:',num2str(best),...
            '----中值:',num2str(median(F)),'----均值:',...
            num2str(mean(F)),'----方差:',num2str(var(F))]);
    end
end
GlobalMin=best;
GlobalParams=X(bestNo(1),:);
plot([1:Max_N],GlobalMin_itr);
title('收敛曲线');

function fun=ackley(X)
fun=20+exp(1)-20*exp(-0.2*(sum(X.^2)/length(X))^0.5)...
    -exp(sum(cos(2*pi*X))/length(X));

结语:

        此章节为作者为准备考试所复习,暂时结束,大致的经典优化算法就是这些,后续遇到更好的智能优化算法还会继续更新。

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

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

相关文章

Vitis HLS 学习笔记--HLS入门示例集合-目录

目录 1. 示例集合概述 2. Interface 接口 2.1 Aggregation_Disaggregation 聚合与解聚 2.1.1 aggregation_of_m_axi_ports 2.1.2 aggregation_of_nested_structs 2.1.3 aggregation_of_struct 2.1.4 auto_disaggregation_of_struct 2.1.5 disaggregation_of_axis_port …

类与对象(二)

类的六个默认构造函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&#xff1f;并不是&#xff0c;任何类在什么都不写时&#xff0c;编译器会自动生成以下6个默认成员函数。 默认成员函数&#xff1a;用户没有显式实现&#xff0c;编译器会生…

2.6设计模式——Flyweight 享元模式(结构型)

意图 运用共享技术有效地支持大量细粒度的对象。 结构 其中 Flyweight描述一个接口&#xff0c;通过这个接口Flyweight可以接受并作用于外部状态。ConcreteFlyweight实现Flyweight接口&#xff0c;并作为内部状态&#xff08;如果有&#xff09;增加存储空间。ConcreteFlywe…

6547网新增信息素养大赛真题及白名单考级真题

打扰大家了&#xff0c;汇报一下最近的更新动态&#xff0c;如果大家有急切需要的白名单真题及试卷留言&#xff0c;我们会优先更新&#xff01; 6547网文库&#xff08;www.6547.cn/wenku&#xff09;&#xff1a;新增信息素养大赛图形化编程真题及Python真题&#xff0c;2024…

STM32单片机C语言模块化编程实战:LED控制详解与示例

一、开发环境 硬件&#xff1a;正点原子探索者 V3 STM32F407 开发板 单片机&#xff1a;STM32F407ZGT6 Keil版本&#xff1a;5.32 STM32CubeMX版本&#xff1a;6.9.2 STM32Cube MCU Packges版本&#xff1a;STM32F4 V1.27.1 之前介绍了很多关于点灯的方法&#xff0c;比如…

不要小看使用说明书,它才是提高成交率的秘诀

在产品推广和销售环节中&#xff0c;许多企业可能忽略了一个非常重要但常被低估的环节——使用说明书的作用。使用说明书&#xff0c;这本附随每件产品的“小书”&#xff0c;往往是用户了解和使用产品的第一步。事实上&#xff0c;一个清晰、详尽、易懂的使用说明书能够显著提…

Blueprints - 鼠标光标判断相关节点

一些以前的学习笔记归档&#xff1b; 俯视角场景中要用鼠标光标判断是否点中物体&#xff0c;或依靠光标引发各种事件&#xff1b; 这些逻辑一般编写在Controller中&#xff0c;Controller类本身就带有相关判断节点&#xff1a; 其中Get Hit Result Under Cursor by Channel是…

OpenFeign微服务调用组件!!!

1.Feign是什么 GitHub - OpenFeign/feign: Feign makes writing java http clients easierFeign makes writing java http clients easier. Contribute to OpenFeign/feign development by creating an account on GitHub.https://github.com/OpenFeign/feignFeign是Netflix开…

第十讲 操作符详解

第十讲 操作符详解 1 操作符的分类 算术操作符&#xff1a; 、- 、* 、/ 、%移位操作符: << >>位操作符: & | ^赋值操作符: 、 、 - 、 * 、 / 、% 、<< 、>> 、& 、| 、^单⽬操作符&#xff1a; &#xff01;、、–、&、*、、-、~ 、…

JavaScript:将input标签中的内容打印到控制台

使用浏览器进行开发时&#xff0c;按F12可以查看网页信息。 目标&#xff1a;实现将input标签中的内容&#xff0c;打印到控制台&#xff08;console&#xff09; HTML页面的关键代码实现&#xff1a; 登录功能&#xff1a; HTML代码&#xff1a; <div class"form-…

个人博客系统的设计与实现

https://download.csdn.net/download/liuhaikang/89222885http://点击下载源码和论文 本 科 毕 业 设 计&#xff08;论文&#xff09; 题 目&#xff1a;个人博客系统的设计与实现 专题题目&#xff1a; 本 科 毕 业 设 计&#xff08;论文&#xff09;任 务 书 题 …

ABTest如何计算最小样本量-工具篇

如果是比例类指标&#xff0c;有一个可以快速计算最小样本量的工具&#xff1a; https://www.evanmiller.org/ab-testing/sample-size.html 计算样本量有4个要输入的参数&#xff1a;①一类错误概率&#xff0c;②二类错误概率 &#xff08;一般是取固定取值&#xff09;&…

设计模式-01 设计模式简介之分类

设计模式-01 设计模式简介之分类 1.分类概述 今天梳理下设计模式的分类学说。按照GoF书籍 《Design Patterns - Elements of Reusable Object-Oriented Software》&#xff08;中文译名&#xff1a;《设计模式 - 可复用的面向对象软件元素》&#xff09; 中所提到的&#xff0c…

牛客NC209 最短无序连续子数组【中等 数组,双指针 C++/Java/Go/PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/d17f4abd1d114617b51e951027be312e 思路 解题思路 1、方法1&#xff0c;排序对比&#xff1a;将数组按升序排序&#xff0c;然后与原数组对照&#xff0c;从哪里开始变化到哪里结束变化的数组就是答案。 2、 方…

初识 Express

目录 1. Express 简介 1.1. 什么是 Express 1.1.1. 概念 1.1.2. 通俗理解 1.1.3. Express 的本质 1.2. 进一步理解 Express 1.2.1. 问题引入1——不使用 Express 能否创建 Web 服务器&#xff1f; 1.2.2. 问题引入2——有了 http 内置模块&#xff0c;为什么还要用 Exp…

【算法刷题 | 贪心算法03】4.25(最大子数组和、买卖股票的最佳时机|| )

文章目录 4.最大子数组和4.1题目4.2解法一&#xff1a;暴力4.2.1暴力思路4.2.2代码实现 4.3解法二&#xff1a;贪心4.3.1贪心思路4.3.2代码实现 5.买卖股票的最佳时机||5.1题目5.2解法&#xff1a;贪心5.2.1贪心思路5.2.2代码实现 4.最大子数组和 4.1题目 给你一个整数数组 n…

【JavaScript】内置对象 ③ ( Math 内置对象 | Math 内置对象简介 | Math 内置对象的使用 )

文章目录 一、Math 内置对象1、Math 内置对象简介2、Math 内置对象的使用 二、代码示例1、代码示例 - Math 内置对象的使用2、代码示例 - 封装 Math 内置对象 一、Math 内置对象 1、Math 内置对象简介 JavaScript 中的 Math 内置对象 是一个 全局对象 , 该对象 提供了 常用的 数…

openEuler-22.03下载、安装

一、下载 下载地址&#xff1a;openEuler下载 | 欧拉系统ISO镜像 | openEuler社区官网 下载版本&#xff1a;openEuler-22.03-LTS-x86_64-dvd.iso 二、安装 配置完后开启虚拟机 设置完后&#xff0c;重启虚拟机 设置桥接模式的网络 cd /etc/sysconfig/network-scripts/ vi if…

Apple公司面试题之Apple-Orange

1. 引言 你幻想过在Apple公司工作吗&#xff1f; 如果心动过&#xff0c;那这个逻辑推理面试题就是给你准备的&#xff01;这是一道有趣的面试题&#xff0c;如下所示&#xff1a; 看到这里的同学&#xff0c;我建议你暂停文章&#xff0c;拿起笔和纸&#xff0c;试一试。准…

图像在神经网络中的预处理与后处理的原理和作用(最详细版本)

1. 问题引出及内容介绍 相信大家在学习与图像任务相关的神经网络时&#xff0c;经常会见到这样一个预处理方式。 self.to_tensor_norm transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]) 具体原理及作用稍后解释&…