传送门(所有的实验都使用python实现)
一、实验目的
理解并使用分布估计算法
二、实验内容
实现基于分布估计算法的背包问题求解
三、实验环境
使用Python3.0 在 eclipse进行编辑
四、实验步骤
1、输入介绍:
背包物体的个数为10,背包容量C,物品价值p,物品重量c。初始化概率模型每维为0.5
2、产生个体:
通过概率模型,产生n个体。
3、计算个体适应度:
个体适应度为背包中物体的价值总和取负数,但是背包超重的情况下,方案不合法。所以加入罚函数,设超过部分重量为r,将适应值加上r^2*M,只要M足够大就可以将适应值大大降低,进而避免被当成较优解选中。
4、保留适应度较高的前x个解,通过计算联合概率分布,更新概率模型。
5.终止条件
若全局最优未达到295,回到步骤2,否则打印结果,结束迭代。
运行截图:
个体数100,较优解取前30%。未找到最优解
个体数200,较优解取前30%。找到最优解
个体数500,较优解取前30%。找到最优解
个体数1000,较优解取前30%。找到最优解
五、总结
个体数直接影响了算法的效率,通过多次实验可以知道当个体数为100时,多次迭代未能找出最优解,陷入了局部最优,当个体数逐渐增多时,迭代次数明显减少。但是个体过多会导致单次迭代次数时间变长,所以个体数量在500为最佳。此外,构造概率模型的前x个较优解也会影响效率,x取太大失去了较优解的优势,取太小损失了部分较优解,所以取30%为最佳。
python源码
#coding:gbk
import random
global n,m,C; #n个体数量, m物品数量 ,背包容量C
global bn,time; # bn较优个体数量 time 迭代次数
global best; #记录全局最优
n=100; m=10; bn=int(n*0.3);
time =100; #控制迭代次数
p = [0.0]*m; ans = [[0]*(m) for i in range(n)] #概率模型p ans记录种群情况
F = [0.0]*n ; best_way=[0]*m; #F个体适应值 best_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 produce(): #个体产生
for i in range(n):
for k in range(m):
if(random.random() < p[k]): ans[i][k]=1;
else: ans[i][k]=0;
def calc(x): #计算个体适应值
global C
vsum=0;wsum=0;
for i in range(m):
vsum +=x[i]*value[i]; wsum += x[i]*weight[i];
if(C-wsum < 0): gg=C-wsum; #罚函数,若超重则会被无限放大
else :gg= 0;
return -vsum+10000*gg*gg;
def update(): #更新概率模型
mx = -1; ob=0;
for i in range(m): p[i]=0;
for i in range(bn):
mx = -1;
for k in range(n):
if(-F[k]>mx): mx=-F[k]; ob=i;
F[ob]=10000;
for j in range(m):
if(ans[ob][j]==1):p[j]+=1.0;
for i in range(m):
p[i]=p[i]/bn;
def init(): #初始化函数
global C,best;
C = 269;
best=-1;
for i in range(m):p[i]=0.5; #初始概率都为0.5
def slove(): #迭代函数
global best
produce() #产生新个体
for i in range(n): #计算适应度
F[i]=calc(ans[i])
if(-F[i] > best ):
best = -F[i]; cop(best_way,ans[i],m);
update(); #更新概率模型
init();
isGood = 0; #标记是否找到最优解
for i in range(time):
slove();
if(best==295):
print('找到最优解:295,迭代次数',i+1); isGood = 1; break; #达到最优解提前退出
if(isGood == 0): print('只找到次优解:',best,'迭代次数',time);
print('方案为:',best_way); #打印方案