模拟退火算法

【注意事项】

【实现算法】

【伪代码】

//目的:求系统的最小值
S(i):       系统在状态y时的评价函数值
i:      系统当前状态
i + 1:    系统的新状态
r:       控制降温的速率
T0:         系统的初始温度(高温状态)
T_min:      温度的下限
 
while (T0 > T_min)
{
    dE = S(i + 1) - S(i);
    if dE < 0
      //接收从S(i)到S(i+1)的移动
    else if (exp(-dE / T) > random(0,1))
      //接收从S(i)到S(i+1)的移动
    else
      //不接收从S(i)到S(i+1)的移动
    T0 = r * T0;                //降温退火(0 < r < 1 ; r越大, 降温越慢; r越小, 降温越快)
    i++;
}

【例题1】模拟退火算法解决TSP问题

【代码】

#程序文件Pex17_1.py
from numpy import loadtxt,radians,sin,cos,inf,exp
from numpy import array,r_,c_,arange,savetxt
from numpy.lib.scimath import arccos
from numpy.random import shuffle,randint,rand
from matplotlib.pyplot import plot, show, rc
a=loadtxt("D:\桌面的文件\Pdata17_1.txt")

#a[:,::2] 会选取数组 a 的所有行 (: 表示所有行),然后每隔一行取一个元素。
#a[:,1::2] 则是选取数组 a 的所有行,但是从第二个元素开始每隔一个元素取一个
x=a[:,::2].flatten(); 
y=a[:,1::2].flatten()
#创建一个虚拟点对 d1 表示路径的起点和终点
d1=array([[70,40]]); 
#c_[] 表示按列方向(即垂直方向)拼接。
xy=c_[x,y]
#r_[] 是按行方向(即水平方向)拼接
#形成一个完整的包含起止点的数据集 xy
xy=r_[d1,xy,d1];
#用来获取数组 xy 的行数
N=xy.shape[0]
lon = radians(xy[:, 0])  # 经度转弧度
lat = radians(xy[:, 1])  # 纬度转弧度
#通过.real属性获取复数的实部
d = array([[6370 * arccos(cos(lon[i] - lon[j]) * cos(lat[i]) * cos(lat[j]) +
                     sin(lat[i]) * sin(lat[j])) for i in range(N)]
           for j in range(N)]).real
savetxt('D:\桌面的文件\Pdata17_2.txt',c_[xy,d])  #把数据保存到文本文件
#生成了一个从0开始到N-1结束的整数序列,这个序列代表了遍历所有城市的顺序
path=arange(N)

#初始值设为无穷大,这个变量将用来存储当前找到的最短总路径长度。
L=inf
for j in range(1000):
    #新的数组 path0 包含从1到N-2的城市编号,并对它们进行随机打乱以尝试不同的排列顺序
    path0=arange(1,N-1); 
    shuffle(path0)
    #将0和N-1添加到打乱后的城市序列首尾,形成新的完整路径候选方案
    path0=r_[0,path0,N-1]; 
    #计算新路径的第一个边(从城市0到下一个城市)的距离作为累计距离 L0 的初始值
    L0=d[0,path0[1]]
    for i in range(1,N-1):
        L0+=d[path0[i],path0[i+1]]
    if L0<L: 
        path=path0; 
        L=L0

print(path,'\n',L)

#模拟退火
#这个值通常用作终止条件
e=0.1**30; 
#这是算法的最大迭代次数
M=20000; 
#这是降温系数(cooling rate)
at=0.999; 
#初始温度设置为1
T=1

#遍历最大迭代次数 M
for k in range(M):
    #用 randint(1, 101, 2) 随机选择两个城市编号 c1 和 c2,确保它们不为0和101(因为这是起点和终点)。
    c=randint(1,101,2); 
    c.sort()
    c1=c[0]; 
    c2=c[1]
    #计算改变路径顺序后的总距离变化量 df
    df=d[path[c1-1],path[c2]]+d[path[c1],path[c2+1]]-\
    d[path[c1-1],path[c1]]-d[path[c2],path[c2+1]]  #续行
    if df<0:
        path=r_[path[0],path[1:c1],path[c2:c1-1:-1],path[c2+1:102]]; 
        L=L+df
    else:
        if exp(-df/T)>=rand(1):
            path=r_[path[0
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值