【注意事项】

【实现算法】

【伪代码】
//目的:求系统的最小值
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

最低0.47元/天 解锁文章
2万+





