文章目录

  • 一.背包问题描述
  • 二.背包问题具体示例
  • 三.遗传算法求解背包问题
    • 1.个体编码
    • 2.约束处理
    • 3.代码实现

一.背包问题描述

背包问题(knapsack problem)是指从多种物品中选择几件物品装满背包。在不超过背包承受重量的前提下,使装入背包的物品价值最大。假设存在n个不同物品,对于某物品j,其重量为w_j,价值为c_j,背包的最大承重量为W,则背包问题可以用数学语言描述为:

其中x_j为物品j的决策变量,如果物品j被选中,则x_j = 1,否则x_j = 0

背包问题理论上是一个NP-hard问题,目前还没有可以求解最优解的算法,但是很多情况下,用遗传算法在短时间内能求解到比较高质量的解。

二.背包问题具体示例

给定物品数目n为20个,重量W限制为40单位
物品的重量与价值如下所示:

三.遗传算法求解背包问题

1.个体编码

求解背包问题时,比较自然的编码方式是采用二进制编码,即用长度为物品个数的二进制序列来表示问题的候选解,序列中每一位表示物品的选择情况,当该位为1时,代表物品被选中,否则代表物品未放入背包中。

2.约束处理

在对染色体进行交叉和变异操作的时候,可能会出现解不符合约束的情况,一般有两种处理的思路:

  • 第一种思路是使用惩罚函数降低这种解的适应度,使得不符合约束的解在自然选择中逐渐被淘汰。
  • 另一种思路是使用修复方法,将落在不可行区域的候选解重新移入可行域。

这个背包问题比较简单,使用最简单粗暴的死亡惩罚就能取得较好的结果。

3.代码实现

遗传算法操作:

  1. 编码方式-二进制编码
  2. 评价函数-放入背包的所有物品价值之和,施加死亡惩罚
  3. 育种选择-锦标赛选择
  4. 变异算法-交叉-两点交叉,突变-位翻转突变
  5. 环境选择-精英保留策略
#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
@author: liujie
@software: PyCharm
@file: 背包问题.py
@time: 2020/11/29 14:33
"""
import numpy as np
import matplotlib.pyplot as plt
import random
from deap import creator,tools,baseparams = {'font.family':'serif','figure.dpi':300,'savefig.dpi':300,'font.size':12,'legend.fontsize':'small'
}plt.rcParams.update(params)
# print(plt.rcParams.keys())# 定义问题
creator.create('FitnessMax',base.Fitness,weights=(1.0,))
creator.create('Individual',list,fitness = creator.FitnessMax)# 个体编码-二进制编码
# 编码长度为物品个数
gen_size = 20
toolbox = base.Toolbox()
toolbox.register('Binary',random.randint,0,1)
# 注册个体
toolbox.register('Individual',tools.initRepeat,creator.Individual,toolbox.Binary,n = gen_size)
# 注册种群
toolbox.register('Population',tools.initRepeat,list,toolbox.Individual)weightList = [2, 5, 18, 3, 2, 5, 10, 4, 8, 12, 5, 10, 7, 15, 11, 2, 8, 10, 5, 9]
valueList = [5, 10, 12, 4, 3, 11, 13, 10, 7, 15, 8, 19, 1, 17, 12, 9, 15, 20, 2, 6]
# 评价函数-背包中价值总和
def eval(ind):return (np.sum(np.dot(np.array(valueList),np.array(ind).T))),## 施加惩罚
def feasible(ind, W=40):'''可行性函数,判断个体是否满足背包总重量约束'''weightSum = np.sum(np.dot(np.array(weightList),np.array(ind).T))if weightSum < W:return Truereturn Falsetoolbox.register('evaluate',eval)
# 当个体不满足总的重量约束时,个体适应度-10
toolbox.decorate('evaluate',tools.DeltaPenality(feasible,-10))
# 注册遗传算法操作-育种选择,交叉、变异
toolbox.register('select',tools.selTournament,tournsize = 2)
toolbox.register('mate',tools.cxTwoPoint)
toolbox.register('mutate',tools.mutFlipBit,indpb=0.5)# 创建统计对象-用数据记录算法迭代过程
stats = tools.Statistics(key= lambda ind : ind.fitness.values)
stats.register('avg',np.mean)
stats.register('std',np.std)
stats.register('min',np.min)
stats.register('max',np.max)# 创建日志对象
logbook = tools.Logbook()
logbook.header = 'gen','avg','std','min','max'# 遗传算法主要操作
pop_size = 100
N_GEN = 100
CXPB = 0.8
MUTPB = 0.2# 生成族群
pop = toolbox.Population(n = pop_size)# 评价初代种群
invalid_ind = [ind for ind in pop if not ind.fitness.valid]
fitnesses = list(map(toolbox.evaluate,invalid_ind))
for ind,fit in zip(invalid_ind,fitnesses):ind.fitness.values = ind
# 记录
record = stats.compile(pop)
logbook.record(gen = 0,**record)# 遗传算法迭代
for gen in range(1+N_GEN):# 配种选择selectTour = toolbox.select(pop,k = pop_size)# 复制selectInd = list(map(toolbox.clone,selectTour))# selectInd = [toolbox.clone(_) for _ in selectTour]# 交叉for child1,child2 in zip(selectInd[::2],selectInd[1::2]):if random.random() < CXPB:toolbox.mate(child1,child2)del child1.fitness.valuesdel child2.fitness.values# 变异for ind in selectInd:if random.random() < MUTPB:toolbox.mutate(ind)del ind.fitness.values# 对于被改变的个体,重新计算其适应度invalid_ind = [ind for ind in selectInd if not ind.fitness.valid]fitnesses = list(map(toolbox.evaluate,invalid_ind))for ind,fit in zip(invalid_ind,fitnesses):ind.fitness.values = fit# 精英育种combinedPop = pop + selectIndpop = tools.selBest(combinedPop,pop_size)# 记录record = stats.compile(pop)logbook.record(gen = gen,**record)# 打印迭代情况
print(logbook)# 打印最终结果
bestInd = tools.selBest(pop,1)[0]
bestFit = bestInd.fitness.values[0]
weightSum = np.sum(np.dot(np.array(weightList),np.array(bestInd).T))
print('最优解为:',str(bestInd))
print('对应函数的最大值为:',bestFit)
print('背包重量为:',weightSum)# 迭代过程可视化
avg = logbook.select('avg')
max = logbook.select('max')
gen = logbook.select('gen')
plt.plot(gen,avg,'r-',label='AVG_FITNESS')
plt.plot(gen,max,'b-',label='MAX_FITNESS')
plt.legend(loc = 'best')
plt.xlabel('gen')
plt.ylabel('fit')
plt.tight_layout()
plt.show()

运行结果

gen  avg     std     min max
0   0.51    0.4999  0   1
0   1.92    7.47353 0   56
1   6.91    16.5784 0   69
2   12.39   21.2028 1   69
3   27.06   25.4023 1   69
4   52.23   8.44258 34  78
5   58.82   4.91606 54  78
6   63.04   5.65671 56  78
7   66.95   4.76943 61  78
8   70.95   4.16023 66  81
9   75.22   3.53152 70  81
10  79.05   1.43091 78  81
11  80.4    1.2     78  81
12  81      0       81  81
13  81      0       81  81
14  81      0       81  81
15  81      0       81  81
16  81      0       81  81
17  81      0       81  81
18  81      0       81  81
19  81      0       81  81
20  81      0       81  81
21  81      0       81  81
22  81      0       81  81
23  81      0       81  81
24  81      0       81  81
25  81      0       81  81
26  81      0       81  81
27  81      0       81  81
28  81      0       81  81
29  81      0       81  81
30  81      0       81  81
31  81      0       81  81
32  81      0       81  81
33  81      0       81  81
34  81      0       81  81
35  81      0       81  81
36  81      0       81  81
37  81      0       81  81
38  81      0       81  81
39  81      0       81  81
40  81      0       81  81
41  81      0       81  81
42  81      0       81  81
43  81      0       81  81
44  81      0       81  81
45  81      0       81  81
46  81      0       81  81
47  81      0       81  81
48  81      0       81  81
49  81      0       81  81
50  81      0       81  81
51  81      0       81  81
52  81      0       81  81
53  81      0       81  81
54  81      0       81  81
55  81      0       81  81
56  81      0       81  81
57  81      0       81  81
58  81      0       81  81
59  81      0       81  81
60  81      0       81  81
61  81      0       81  81
62  81      0       81  81
63  81      0       81  81
64  81      0       81  81
65  81      0       81  81
66  81      0       81  81
67  81      0       81  81
68  81      0       81  81
69  81      0       81  81
70  81      0       81  81
71  81      0       81  81
72  81      0       81  81
73  81      0       81  81
74  81      0       81  81
75  81      0       81  81
76  81      0       81  81
77  81      0       81  81
78  81      0       81  81
79  81      0       81  81
80  81      0       81  81
81  81      0       81  81
82  81      0       81  81
83  81      0       81  81
84  81      0       81  81
85  81      0       81  81
86  81      0       81  81
87  81      0       81  81
88  81      0       81  81
89  81      0       81  81
90  81      0       81  81
91  81      0       81  81
92  81      0       81  81
93  81      0       81  81
94  81      0       81  81
95  81      0       81  81
96  81      0       81  81
97  81      0       81  81
98  81      0       81  81
99  81      0       81  81
100 81      0       81  81
最优解为: [1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
对应函数的最大值为: 81.0
背包重量为: 39

可视化

基于DEAP库的python进化算法--遗传算法实践--背包问题相关推荐

  1. 遗传算法 python 简书_基于DEAP库的Python进化算法从入门到入土—(二)简单遗传算法实现...

    前言 在上一篇中,我们已经介绍了如何在DEAP中实现进化算法的基本操作,在这一篇中我们试图将各个操作组装起来,用进化算法解决一个简单的一元函数寻优问题. 进化算法实例 - 一元函数寻优 问题描述与分析 ...

  2. python路线寻优_基于DEAP库的Python进化算法从入门到入土 --(四)遗传算法的改进...

    前言 前面一节我们尝试了用GA求解TSP问题,简单遗传算法总是不能很好收敛到一个较优的解,在用时和求解精度上都被贪心算法吊打.在末尾我们总结了三个可能的改进方向,这次我们想要沿着这三个方向试着改进简单 ...

  3. 基于DEAP库的Python进化算法

    https://www.jianshu.com/p/8fa044ed9267 http://geatpy.com/index.php/category/geatpy_tutorials/

  4. 基于Pyinstaller库将Python项目包括 图片打包exe方法,本人已经实践多次

    基于Pyinstaller库将Python项目包括 图片打包exe方法,本人已经实践多次 文章目录 基于Pyinstaller库将Python项目包括 图片打包exe方法,本人已经实践多次 一.前言 ...

  5. IGD+-EMOA:基于IGD+的多目标进化算法

    IGD±EMOA:基于IGD+的多目标进化算法 参考文献 <IGD±EMOA:A Multi-Objective Evolutionary Algorithm based on IGD+> ...

  6. MaOEA-IBP:带有边界保护的基于指标的多目标进化算法

    MaOEA-IBP:带有边界保护的基于指标的多目标进化算法 参考文献 <An Indicator-Based Many-Objective Evolutionary Algorithm With ...

  7. 【图像压缩】基于matlab香农熵和差分进化算法多级图像阈值图像压缩【含Matlab源码 2035期】

    一.差分进化算法简介 1 前言 在遗传.选择和变异的作用下,自然界生物体优胜劣汰,不断由低级向高级进化和发展.人们注意到,适者生存的进化规律可以模式化,从而构成一些优化算法:近年来发展的进化计算类算法 ...

  8. 进化算法--遗传算法

    遗传算法 一.能解决的问题 如果你需要解决一个问题,这个问题的每一个可能的解均可以用位串来表示,那么遗传算法就能解决这个问题. 二.术语 个体:每一个可能的解: 种群:一群个体: 基因:个体中位的一个 ...

  9. 新手题库-《Python语言程序设计》实践6

    选择题 1. 关于Python的分支结构,以下选项中描述错误的是 [ 正确答案: B] A Python中if-elif-else语句描述多分支结构 B 分支结构可以向已经执行过的语句部分跳转 C P ...

  10. Python遗传算法库和进化算法框架(二)Geatpy库函数和数据结构

    (转载自https://blog.csdn.net/qq_33353186/article/details/82020507) 上一篇讲了Geatpy的快速入门:https://blog.csdn.n ...

最新文章

  1. 个人开发者帐号+wireless install 实现非app store程序的在线更新功能
  2. [android] 手机卫士设置向导页面
  3. 43 MM配置-采购-条件-定价过程-定义存取顺序
  4. WordPress基础教学:绝对必装的JetPack外挂
  5. Centos5.6 x86_64下安装DRBD+Heartbeat+NFS
  6. 反应堆模式最牛的那篇论文--由solidmango执笔翻译
  7. burp proxy 过滤_burpsuite只拦截特定网站数据包教程
  8. Android自定义View控件
  9. iovec结构体定义及使用 (转)
  10. 2022年上半年系统集成项目管理工程师下午真题及答案解析
  11. 推荐一些学习SEO的优秀书籍附pdf电子书下载地址
  12. Tools_Procexp找文件被哪个进程占用
  13. 双十一值得入手的数码好物有哪些?分享几款不错的数码好物
  14. 制作svg格式矢量图
  15. 2年工作经验杂谈(java开发)
  16. golang指数运算
  17. 【20保研】天津大学智能与计算学部2020级研究生招生夏令营活动通知
  18. 炫富神器 | 辣条专业国内首开,网友:中国吃货石锤了 ​!
  19. ae缺少效果opticalflares_Optical Flares 镜头光晕AE插件
  20. 建模师有年龄限定吗?45岁还能学吗

热门文章

  1. uva 10562 Undraw the Trees
  2. NET常出现的三十三种代码(1)
  3. c#通过RFC调用SAP接口程序之输入输出参数案例
  4. Oracle之触发器
  5. Luogu1613 跑路
  6. javascript 对象(四)
  7. VS 2017 RC到期的解决方法
  8. Linux内核分析学习心得
  9. [IC]Lithograph(1)光刻技术分析与展望
  10. WebService的网络协议