模拟退火算法

背包内物品最佳搭配方案:
import random
import math
import numpy as np
#global强调全局变量,即当有函数内部变量引用时,写global可以修改其值而不报错
global m,C #m个物品,背包容量C
global time,balance #time迭代次数,balance平衡次数
global best,T,af #best记录全局最优,T温度,af退火率
m = 7 #物品数
C = 8 #背包承载量
T = 200.0 #初始温度
af = 0.95 #退火速度
time =10 #迭代次数上限
balance = 10 #平衡次数
best_way = [0]*m #best_way记录全局最优解方案
now_way = [0]*m #now_way记录当前解方案
weight = [1,2,2,0.5,0.6,0.8,2.5] #物品重量
value = [16,18,31,29,17,23,26] #物品价格
name = [‘面包’,‘苹果’,‘牛奶’,‘保温杯’,‘面巾纸’,‘沐浴露’,‘洗衣液’]

def cop(a,b,le): #复制函数把b数组的值赋值a数组
for i in range(le):
a[i] = b[i]

def value_of_items(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 random_solution(): #初始产生随机解
while True:
for k in range(m):
#随机选择物品,有则1,无则0
if(random.random() < 0.5):
now_way[k] = 1
else:
now_way[k] = 0
value_of_items(now_way)
if(wsum < C):
break #当随机选择的物品总重量小于背包容量时即可输出
global best
best=value_of_items(now_way) #计算此时的物品总价值,并作为当前的最高价值
cop(best_way,now_way,m) #将随机选择的物品选择作为当前最佳选择

def init(): #初始化函数
global best,T
best=0
random_solution() #产生初始解

def get_out(x): #随机将背包中已经存在的物品取出
while True:
ob = random.randint(0,m-1) #随机选择一个位置
if(x[ob] == 1):
x[ob] = 0
break

def put_in(x): #随机放入背包中不存在的物品
while True:
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 = value_of_items(now_way) #当前价值
cop(test,now_way,m)
ob = random.randint(0,m-1) #随机选取某个物品
if(test[ob] == 1):
put_in(test)
test[ob] = 0 #在背包中则将其拿出,并加入其它物品
else: #不在背包中则直接加入或替换掉已在背包中的物品
if(random.random() < 0.5):
test[ob] = 1
else:
get_out(test)
test[ob] = 1
temp = value_of_items(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)

def name_of_items():
best_name = []
for i in range(m):
if best_way[i] == 1:
best_name.append(name[i])
return best_name

if name == “main”:
init()
isGood = 0
for i in range(time):
slove()
T = T*af #温度下降
print(‘背包内总价值为:’+str(best)+“元”)
best_name = name_of_items()
print(‘背包内物品:’,best_name) #打印方案

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值