模拟退火算法(python)

 是修改了一位博主的代码,不保证完全正确,这位博主博客链接:模拟退火算法详细讲解(含实例python代码)_模拟退火算法实例分析_Eterbity的博客-CSDN博客

import math
import random
import matplotlib.pyplot as plt

class SA:
    def __init__(self,  iter=100, T0=100, Tf=0.01, alpha=0.99):
        self.iter = iter  # 内循环迭代次数,即为L =100
        self.alpha = alpha  # 降温系数,alpha=0.99
        self.T0 = T0  # 初始温度T0为100
        self.Tf = Tf  # 温度终值Tf为0.01
        self.T = T0  # 当前温度
        self.x = [random.uniform(-5,5) for i in range(iter)]  # 随机生成100个x的值
        self.y = [random.uniform(-5,5) for  i in range(iter)]  # 随机生成100个y的值
        self.most_best = []
        self.history = {"v":[],'f': [], 'T': []}
        self.count=0#外层循环次数

    def func(self,x, y):  # 函数优化问题
        res = 4 * x ** 2 - 2.1 * x ** 4 + x ** 6 / 3 + x * y - 4 * y ** 2 + 4 * y ** 4
        return res

    def generate_new(self, x, y):  # 扰动产生新解的过程。
        while True:
            x_new = x + self.T * (random.random() - random.random())
            y_new = y + self.T * (random.random() - random.random())
            if (-5 <= x_new <= 5) & (-5 <= y_new <= 5):
                break  # 重复得到新解,直到产生的新解满足约束条件
        return x_new, y_new

    def Metrospolis(self, f, f_new):  # Metropolis准则
        if f_new <= f:
            return 1
        else:
            p = math.exp((f - f_new) / self.T)#  self.T当前温度
            if random.random() < p:
                return 1
            else:
                return 0

    def best(self):  # 获取最优目标函数值
        f_list = []  # 100
        var=[]
        for i in range(self.iter):
            f = self.func(self.x[i], self.y[i])
            f_list.append(f)
        f_best = min(f_list)
        idx = f_list.index(f_best)#最优解的索引
        var.append(self.x[idx])#最优解
        var.append(self.y[idx])
        return f_best, var
    def run(self):
        # 外循环迭代,当前温度小于终止温度的阈值
        while self.T > self.Tf:
            # 内循环对100个解进行
            for i in range(self.iter):
                f = self.func(self.x[i], self.y[i])  # 原始值
                x_new, y_new = self.generate_new(self.x[i], self.y[i])  # 产生新解
                f_new = self.func(x_new, y_new)  # 新值
                if self.Metrospolis(f, f_new):  # 判断是否接受新值
                    self.x[i] = x_new  # 如果接受新值,则把新值的x,y存入x数组和y数组(替换)
                    self.y[i] = y_new
            # 迭代L次记录在该温度下最优解
            ft, var = self.best()
            self.history["v"].append(var)
            self.history['f'].append(ft)#917
            self.history['T'].append(self.T)
            # 温度按照一定的比例下降(冷却)
            self.T = self.T * self.alpha
            self.count += 1
            # 得到最优解
            # todo 最优的一代,一定在最后一代吗 经过如下两个解的对比,不是一定在最后一代
        f_best, var = self.best()
        print(f"在最后一代找最优解 F={f_best}, x={var[0]}, y={var[1]}")

        f_best1=min(self.history["f"])
        temp=self.history["f"].index(f_best1)
        var_best1=self.history["v"][temp]
        print(f"在每一代(每个温度下)的最优值中找最优解 F={f_best1},x={var_best1[0]},y={var_best1[1]},该最优解首次出现在第{temp+1}代中")

sa = SA()#传入的一个函数
sa.run()


plt.plot([i for i in range(sa.count)], sa.history['f'])
plt.title('SA')
plt.xlabel('T')
plt.ylabel('f')
# plt.gca().invert_xaxis()#将绘图的 x 轴反转
plt.show()


 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值