实验9 模拟退火算法求解背包问题

传送门(所有的实验都使用python实现)

实验1 BP神经网络实验

实验2 som网实验

实验3 hopfield实现八皇后问题

实验4 模糊搜索算法预测薄冰厚度

实验5 遗传算法求解tsp问题

实验6 蚁群算法求解tsp问题

实验7 粒子群优化算法求解tsp问题

实验8 分布估计算法求解背包问题

实验9 模拟退火算法求解背包问题

实验10 禁忌搜索算法求解tsp问题

一、实验目的

理解并使用模拟退火算法

二、实验内容

实现基于模拟退火算法的背包问题求解

三、实验环境

使用Python3.0 在 eclipse进行编辑

四、实验步骤

1、输入介绍:

    背包物体的个数为10,背包容量C,物品价值p,物品重量c。   

    参数设定 : 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 <C): break;
    global best;
    best=calc(now_way);
    cop(best_way,now_way,m);

def init():   #初始化函数
    global C,best,T;
    C = 269;
    best=-1;
    produce()    #产生初始解
def get(x):      #随机将背包中已经存在的物品取出
    while(1>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);               #打印方案
  • 17
    点赞
  • 124
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Blaze Jack

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值