智能算法系列之基于粒子群优化的模拟退火算法

这篇具有很好参考价值的文章主要介绍了智能算法系列之基于粒子群优化的模拟退火算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

  本篇是智能算法(Python复现)专栏的第四篇文章,主要介绍粒子群优化算法与模拟退火算法的结合,以弥补各自算法之间的不足。

  在上篇博客【智能算法系列之粒子群优化算法】中有介绍到混合粒子群优化算法,比如将粒子更新后所获得的新的粒子,采用模拟退火的思想决定是否接受进入下一代迭代。不过啊,本篇也算是混合粒子群优化算法吧,侧重点是将粒子群优化应用在模拟退火算法中,而不是在粒子群优化算法中应用模拟退火算法。

1. 算法结合思路

  在这篇博客【智能算法系列之模拟退火算法】中介绍到的模拟退火算法有可以优化的地方,比如在初始解得选择上,默认是随机选择一个解作为初始解,所以想法就来了:如果初始解是一个局部最优解,在此基础之上应用模拟退火算法,那结果肯定会比随机初始解效果好。
  如何选择这个初始解或者局部最优解呢,那又有很多算法了,前面介绍的遗传算法和粒子群优化算法都可以使用,本篇就使用粒子群优化来选择初始解。

  后续也会在本篇中更新使用遗传算法来选择初始解,不过不打算更新此算法的文章,详细的可以查阅 IALib 库代码。

  正如上述所说,本篇并没有在每一代中都应用模拟退火算法(这样的话就是混合粒子群了),而是这样:

智能算法系列之基于粒子群优化的模拟退火算法

2. 问题场景

  依然是最值问题,不过将原始的一元函数最值问题换成了二元函数最值问题[复杂度也没增加多少,主要是为了方便可视化]。本次求解三个经典函数的最值:

2.1 Sphere

f ( x , y ) = x 2 + y 2 f(x, y) = x^2 + y^2 f(x,y)=x2+y2

智能算法系列之基于粒子群优化的模拟退火算法

2.2 Himmelblau

f ( x , y ) = ( x 2 + y − 11 ) 2 + ( x + y 2 − 7 ) 2 f(x, y) = (x^2 + y - 11)^2 + (x + y^2 - 7)^2 f(x,y)=(x2+y11)2+(x+y27)2

智能算法系列之基于粒子群优化的模拟退火算法

2.3 Ackley

f ( x , y ) = − a ∗ e x p [ − b x 2 + y 2 2 ] − e x p [ c o s ( c x ) + c o s ( c y ) 2 ] + a + e f(x, y) = -a * exp\bigg[{ -b\sqrt{\frac {x^2 + y^2} {2}} }\bigg] -exp\bigg[ \frac {cos(cx) + cos(cy)} {2} \bigg] + a + e f(x,y)=aexp[b2x2+y2 ]exp[2cos(cx)+cos(cy)]+a+e  其中, a = 20 , b = 0.2 , c = 2 π , e = 2.71282 a=20, b=0.2, c=2\pi, e=2.71282 a=20,b=0.2,c=2π,e=2.71282.

智能算法系列之基于粒子群优化的模拟退火算法

2.4 函数可视化

# -*- coding:utf-8 -*-
# Author:   xiayouran
# Email:    youran.xia@foxmail.com
# Datetime: 2023/3/30 14:22
# Filename: visu_func.py
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D


class Visu3DFunc(object):
    def __init__(self, func_name='Sphere'):
        self.func_name = func_name
        self.X = np.linspace(-5, 5, num=200)
        self.Y = np.linspace(-5, 5, num=200)

    @classmethod
    def sphere(cls, x, y):
        """Sphere"""
        return x**2 + y**2

    @classmethod
    def himmelblau(cls, x, y):
        """Himmelblau"""
        return (x**2 + y - 11)**2 + (x + y**2 - 7)**2

    @classmethod
    def ackley(cls, x, y, a=20, b=0.2, c=2*np.pi):
        """Ackley"""
        term1 = -a * np.exp(-b * np.sqrt((x**2 + y**2)/2))
        term2 = -np.exp((np.cos(c*x) + np.cos(c*y))/2)
        return term1 + term2 + a + np.exp(1)

    def draw(self):
        fig = plt.figure()
        # ax = fig.gca(projection='3d')
        ax = Axes3D(fig)
        X, Y = np.meshgrid(self.X, self.Y)

        if self.func_name == 'Sphere':
            Z = self.sphere(X, Y)
        elif self.func_name == 'Himmelblau':
            Z = self.himmelblau(X, Y)
        else:
            Z = self.ackley(X, Y)

        ax.plot_surface(X, Y, Z, cmap=plt.cm.cool)
        ax.contour(X, Y, Z, levels=5, offset=0)
        ax.set_xlabel('X')
        ax.set_ylabel('Y')
        ax.set_zlabel('Z')
        ax.set_title('{} Function'.format(self.func_name))
        # ax.scatter3D(0, 0, self.sphere(0, 0), s=100, lw=0, c='green', alpha=0.7)
        plt.savefig(self.func_name)

        plt.show()


if __name__ == '__main__':
    # Sphere, Himmelblau, Ackley
    visu_obj = Visu3DFunc(func_name='Sphere')
    visu_obj.draw()

3. 算法实现

# -*- coding:utf-8 -*-
# Author:   xiayouran
# Email:    youran.xia@foxmail.com
# Datetime: 2023/3/30 15:50
# Filename: pso_saa.py
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

from IALib.base_algorithm import BaseAlgorithm
from IALib.particle_swarm_optimization import ParticleSwarmOptimization, Particle
from IALib.simulate_anneal_algorithm import SimulateAnnealAlgorithm
from IALib.mixup.visu_func import Visu3DFunc


__all__ = ['PSO_SAA']


class PSO_SAA(BaseAlgorithm):
    def __init__(self, population_size=100, p_dim=1, v_dim=1, max_iter=500, x_range=(0, 5),
                 t_max=1.0, t_min=1e-3, coldrate=0.9, seed=10086):
        super(PSO_SAA, self).__init__()
        self.__population_size = population_size  # 种群大小
        self.__p_dim = p_dim        # 粒子位置维度
        self.__v_dim = v_dim        # 粒子速度维度
        self.__max_iter = max_iter  # 最大迭代次数
        self.__t_max = t_max  # 初始温度
        self.__t_min = t_min  # 终止温度
        self.__coldrate = coldrate  # 降温速率
        self.saa_best_particle = None   # 模拟退火算法得到的最优解
        self.best_particle = None       # 最优解
        self.__x_range = x_range
        self.__seed = seed
        self.optimal_solution = None

        np.random.seed(self.__seed)

    def problem_function(self, x):
        if self.__p_dim == 1:
            return super().problem_function(x)
        else:
            return Visu3DFunc.sphere(*x)

    def solution(self):
        # PSO
        algo_pso = ParticleSwarmOptimization(population_size=self.__population_size,
                                             p_dim=self.__p_dim, v_dim=self.__v_dim,
                                             max_iter=self.__max_iter, x_range=self.__x_range)
        algo_pso.solution()

        # SAA
        x = algo_pso.global_best_particle.best_position   # 初始解
        while self.__t_max > self.__t_min:
            for _ in range(self.__max_iter):
                x_new = np.clip(x + np.random.randn(), a_min=self.__x_range[0], a_max=self.__x_range[1])
                delta = self.problem_function(x_new) - self.problem_function(x)  # 计算目标函数的值差
                if delta < 0:  # 局部最优解
                    x = x_new   # 直接接受更优解
                else:
                    p = np.exp(-delta / self.__t_max)  # 粒子在温度T时趋于平衡的概率为exp[-ΔE/(kT)]
                    r = np.random.uniform(0, 1)
                    if p > r:  # 以一定概率来接受最优解
                        x = x_new
            self.__t_max *= self.__coldrate

        # optimal solution
        saa_best_particle = Particle()
        saa_best_particle.position = x
        saa_best_particle.best_position = x
        saa_best_particle.fitness = self.problem_function(x)
        self.saa_best_particle = saa_best_particle

        if saa_best_particle.fitness < algo_pso.global_best_particle.fitness:
            self.best_particle = saa_best_particle
        else:
            self.best_particle = algo_pso.global_best_particle

        self.optimal_solution = (self.parse_format(self.best_particle.position),
                                 self.parse_format(self.best_particle.fitness))
        print('the optimal solution is', self.optimal_solution)
        # print('optimal solution:\nposition: {} \nfitness: {}'.format(self.best_particle.best_position,
        #                                                              self.best_particle.fitness))

    def draw(self):
        # PSO
        algo_pso = ParticleSwarmOptimization(population_size=self.__population_size,
                                             p_dim=self.__p_dim, v_dim=self.__v_dim,
                                             max_iter=self.__max_iter, x_range=self.__x_range)
        algo_pso.draw(mixup=True)
        plt.clf()
        x = np.linspace(*self.__x_range, 200)
        plt.plot(x, self.problem_function(x))

        # SAA
        x = algo_pso.global_best_particle.best_position   # 初始解
        while self.__t_max > self.__t_min:
            for _ in range(self.__max_iter):
                # something about plotting
                if 'sca' in globals() or 'sca' in locals():
                    sca.remove()
                sca = plt.scatter(x, self.problem_function(x), s=100, lw=0, c='red', alpha=0.5)
                plt.pause(0.01)

                x_new = np.clip(x + np.random.randn(), a_min=self.__x_range[0], a_max=self.__x_range[1])
                delta = self.problem_function(x_new) - self.problem_function(x)  # 计算目标函数的值差
                if delta < 0:  # 局部最优解
                    x = x_new   # 直接接受更优解
                else:
                    p = np.exp(-delta / self.__t_max)  # 粒子在温度T时趋于平衡的概率为exp[-ΔE/(kT)]
                    r = np.random.uniform(0, 1)
                    if p > r:  # 以一定概率来接受最优解
                        x = x_new
            self.__t_max *= self.__coldrate

        # optimal solution
        saa_best_particle = Particle()
        saa_best_particle.position = x
        saa_best_particle.best_position = x
        saa_best_particle.fitness = self.problem_function(x)
        self.saa_best_particle = saa_best_particle

        if saa_best_particle.fitness < algo_pso.global_best_particle.fitness:
            self.best_particle = saa_best_particle
        else:
            self.best_particle = algo_pso.global_best_particle

        plt.scatter(self.best_particle.best_position, self.best_particle.fitness, s=100, lw=0, c='green', alpha=0.7)
        plt.ioff()
        plt.show()

        self.optimal_solution = (self.parse_format(self.best_particle.position),
                                 self.parse_format(self.best_particle.fitness))
        print('the optimal solution is', self.optimal_solution)
        # print('optimal solution:\nposition: {} \nfitness: {}'.format(self.best_particle.best_position,
        #                                                              self.best_particle.fitness))

    def draw3D(self):
        # PSO
        algo_pso = ParticleSwarmOptimization(population_size=self.__population_size,
                                             p_dim=self.__p_dim, v_dim=self.__v_dim,
                                             max_iter=self.__max_iter, x_range=self.__x_range)
        algo_pso.draw3D(mixup=True)
        plt.clf()
        ax = Axes3D(algo_pso.fig)
        x_ = np.linspace(*self.__x_range, num=200)
        X, Y = np.meshgrid(x_, x_)
        Z = self.problem_function([X, Y])
        ax.plot_surface(X, Y, Z, cmap=plt.cm.cool)
        ax.contour(X, Y, Z, levels=5, offset=0)
        ax.set_xlabel('X')
        ax.set_ylabel('Y')
        ax.set_zlabel('Z')

        # SAA
        x = algo_pso.global_best_particle.best_position   # 初始解
        while self.__t_max > self.__t_min:
            for _ in range(self.__max_iter):
                # something about plotting
                if 'sca' in globals() or 'sca' in locals():
                    sca.remove()
                sca = ax.scatter3D(*x, self.problem_function(x), s=100, lw=0, c='red', alpha=0.5)
                plt.pause(0.01)

                x_new = np.clip(x + np.random.randn(), a_min=self.__x_range[0], a_max=self.__x_range[1])
                delta = self.problem_function(x_new) - self.problem_function(x)  # 计算目标函数的值差
                if delta < 0:  # 局部最优解
                    x = x_new   # 直接接受更优解
                else:
                    p = np.exp(-delta / self.__t_max)  # 粒子在温度T时趋于平衡的概率为exp[-ΔE/(kT)]
                    r = np.random.uniform(0, 1)
                    if p > r:  # 以一定概率来接受最优解
                        x = x_new
            self.__t_max *= self.__coldrate

        # optimal solution
        saa_best_particle = Particle()
        saa_best_particle.position = x
        saa_best_particle.best_position = x
        saa_best_particle.fitness = self.problem_function(x)
        self.saa_best_particle = saa_best_particle

        if saa_best_particle.fitness < algo_pso.global_best_particle.fitness:
            self.best_particle = saa_best_particle
        else:
            self.best_particle = algo_pso.global_best_particle

        ax.scatter3D(*self.best_particle.best_position, self.best_particle.fitness, s=100, lw=0, c='green', alpha=0.7)
        plt.ioff()
        plt.show()

        self.optimal_solution = (self.parse_format(self.best_particle.position),
                                 self.parse_format(self.best_particle.fitness))
        print('the optimal solution is', self.optimal_solution)
        # print('optimal solution:\nposition: {} \nfitness: {}'.format(self.best_particle.best_position,
        #                                                              self.best_particle.fitness))


if __name__ == '__main__':
    algo = PSO_SAA()
    # algo.draw()
    algo.draw3D()

代码仓库:IALib[GitHub]

  本篇代码已同步至【智能算法(Python复现)】专栏专属仓库:IALib
  运行IALib库中的PSO-SAA算法:文章来源地址https://www.toymoban.com/news/detail-505487.html

git clone git@github.com:xiayouran/IALib.git
cd examples
python main.py -algo pso_saa		# 2D visu
python main_pro.py -algo pso_saa	# 3D visu

到了这里,关于智能算法系列之基于粒子群优化的模拟退火算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【智能算法1】模拟退火算法_Python实现

    【智能算法1】模拟退火算法_Python实现

    1.1 固体退火的原理 加热使得固体融化,然后缓慢地降低温度,以此来让固体内部的粒子排布更加均匀。 分为四个阶段: 升温阶段、降温阶段、等温阶段、达到目标温度退火完成 等温阶段就是在塑造形状。 1.2 Metropolis准则 概率接受新状态,称为Metropolis准则。 假设前一状态

    2024年02月05日
    浏览(11)
  • Matlab|基于多目标粒子群算法的微电网优化调度(多约束多目标智能算法模板)

    Matlab|基于多目标粒子群算法的微电网优化调度(多约束多目标智能算法模板)

    目录 1 主要内容 2 部分代码 3 程序结果 4 下载链接 程序针对微电网优化模型进行优化求解,文件夹共包含四部分内容,分别是:原始多目标粒子群、改进多目标粒子群、改进多目标粒子群(勘误)和改进多目标粒子群(多约束模板),满足各位同学对于多目标粒子群算法各

    2024年03月13日
    浏览(12)
  • 模拟退火算法与遗传算法求解多目标优化问题的算法实现(数学建模)

    模拟退火算法与遗传算法求解多目标优化问题的算法实现(数学建模)

    模拟退火算法是一种全局优化算法,解决的问题通常是找到一个最小化(或最大化)某个函数的全局最优解。它通过模拟物理退火的过程来搜索解空间,在开始时以一定的温度随机生成初始解,然后一步步降低温度,同时在当前解的周围随机搜索新的解,并根据一定概率接受

    2024年02月02日
    浏览(10)
  • 【人工智能】—局部搜索算法、爬山法、模拟退火、局部剪枝、遗传算法

    【人工智能】—局部搜索算法、爬山法、模拟退火、局部剪枝、遗传算法

    在某些规模太大的问题状态空间内,A*往往不够用 问题空间太大了 无法访问 f 小于最优的所有状态 通常,甚至无法储存整个边缘队列 解决方案 设计选择更好的启发式函数 Greedy hill-climbing (fringe size = 1) Beam search (limited fringe size) 瓶颈:内存不足,无法存储整个边缘队列 爬山搜

    2023年04月22日
    浏览(11)
  • 25.6 matlab里面的10中优化方法介绍——模拟退火算法(matlab程序)

    25.6 matlab里面的10中优化方法介绍——模拟退火算法(matlab程序)

    1. 简述        相信没有相关物理知识背景的小伙伴看到“退火”二字是一脸懵逼的...固体的退火过程指的是将固体加热至足够高的温度,再使其慢慢冷却的过程。在加热过程中,原本有序排列的内部粒子开始无序运动,此时固体的内能不断增大;而在降温过程中,粒子的排

    2024年02月15日
    浏览(13)
  • 模拟退火-粒子群全局路径规划+DWA局部路径规划

    模拟退火-粒子群全局路径规划+DWA局部路径规划

    整理了一个路径规划demo,当然图是改进的效果 demo分别有对应的开源 可以在网上搜到,我觉得已经介绍的很详细了,所以不做过多的解释,传送门在下面 ( 写的不好 轻喷 ) 粒子群本质是参数寻优问题,也就是说在运用到路径规划这块需要对规划的路径进行模型建立,这块

    2024年02月06日
    浏览(11)
  • Baltamatica 北太天元 —— 基于模拟退火算法的旅行商问题

    Baltamatica 北太天元 —— 基于模拟退火算法的旅行商问题

    北太天元(Baltam)是一款对标矩阵实验室(Matlab)的国产通用科学计算软件,目前版本还在持续更新迭代中,并在国内不断提升知名度,营造良好的生态社区氛围。在很多外行、内行人都不看好Matlab国产化,甚至面对工业软件国产化的项目“谈虎色变”的形势下,北太天元横

    2024年02月11日
    浏览(20)
  • 智能优化算法:多目标粒子群优化算法(MOPSO)

    智能优化算法:多目标粒子群优化算法(MOPSO)

    目录 一、粒子群优化算法(Particle Swarm Optimization,PSO) 二、多目标优化Pareto支配 三、多目标粒子群优化算法(Multiple Objective Particle Swarm Optimization,MOPSO) 四、参考文献: 粒子群算法(PSO)[1]是一种群智能优化算法,于1995年Kennedy和Eberhart提出,其灵感来源于鸟群的协作觅食行

    2023年04月19日
    浏览(14)
  • 97基于matlab的改进的带记忆的模拟退火算法求解TSP问题

    97基于matlab的改进的带记忆的模拟退火算法求解TSP问题

    基于matlab的改进的带记忆的模拟退火算法求解TSP问题,采用多普勒型降温曲线描述迭代过程,在传统算法的基础上增加记忆功能,可测试中国31/64/144以及att48城市的数据,也可自行输入数据进行测试,测试结果基本达到当前最优水平。duoci.m为主文件。数据可更换自己的,程序

    2024年02月05日
    浏览(11)
  • MATLAB智能优化算法 - 粒子群算法及MATLAB实例仿真

    MATLAB智能优化算法 - 粒子群算法及MATLAB实例仿真

    粒子群算法来源于鸟类集体活动的规律性,进而利用群体智能建立简化模型。它模拟的是鸟类的觅食行为,将求解问题的空间比作鸟类飞行的时间,每只鸟抽象成没有体积和质量的粒子,来表征一个问题的可行解。 粒子群算法首先在给定的解空间中随机初始化粒子群,待优化

    2023年04月17日
    浏览(62)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包