传送门(所有的实验都使用python实现)
实验1 BP神经网络实验
实验2 som网实验
实验3 hopfield实现八皇后问题
实验4 模糊搜索算法预测薄冰厚度
实验5 遗传算法求解tsp问题
实验6 蚁群算法求解tsp问题
实验7 粒子群优化算法求解tsp问题
实验8 分布估计算法求解背包问题
实验9 模拟退火算法求解背包问题
实验10 禁忌搜索算法求解tsp问题
一、实验目的
理解并使用模拟退火算法
二、实验内容
实现基于模拟退火算法的背包问题求解
三、实验环境
使用Python3.0 在 eclipse进行编辑
四、实验步骤
1、输入介绍:
参数设定 : time 迭代次数, balance 平衡次数 best记录全局最优 T 温度 af退火率
2、产生个体:
随机产生一个合法的初始解
3、产生新解:
随机选取物品, 若 i 不在背包中, 则将其直接放入背包中, 或同时从背包中随机取出另一物品 j ; 若 i已在背包中, 则将其取出, 并同时随机装入另一物品j .
4、计算背包价值与合法性。
计算物品价值总和,并判断是否超重。
5、接受新解:
(1)超重,放弃此解
(2)比当前解背包价值更优,直接接受新解
(3)比当前解背包价值更劣,概率接受新解,概率 p=exp(-dlt/T)其中dlt为背包价值差。
6、更新全局最优解。
7、若达到平衡次数,则下降温度,重置平衡次数。否则继续产生新解。
8、终止条件
背包价值达到最优解或者温度下降到x度以下。
运行截图:
初始温度200 退火率0.95 平衡次数5 找到最优解所需次数36
初始温度200 退火率0.8 平衡次数5 找到最优解所需次数22
初始温度200 退火率0.95 平衡次数10 找到最优解所需次数7
初始温度200 退火率0.95 平衡次数100 找到最优解所需次数1
五、总结
退火率的设置对于算法效率影响十分明显,温度下降过快虽然较早达到稳定,但是有时找不到最优解,温度下降过慢会导致耗时增多,经过多次实验得出,退火率选择0.8为最佳。
平衡次数设置越多,所需迭代次数越少,但是单次迭代时间变长,所以平衡次数设置10次为最佳。
初始温度设置将会影响解的搜索范围,温度越高最终解的质量越优,但是耗时也相应变长,初始温度设置200为最佳。
python源码
#coding:gbk
import random
import math
global m,C; # m个物品 ,背包容量C
global time,balance; # time 迭代次数, balance 平衡次数
global best,T,af; #best 记录全局最优 T 温度 af退火率
m=10; T=200.0; af =0.95;
time =10; balance = 100;
best_way=[0]*m; now_way=[0]*m # best_way 记录全局最优解方案 now_way 记录当前解方案
weight=[95, 4, 60, 32, 23, 72, 80, 62,65, 46]; value=[55, 10, 47, 5, 4, 50, 8, 61,85, 87]
def cop(a,b,le): #复制函数 把b数组的值赋值a数组
for i in range(le):
a[i]=b[i]
def calc(x): #计算背包价值
global C,wsum;
vsum=0;wsum=0;
for i in range(m):
vsum +=x[i]*value[i]; wsum += x[i]*weight[i];
return vsum;
def produce(): #初始产生随机解
while (1>0):
for k in range(m):
if(random.random() < 0.5): now_way[k]=1;
else: now_way[k]=0;
calc(now_way)
if(wsum 0):
ob = random.randint(0,m-1);
if(x[ob]==1): x[ob]=0;break;
def put(x): #随机放入背包中不存在的物品
while(1>0):
ob = random.randint(0,m-1);
if(x[ob]==0): x[ob]=1;break;
def slove(): #迭代函数
global best,T,balance;
test=[0]*m;
now = 0; #当前背包价值
for i in range(balance):
now = calc(now_way);
cop(test,now_way,m);
ob = random.randint(0,m-1); #随机选取某个物品
if(test[ob]==1): put(test);test[ob]=0; #在背包中则将其拿出,并加入其它物品
else: #不在背包中则直接加入或替换掉已在背包中的物品
if(random.random()<0.5):test[ob]=1;
else : get(test); test[ob]=1;
temp= calc(test);
if(wsum>C):continue; # 非法解则跳过
if(temp > best): best=temp; cop(best_way,test,m); #更新全局最优
if(temp > now): cop(now_way,test,m); #直接接受新解
else:
g = 1.0*(temp-now)/T;
if(random.random() < math.exp(g)): #概率接受劣解
cop(now_way,test,m);
#*****************************主函数**********************
init();
isGood = 0;
for i in range(time):
slove();
T = T*af; #温度下降
if(best==295):
print('找到最优解:295,迭代次数',i+1); isGood = 1; break; #达到最优解提前退出
if(isGood == 0): print('只找到次优解:',best,'迭代次数',time);
print('方案为:',best_way); #打印方案