2020A炉温曲线第三题模拟退火算法(附python代码)

在问题二的条件下求出面积的最小值

from matplotlib import pyplot as plt
import numpy as np
import random
import math
from 第二题 import k,T
def test(v,T1,T2,T3,T4):
    t_list=np.linspace(0,400,801).tolist()
    u_list=[25]
    for i in t_list:
        kk=k(i,v)*(T(i,v,T1,T2,T3,T4)-u_list[-1])
        if abs(kk)>3:
            return False
        u_list.append(u_list[-1]+kk*0.5)
    u_list.pop()
    if len([i for i in u_list if i>=150 and i<=190])<60/0.5 or len([i for i in u_list if i>=150 and i<=190])>120/0.5:
        return False
    if len([i for i in u_list if i>=217])<40/0.5 or len([i for i in u_list if i>=270])>90/0.5:
        return False
    max=np.array(u_list).max()
    if max>250 or max<240:
        return False
    return True

#[start,end]为定义域
def initialization(start, end):
    return random.uniform(start, end)
def initialication_tuple(start_list,end_list):#在定义域内构建初值
    while True:
        v=initialization(start_list[0],end_list[0])
        T1=initialization(start_list[1],end_list[1])
        T2=initialization(start_list[2],end_list[2])
        T3=initialization(start_list[3],end_list[3])
        T4=initialization(start_list[4],end_list[4])
        if test(v,T1,T2,T3,T4):
            return v,T1,T2,T3,T4
def in_range(x, start, end):
    return True if start <= x <= end else False
def generate_new(x, start, end):
    while True:
        #采用高斯分布生成新解
        upper_bound = end - x
        lower_bound = start - x
        sigma = max(upper_bound, lower_bound) / 3
        new_x = random.gauss(x, sigma)
        #判断是否在定义域内,在则返回;否则重复生成
        if in_range(new_x, start, end):
            return new_x
def geerate_new_tuple(x_list,start_list,end_list):
    while True:#若不满足条件则重复生成,直至满足条件为止
        new_vt1t2t3t4=[generate_new(x,start,end)for x,start,end in zip(x_list,start_list,end_list)]
        if test(new_vt1t2t3t4[0],new_vt1t2t3t4[1],new_vt1t2t3t4[2],new_vt1t2t3t4[3],new_vt1t2t3t4[4]):
            return new_vt1t2t3t4

def f(v,T1,T2,T3,T4):
    t_list=np.linspace(0,400,801).tolist()
    u_list=[25]
    for i in t_list:
        kk=k(i,v)*(T(i,v,T1,T2,T3,T4)-u_list[-1])
        u_list.append(u_list[-1]+kk*0.5)
    u_list.pop()
    list_217=[i for i in u_list if i>217]
    max_position=np.array(list_217).argmax()
    list_217=list_217[:max_position]
    return np.array(list_217).sum()-217*len(list_217)

def search(all_vt1t2t3t4,all_fx):
    return all_vt1t2t3t4[np.array(all_fx).argmin()]

def metropolis(fx,new_fx,t):
    if new_fx<=fx:
        return True
    else:
        p=math.exp((fx-new_fx)/t)
        return True if random.random()<p else False

def tuihuo(t0, t_final, alpha, inner_iter,start_list,end_list):
    #t0为初始温度,t_final为终止温度,alpha为冷却系数,inner_iter为内层迭代次数,[start,end]为定义域
    all_vt1t2t3t4=[]
    all_fx=[]
    v,T1,T2,T3,T4=initialication_tuple(start_list,end_list)
    all_vt1t2t3t4.append((v,T1,T2,T3,T4))
    all_fx.append(f(v,T1,T2,T3,T4))
    t=t0
    while t>t_final:
        v,T1,T2,T3,T4=search(all_vt1t2t3t4,all_fx)
        fx=f(v,T1,T2,T3,T4)
        for i in range(inner_iter):
            new_vt1t2t3t4=geerate_new_tuple([v,T1,T2,T3,T4],start_list,end_list)
            new_fx=f(new_vt1t2t3t4[0],new_vt1t2t3t4[1],new_vt1t2t3t4[2],new_vt1t2t3t4[3],new_vt1t2t3t4[4])
            if metropolis(fx,new_fx,t):
                v,T1,T2,T3,T4=tuple(new_vt1t2t3t4)
                fx=new_fx
        all_vt1t2t3t4.append((v,T1,T2,T3,T4))
        all_fx.append(f(v,T1,T2,T3,T4))
        t=alpha*t
        print(fx*0.5)
    return search(all_vt1t2t3t4,all_fx),all_fx
            
def f_show(v,T1,T2,T3,T4):
    t_list=np.linspace(0,400,801).tolist()
    u_list=[25]
    for i in t_list:
        kk=k(i,v)*(T(i,v,T1,T2,T3,T4)-u_list[-1])
        u_list.append(u_list[-1]+kk*0.5)
    u_list.pop()
    list_217=[i for i in u_list if i>217]
    max_position=np.array(list_217).argmax()
    list_217=list_217[:max_position]
    plt.plot(t_list,u_list)
    plt.axhline(y=217,ls='--',color='g')
    plt.plot([i[0] for i in zip(t_list,u_list) if i[1]>217][:max_position],list_217)
    plt.show()

if __name__=='__main__':
    all=tuihuo(3000,10,0.95,20,[65,165,185,225,245],[100,185,205,245,265])
    print(all[0])
    print(f(all[0][0],all[0][1],all[0][2],all[0][3],all[0][4])/2)
    f_show(all[0][0],all[0][1],all[0][2],all[0][3],all[0][4])
    plt.plot(all[1])
    plt.show()

最小面积 436.88723462346024

温区

1-5

6

7

8-9

温度

184.99999999300636

204.99999746941685

232.35526429807527

264.99884587932297

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值