SA/VFSA||史上最正确最体贴最免费的模拟退火算法Python

当你找遍本站及外站资源依旧无法成功复现SA时,看完这篇文章就OK了,废话不多说,想必你找到这篇文章时,你已经了解了什么是SA了,直接上代码!!!

import numpy as np
import time
from matplotlib import pyplot as plt
import copy
from scipy import special as sp


def D_los_fitness(X):
    # fitness = np.sum(np.power(np.abs(X + 0.5), 2))
    # fitness = np.sum(X**2)
    fitness = np.sum(X**2-10*np.cos(2*np.pi*X)+10)
    return fitness


def sa(dims, lbs, ubs):
    t1 = time.time()
    # 设置参数
    pop, iters, dim, lb, ub = 1, 500, dims, lbs, ubs
    T_0, T_end, alpha = 100, 1e-8, 0.8  # 分别为初始温度、终止温度、降温系数
    inner_iter = 100  # 内部循环
    # 开始执行算法
    X_old = lb + (ub - lb) * np.random.rand(dim)  # 初始化
    fitness_old = D_los_fitness(X_old)  # 计算当前适应度
    best_position = copy.copy(X_old)  # 记录最优解位置
    best_fitness = copy.copy(fitness_old)  # 记录最优适应度

    # Curve = np.zeros(iters)
    Curve = []
    """算法开始咯"""
    # 外部循环,主要是用来降温
    for k in range(iters):
        print(k)
        # 内部循环,恒温下寻找当前温度下的最好的解
        for p in range(inner_iter):
            X_new = X_old + (ub - lb) * (
                T_0 * np.sign(np.random.rand(dim) - 0.5) * (
                    np.power(1 + 1 / T_0, np.abs(2 * np.random.rand(dim) - 1)) - 1)
            )
            X_new = np.clip(X_new, lb, ub)  # 边界检测
            # 计算位置更新后的适应度
            fitness_new = D_los_fitness(X_new)
            # 使用那什么概率接受解
            if fitness_new - fitness_old < 0:
                X_old = X_new
                fitness_old = fitness_new
            else:
                # if np.random.rand() < np.power(1-(1-0.2)*(fitness_new - fitness_old)/T_0, 1/(1-0.2)):
                if np.random.rand() < np.exp(-1 * (fitness_new - fitness_old) / T_0):
                    X_old = X_new
                    fitness_old = fitness_new
            # 更新全局最优解位置
            if fitness_old < best_fitness:
                best_position = X_old
                best_fitness = fitness_old
        
        # 降温,快速降温
        T_0 = T_0 * np.power(alpha, np.power(k+1, 1 / dim))
        Curve.append(best_fitness)

    # 结果输出与绘图
    t2 = time.time()
    print("耗时:", t2 - t1)
    print('最优适应度值:', Curve[-1])
    print('最优解[x1,x2]:', best_position)
    print('Curve:', len(Curve))

    # 绘制适应度曲线
    plt.figure(1)
    plt.plot(Curve, 'r--', linewidth=1)
    plt.xlabel('Iteration', fontsize='medium')
    plt.ylabel("Fitness", fontsize='medium')
    plt.grid()
    plt.title('SSA', fontsize='large')
    plt.show()

    return Curve


dim_external = 8
lb_external = np.full(dim_external, -5.12)
ub_external = np.full(dim_external, 5.12)
sa(dim_external, lb_external, ub_external)

上述代码直接复制粘贴即可使用,注意以下事项:

1、记得安装numpy、matplotlib库(scipy库可以不用安装)。

2、切换其他函数测试时,只需要修改dim_external、lb_external、ub_external里面的数值以及D_los_fitness函数体内部的函数实现即可。文章代码中给出了三个测试函数,分别是step函数、sphere函数以及rastrigin函数,它们的最优适应度都是0,解空间分别为[-100,100]、[-5.12,-5.12]、[-5.12,-5.12],维度都是30。

3、当结果不正确时(几乎不会发生),可以尝试修改sa函数内部的参数,不过谨慎修改!

4、最重要的一点,写代码累死人,免费分享,还请各位看官老爷点赞收藏加关注!!!!

写在最后,如果您要保存图片,可以在plt.show()之前添加这行代码,记得修改文件路径哦! 

plt.savefig('D:\\VFSA.png')

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值