引力搜索算法

2023-10-27

最近在论文中看到有学者用改进的引力搜索算法解优化问题,有一个较好的效果,于是去了解了一下这个算法。

引力搜索算法(Gravitational Search Algorithm,GSA)是Esmat Rashedi等人在2009年提出的一种随机性启发式搜索算法,这种算法的灵感来自于牛顿的万有引力定律与运动定律:1.任意两个质点有通过连心线方向上的力相互吸引,该引力大小与它们质量的乘积成正比与它们距离的平方成反比。2.力使物体获得加速度。

在GSA中,质点被抽象成解空间的一个解,解之间存在一个相互吸引力,这个吸引力由解的质量与两个解之间的距离确定,质点的质量被抽象成解的评估函数值。在解空间中,每个解由其他解对其的吸引力获得加速度,质量更大(评估函数值更优)所提供的加速度更大,从而使解向更优解的方向移动。

看到这里,有些小伙伴会以为GSA是个与PSO差不多的算法,是的,GSA与PSO的外层框架是一致的,但是,它们最关键的粒子移动策略却是不同的:

1.在PSO中,粒子的移动只使用两个最佳位置pbest和gbest。但是在GSA中,智能体的方向是根据所有其他智能体或部分较优的智能体获得的总力来计算的。
2.PSO使用一种内存来更新速度(由于pbest和gbest)。然而,GSA是无内存的,只有智能体的当前位置在更新过程中起作用。
3.在PSO中,更新不考虑解之间的距离,而在GSA中,力与解之间的距离成反比。
4.PSO模拟了鸟类的社会行为,而GSA的灵感来自于物理现象。

GSA的主要过程如下:

1. 确定搜索空间。
2. 随机初始化个体种群。
3. 对种群进行适应度评价。
4. 更新引力常量G,更新种群中最好的个体 best与最差的个体worst,更新个体的质量。
5. 计算每个个体在不同方向上的总引力。
6. 计算个体的加速度,基于此更新个体的速度。
7. 根据速度更新个体在解空间中的位置。
8. 重复步骤3-7直到达到停止标准。

算法流程:
在这里插入图片描述

具体的个体属性更新公式与引力计算公式建议参考 GSA: A Gravitational Search Algorithm这篇文章。

例: min z = x1 ** 2 + x2 ** 2
s.t. -10 <= x1 <= 10 , -10 <= x2 <= 10

# Gravitational Search Algorithm
import numpy as np
import random as rd
from math import exp, sqrt

'''min z = X1 ** 2 + X2 ** 2
   s.t.   -10 <= x1 <= 10
          -10 <= X2 <= 10   '''

def init(n):
    position, velocity = [], []
    for i in range(n):
        X1 = rd.uniform(-10, 10)
        X2 = rd.uniform(-10, 10)
        V1 = rd.uniform(-3, 3)
        V2 = rd.uniform(-3, 3)
        position.append([X1, X2])
        velocity.append([V1, V2])
    return position, velocity

def objFuntion(x1, x2):
    return x1 ** 2 + x2 ** 2

def fitnessEva(position):
    fitness = []
    for i in range(len(position)):
        fitness.append(objFuntion(position[i][0], position[i][1]))
    return fitness

def findBestAndWorst(position):
    return min(fitnessEva(position)), max(fitnessEva(position))

def calculateMass(fitness):
    mass = []
    Mass = []
    for i in range(len(fitness)):
        mass.append((fitness[i] - max(fitness)) / (min(fitness) - max(fitness)))
    for i in range(len(mass)):
        Mass.append(mass[i] / sum(mass))
    return Mass

def calculateAcceleration(position, Mass, G, topK):
    acceleration = []
    Fi0, Fi1 = 0, 0

    for i in range(len(position)):
        for j in range(len(position)):
            if i != j and j in topK:
                Fi0 += rd.random() * G * ((Mass[i] * Mass[j]) / (calculateDistance(position[i], position[j]) + r)) * (
                            position[j][0] - position[i][0])
                Fi1 += rd.random() * G * ((Mass[i] * Mass[j]) / (calculateDistance(position[i], position[j]) + r)) * (
                            position[j][1] - position[i][1])
        if Mass[i] != 0:
            acceleration.append([Fi0 / Mass[i] / 10, Fi1 / Mass[i] / 10])   #这里除10是为了避免粒子的加速度过大
        else:
            acceleration.append([10, 10])
        Fi0 = 0
        Fi1 = 0
    return acceleration

def findTopK(fitness, K):
    topK = []
    dic = {}
    for i in range(len(fitness)):
        dic[i] = fitness[i]
    fitness.sort()
    for i in range(K):
        topK.append(list(dic.keys())[list(dic.values()).index(fitness[i])])
    return topK


def updateVelocityAndPosition(acceleration, position, velocity):
    for i in range(len(velocity)):
        velocity[i][0] = rd.random() * velocity[i][0] + acceleration[i][0]
        velocity[i][1] = rd.random() * velocity[i][1] + acceleration[i][1]

        position[i][0] = position[i][0] + velocity[i][0]
        position[i][1] = position[i][1] + velocity[i][1]

def calculateDistance(p1,p2):
    return sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2)

def checkPosition(position):
    for i in range(len(position)):
        if position[i][0] < -10:
            position[i][0] = -10
        elif position[i][0] > 10:
            position[i][0] = 10
        if position[i][1] < -10:
            position[i][1] = -10
        elif position[i][1] > 10:
            position[i][1] = 10

if __name__ == '__main__':
    G = 100
    r = 1
    K = 50

    iterx, maxIterx = 0, 50
    position, velocity = init(50)
    while iterx < maxIterx:
        fitness = fitnessEva(position)               #适应性评估
        G = G * exp(-20 * iterx / maxIterx)          #更新引力常量
        Mass = calculateMass(fitness)                #更新粒子质量
        topK = findTopK(fitness, K)                  #找出适应度更优的前K个粒子
        acceleration = calculateAcceleration(position, Mass, G, topK)          #计算粒子加速度
        updateVelocityAndPosition(acceleration, position, velocity)            #根据加速度更新速度与位置
        checkPosition(position)                                                #检查粒子是否冲出了解空间
        iterx += 1
        K = K - iterx                                #更新K值
    print(min(fitnessEva(position)))
    print(position[fitnessEva(position).index(min(fitnessEva(position)))])

参考文献:
Rashedi E, Nezamabadi-pour H, Saryazdi S. GSA:a gravitational search algorithm[J].Information Science, 2009, 179 (13) :2232-2248.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

引力搜索算法 的相关文章

随机推荐

  • vue项目引入antDesignUI组件

    快速安装ant design vue并配置 vue2 0 antDesign 1 7 8 第一步 安装ant deisgn vue 1 7 8 npm install ant design vue 1 7 8 save 第二步 配置pack
  • Centos7下载和安装教程

    1 CentOS下载 CentOS是免费版 推荐在官网上直接下载 网址 https www centos org download DVD ISO 普通光盘完整安装版镜像 可离线安装到计算机硬盘上 包含大量的常用软件 一般选择这种镜像类型即
  • 如何用openweather显示html,如何显示openweathermap天气图标

    我正在使用openweathermap显示天气预报 一切正常 但图标有问题 json响应代码是 Array city gt Array id gt 1271476 name gt Guwahati coord gt Array lon gt
  • makefile中wildcard的理解

    wildcard 用来明确表示通配符 因为在 Makefile 里 变量实质上就是 C C 中的宏 也就是说 如果一个表达式如 objs o 则 objs 的值就是 o 而不是表示所有的 o 文件 若果要使用通配符 那么就要使用 wildc
  • PCB制板流程及工艺

    PCB制板的流程一般包括以下几个步骤 1 设计电路原理图和PCB布局 首先 需要设计电路原理图和PCB布局图 电路原理图是电路的逻辑图 用于指导电路的设计和调试 PCB布局图是电路板上各个元件的布局图 包括焊盘 引脚 电源 地线等 电路原理
  • 华中科技大学操作系统实验课 实验二

    一 实验目的 1 理解进程 线程的概念和应用编程过程 2 理解进程 线程的同步机制和应用编程 二 实验内容 1 在Linux下创建一对父子进程 2 在Linux下创建2个线程A和B 循环输出数据或字符串 3 在Windows下创建线程A和B
  • MySQL 回表 & 索引覆盖

    索引类型 聚簇索引 叶子节点存储的是行记录 每个表必须要有至少一个聚簇索引 使用聚簇索引查询会很快 因为可以直接定位到行记录 普通索引 二级索引 除聚簇索引外的索引 即非聚簇索引 普通索引叶子节点存储的是主键 聚簇索引 的值 聚簇索引递推规
  • 【嵌入式学习-C语言篇】 if & switch 的使用

    嵌入式学习 C语言篇 if switch 的使用 if switch 的常用场景 智能音箱 网络状态判断 智能家居 传感器开关灯 基本代码 我们拿网络状态判断来举例 下面代码展示了使用if 和 switch的使用 include
  • 背包问题(资料搜集)

    https comzyh com upload PDF Pack PDF Comzyh pdf 上面的背包问题讲解来自这位大佬 大佬
  • VS Code中统计有效代码行数(除去注释行,空格)

    之前用正则表达式在VSCode中直接查询代码行数 不过这种太麻烦了需要先设置好 要包含的文件 和 要排除的文件 而且还不能排除注释行和空格 所有给大家安利VS Code的一款很好用的插件 1 首先在VS Code中搜索VS Code cou
  • 刷脸支付比以前的支付技术确实安全不少

    支付宝正式推出刷脸支付功能 在我们腾不出手来或是忘记各种各样的密码可以选择往付款摄像头一站随后输入号码就支付完成 整个过程不足十秒钟 随着科学技术的不断完善 刷脸也会变得更加安全 不过就目前的安全来看 日常使用刷脸支付没有任何问题 刷脸支付
  • 华为HCIA-Datacom学习笔记

    系列文章目录 第一章 网络的定义和网络的历史 文章目录 系列文章目录 第一章 网络的定义和网络的历史 前言 一 网络的定义 1 网络范围 二 网络的历史沿革 1 图灵机 2 第一台计算机 3 阿帕网 4 传输协议 5 厂商 6 代理商 7
  • 函数使用注意事项

    1 自定义函数 lt 1 gt 无参数 无返回值 def 函数名 语句 lt 2 gt 无参数 有返回值 def 函数名 语句 return 需要返回的数值 注意 一个函数到底有没有返回值 就看有没有return 因为只有return才可以
  • 服务器修改字体,Win10 1909默认字体怎么修改?Win10 1909默认字体修改教程

    在使用Win10 1909设备的时候 偶尔需要创建一个全新的网络连接来进行文件的共享 但许多Win10 1909用户其实并不清楚 该怎么新建网络连接 针对这一情况 小编今天为大家带来了Win10 1909网络连接新建方法简述 方法步骤 打开
  • 基于组件化+模块化+Kotlin+协程+Flow+Retrofit+Jetpack+MVVM架构实现WanAndroid客户端

    前言 之前一直想写个 WanAndroid 项目来巩固自己对 Kotlin Jetpack 协程 等知识的学习 但是一直没有时间 这里重新行动起来 从项目搭建到完成前前后后用了两个月时间 平常时间比较少 基本上都是只能利用零碎的时间来写 但
  • 虚拟数字人详解|有个性、有情感的对话技术探索

    文 蔡华 华院计算 元宇宙是当前流行的的技术和商业热点 而其背后的核心技术是数字人 近日 华院计算算法研究员蔡华博士就虚拟数字人 有个性 有情感的对话技术 的话题进行了讲解 以下内容为蔡华博士的演讲内容节选 虚拟数字人的三重 境界 关于虚拟
  • STM32编译生成的BIN文件详解

    背景 在做stm32的IAP功能 大概思路参见我的另一篇文章 跟别人讨论了关于app中发生中断之后流程的问题 然后看了一下BIN文件格式 主要是因为BIN文件就是镜像 不包含任何其他信息 如下载的地址等 就是对ROM的绝对描述 可以很清楚看
  • 安卓端自行实现工信部要求的隐私合规检测一(教你手写Xposed模块代码)

    前言 友情提示 文章较长 源码及相关使用教程都在文尾 之所以写这篇文章 是因为不久前 我们公司上架的app被打回来了 信通院那边出了个报告 里面说我们app未经授权就自动获取了手机的mac地址 当时其实是有点懵逼的 因为合规措施其实是已经做
  • 七十九.找出唯一成对的数(位运算)

    1 N 这N个数放在含有N 1个元素的数组中 只有唯一的一个元素值重复 其它均只出现一次 每个数组元素只能访问一次 设计一个算法将它找出来 不用辅助存储空间 能否设计一个算法实现 import java util Random public
  • 引力搜索算法

    最近在论文中看到有学者用改进的引力搜索算法解优化问题 有一个较好的效果 于是去了解了一下这个算法 引力搜索算法 Gravitational Search Algorithm GSA 是Esmat Rashedi等人在2009年提出的一种随机