问题描述

具体的问题描述请参考以下链接:

[Algorithmic Toolbox学习笔记][week3]战利品的最大价值_Karen_AMPM的博客-CSDN博客假设小偷有一个背包只能放下一定重量的货物。如果他来到一家商店,商店里有不同的商品(已知数量和单价)。那么小偷在背包重量有限的情况下,拿走哪些商品才能保证在背包允许的最大重量下商品总价值最高呢?https://blog.csdn.net/Karen_AMPM/article/details/126730940?spm=1001.2014.3001.5501

假设我们有以下一组数据:

背包可承受的最大重量:10kg

item重量和价值如下:

weight   value

item1      5kg        60元  --> 指5kg item1的价值为60元

item2      3kg        50元

item3      2kg        70元

item4      1kg        30元

在上方链接的文章中,当我们要去计算能够被拿走的物品的最大价值的时候,我们使用的是物品的单价(即每千克这个物品的价值是多少),然后去做Greedy Algorithm的计算,即当有5kg item1的时候我们可以只拿走2kg。因此如果使用链接中的代码来运行的话,背包中应该放如下物品:

2kg 的 item3 --> value is 2 x 35 = 70
1kg 的 item4 --> value is 1 x 30 = 30
3kg 的 item2 --> value is 3 x 16.666 = 50
4kg 的 item1 --> value is 4 x 12 = 48

最大价值等于 198

但是,0/1 Knapsack Problem与上方问题不同的是,0/1 Knapsack Problem需要解决的是如何在不拆分物品的条件下去计算出物品的最大价值。比如现有5kg的item1价值60元,那么我们在拿的时候,要么5kg全部拿走,要么不拿,即不能像上面的例子中只拿走4kg。

Knapsack Problem算法解析

分两种情况来解析:

Knapsack with repetitions:指不限制每一个item的组合(重量和价格)的数量。

Knapsack without repetitions (use dynamic programming):指每一个item的组合只有一个。

假设我们有以下一组数据:

weight_list = [5, 3, 2, 1]
value_list = [60, 50, 70, 30]

比如同样针对这组数据,当背包最大承受重量为4kg的时候:

Knapsack with repetitions:我们可以用2组item3(总重量等于4kg),此时的最大价值为140元。
Knapsack without repetitions:由于每组item只能使用1次,因此选择item3和item4,此时背包里的总重量为3kg,且最大价值为70+30=100元

Knapsack with repetitions 

上图中的W表示背包允许的最大重量,那么我们可以知道要求 maxvalue ( W ),我们实际上需要求maxvalue ( W - wi ),由此可见 maxvalue ( W ) = maxvalue ( W - wi ) + vi。

举例说明:

针对上方给出的物品价值和重量,如果背包最大重量为3,那么我们应该怎么做?

首先,当W = 3的时候,此时:
当 i = 0 的时候,wi = w[0] = 5, vi = v[0] = 60 -->由于5超出了最大重量,因此这种情况不考虑
当 i = 1 的时候,wi = w[1] = 3, vi = v[0] = 50 -->maxvalue(3) = maxvalue(3-3) + 50

当 i = 2 的时候,wi = w[2] = 2, vi = v[0] = 70 -->maxvalue(3) = maxvalue(3-2) + 70

当 i = 3 的时候,wi = w[3] = 1, vi = v[0] = 30 -->maxvalue(3) = maxvalue(3-1) + 30

--

此时出现了3个分支:

1. 求maxvalue(0) --> 由于当背包重量为0的时候,其最大价值也为0,因此maxvalue(0) = 0

2. 求maxvalue(1) --> 由于w[0-3]中只有w[3] <= 1,因此此分支下只有一个分支:
     2.1 maxvalue(1) = maxvalue(0) + 30 = 30

3. 求maxvalue(2) --> 由于w[0-3]中有w[2]和w[3] <= 2,因次此分支下又有两个分支:
     3.1 maxvalue(2) = maxvalue(2-2) + 70 = maxvalue(0) + 70

3.2 maxvalue(2) = maxvalue(2-1) + 30 = maxvalue(1) + 30

----

用树形图来表示的话:

--------

由此可知当W = 3的时候,我们实际上有四种可以考虑的情况:

1. 3 = 3 + 0         --> 对应的价值为 50
2. 3 = 1 + 2         --> 对应的价值为 100
3. 3 = 1 + 0 + 2   --> 对应的价值为 100
4. 3 = 1 + 1 + 1   --> 对应的价值为 90

通过比较我们可以知道,此时的最大价值为100。

用python3来实现这个逻辑的话,我们会得到:

def maxvalue(W, wt, val):if W == 0: return 0if len(wt) == 0: return 0for w in range(1, W+1):bigvalue = 0for i in range(0, len(wt)):wi = wt[i]vi = val[i]if wi <= w:left_weight = w - witotal_value = maxvalue(left_weight, wt, val) + viif total_value > bigvalue:bigvalue = total_valuereturn bigvaluewight = 3 # allowed weight of the packpack
weight_list = [6, 3, 4, 2]
value_list = [30, 14, 16, 9]print(maxvalue(wight, weight_list, value_list))

Knapsack without repetitions

当item的组合不允许被重复使用的时候,此时我们应该怎么求解这个问题?
答案就是使用dynamic programming来解决。

假设背包可承受的最大重量为5kg,那么要解决5这个问题,我们首先解决当最大可承受重量为4的时候物品的最大价值;要解决4这个问题,我们要先解决3,...,直到0。那么通过子问题的答案,我们就能够一步一步倒推到主问题的答案。

我们先画下面这样一个表格。表格中的A表示当背包允许的最大重量为3的时候,如果我们只有item1,item2,item3,那么此时可以带走的物品的最大价值是多少?表格中的B表示当背包允许的最大重量为5的时候,如果我们只有item1,那么此时可以带走的物品的最大价值是多少?

针对第一行:
由于单元格中我们要填写的内容是当背包最大重量为W的时候,在只有item1的情况下能够构成的最大价值。

我们知道item1的重量为5,因此只有当W=5的时候才能够放入item1,因此当W=5的时候,maxvalue = v(item1) = 60。而当W=4 或 3,2,1,0的情况下,重量不足以放下item1,因此无法选择item1,所以此时的最大价值为0。

针对第二行:

由于单元格中我们要填写的内容是当背包最大重量为W的时候,在只有item1和item2的情况下能够构成的最大价值。

1. 当W = 0的时候,此时任何物品都放不下 --> maxvalue = 0

2. 当W = 1的时候,item2放不进去 --> 查看W=1的时候只有item1的时候是否能放入
    --> 查看坐标0,1的值 --> maxvalue = v[0,1] = 0

3. 当W = 2的时候,item2放不进去 --> 查看W=2的时候只有item1的时候是否能放入
    --> 查看坐标0,2的值 --> maxvalue = v[0,2] = 0

3. 当W = 3的时候,item2可以放进去 --> 此时有两个选择:
    3.1 使用item2 --> maxvalue = v(item2) + v(W - w (item2))
           = v(item2) + [当W=0时且可用item只有item1时的value]

= v(item2) + [坐标 0,0 的值] = v(item2) + v[0,0] = 50 + 0 = 50

3.2 不使用item2 --> maxvalue = [当W=3时且可用item只有item1时的value]
           = [坐标 0,3 的值] = v[0,3] = 60

--> 此时比较这两个maxvalue,可知在使用item2的时候总价值最大,因此单元格填50

4. 当W = 4的时候,同理可知道 maxvalue = v(item2) = 50

5. 当W = 5的时候,item2可以放进去,此时有两个选择:

5.1 使用item2 --> maxvalue = v(item2) + v(W - w (item2))
           = v(item2) + [当W=2时且可用item只有item1时的value]
           = v(item2) + [坐标 0,2 的值] = v(item2) + v[0,2] = 50 + 0 = 50

5.2 不使用item2 -->  maxvalue = [当W=5时且可用item只有item1时的value]
           = [坐标 0,5 的值] = v[0,5] = 60

--> 此时比较这两个maxvalue,可知不使用item2的时候总价值最大,因此单元格填60

针对第三行:

由于单元格中我们要填写的内容是当背包最大重量为W的时候,在只有item1,item2和item3的情况下能够构成的最大价值。

1. 当W = 0的时候,此时任何物品都放不下 --> maxvalue = 0

2. 当W = 1的时候,item3放不进去 --> 查看W=1的时候只有item1和item2的时候是否能放入
    --> 查看坐标1,1的值 --> maxvalue = v[1,1] = 0

3. 当W = 2的时候,item3可以放进去,此时有两个选择:(具体逻辑请查看当W=3时)

--> maxvalue = v(item3) = 70

3. 当W = 3的时候,item3可以放进去,此时有两种选择:

3.1 使用item3 --> maxvalue = v(item3) + v(W - w (item3))
          = v(item3) + [当W=1时且可用item只有item1和item2时的value]

= v(item3) + [坐标 1,1 的值] = v(item3) + v[1,1] = 70 + 0 = 70
    3.2 不使用item3 --> maxvalue = [当W=3时且可用item只有item1和item2时的value]
           = [坐标 0,5 的值] = v[1,3] = 50

--> 此时比较这两个maxvalue,可知使用item3的时候总价值最大,因此单元格填70

4. 当W = 4的时候,带入3的逻辑可知maxvalue = 70

5. 当W = 5的时候,item3可以放进去,此时有两个分支:

5.1 使用item3 --> maxvalue = v(item3) + v(W - w (item3))
          = v(item3) + [当W=3时且可用item只有item1和item2时的value]

= v(item3) + [坐标 1,3 的值] = v(item3) + v[1,3] = 70 + 50 = 120
    5.2 不使用item3 --> maxvalue = [当W=5时且可用item只有item1和item2时的value]
           = [坐标 1,5 的值] = v[1,5] = 60

--> 此时比较这两个maxvalue,可知使用item3的时候总价值最大,因此单元格填120

同理把第四行也填满后我们会得到下面的表格:

针对上文中红色文字标注出来的坐标:

针对第二行:
求 v[1,5] --> max{ v[0,2] + v(item2), v[0,5] }

针对第三行:
求 v[2,3] --> max{ v[1,1] + v(item3), v[1,3] }
求 v[2,4] --> max{ v[1,2] + v(item3), v[1,4] }
求 v[2,5] --> max{ v[1,3] + v(item3), v[1,5] }

通过以上推演,我们可以得出以下规律,如果我们要求坐标 [i,j] 的值:

注:假设第行 i 对应的item 就为 item i , j 表示背包允许的最大重量

1. 当当前行的item重量大于对应的 j 的时候:

     v [ i , j ] = v [ i-1, j ]

2. 否则就有两个选项,然后取大的值:

    2.1 使用 i 行的item --> maxvalue = v(item i) + v(j - w (item i))
           = v [i-1, j - w(item i)] + v(item i)

    2.2 不使用 i 行的item --> maxvalue = v [ i-1 , j ]

用python3来实现这个逻辑的话,我们会得到:

def maxvalue(W, wt, val):if W == 0: return 0if len(wt) == 0: return 0V = [[0 for x in range(W+1)] for x in range(len(wt)+1)]for j in range(1, W+1):bigvalue = 0for i in range(0, len(wt)):wi = wt[i]vi = val[i]if wi > j:V[i][j] = V[i-1][j]else:V[i][j] = max(V[i-1][j], vi + V[i-1][j-wi])return V[len(wt)-1][W]wight = 4 # allowed weight of the packpack
weight_list = [6, 3, 4, 2]
value_list = [30, 14, 16, 9]print(maxvalue(wight, weight_list, value_list))

[Algorithmic Toolbox学习笔记][week6]0/1 Knapsack Problem相关推荐

  1. [Algorithmic Toolbox学习笔记][week6]Placing Parentheses

    问题描述 假设当前给出一组算式 5 - 8 + 7 * 4 - 8 + 9,在你只能加括号的情况下,怎样去获取其最大值? 比如: 1. ( 5 - 8 ) + ( 7 x 4 ) - ( 8 + 9) ...

  2. Dollar toolbox 学习笔记(一)

     Dollar toolbox 学习笔记(一) Dollar toolbox工具包是dollar写的关于行人检测的MATLAB工具包,工具包是对他经典论文的实现. 可在https://pdolla ...

  3. RK3399学习笔记 1.0.3---python环境 Firefly Core-3399pro-jd4 Win10上RKNN工具安装

    RK3399学习笔记 1.0.3---python环境 Firefly Core-3399pro-jd4 Win10上RKNN工具安装 读取模型各层 1,最好在Conda下新建一个虚拟环境进行安装. ...

  4. Python学习笔记 1.0 基础内容篇章

    Python学习笔记 1.0 基础内容篇章 注释 变量 一.定义变量 二.使用变量 bug和debug bug: Debug工具: 数据类型 认识数据类型 在定义数据类型时发生的错误: 数据类型的补表 ...

  5. 数据可视化清新版【chart.js】学习笔记8.0—极地图(Polar Area)

    Polar Area--(极地图) 极地面积图类似于饼图,但每个线段具有相同的角度 - 线段的半径因值而异.当我们想要显示类似于饼图的比较数据,同时也要显示上下文的值的范围时通常使用这种类型的图表. ...

  6. 嵌入式Linux学习笔记(0)基础命令。——Arvin

    学习记录: 到今天为止ARM裸机开发学习进程:1.2.1-1.2.14 预科班知识Linux介绍学习进程:0.2.1-0.2.6 学习内容笔记: 学习了Linux的开发方式的优劣介绍 学习了常用文件夹 ...

  7. 图像处理学习笔记2.0

    matlab写的floodfill进阶 首先介绍一下floodfill 百度百科 英文版解释请自行搜索. 再来说一下我是怎么想到学这个的,我是要做图像分割的,做完图像分割将图像进行二值化的时候出现了问 ...

  8. linux学习笔记2.0

    ilinux学习笔记 Linux哲学思想 一切都是一个文件(包括硬件) **小型,单一用途的程序 ** **链接程序,共同完成复杂的任务 ** **避免令人困惑的用户界面 ** 配置数据存储在文本中 ...

  9. 淘宝网触屏版 - 学习笔记(0 - 关于dpr)

    注:本文是学习笔记,并不是教程,所以会有很多我不理解或猜测的问题,也会有不尽详实之处,望见谅. 对于pc端网页设计师来说,移动端的网页制作,我之前只是简单的加了一个 <meta name=&qu ...

最新文章

  1. php导出页面word,php导出生成word的方法_PHP
  2. php进程SIGBUS,SIGSEGV错误
  3. java bouncycastle_java – 使用bouncycastle进行签名和验证签名的正确方法
  4. 以前是传xml的吗_明明不太合适但是还是被用在配置文件和数据传输上的XML
  5. 嵌入式工作笔记0002---认识CRT显示器
  6. python股票交易系统实现_python实现股票自动交易,自动量化交易软件
  7. 盘点数独终盘生成算法
  8. [工具书]IntelliJ IDEA社区版下载及配置 - ZIP版
  9. 贝叶斯分析好坏_交易必读|浅谈贝叶斯分析
  10. 计算机数值换算在线,计算机单位换算(计算机单位换算在线)
  11. Notepad++ 替换换行符
  12. 从0到1400star,从阮一峰周刊到尤雨溪推荐,小透明开源项目的2021年总结
  13. 华为朗读屏幕怎么关闭
  14. SQL 常用查询语句
  15. ORACLE公司的历史
  16. 八、jQuery的QQ音乐播放器
  17. HTTP/2是什么?和HTTP/1.1有什么不同?和SPDY有什么不同?
  18. 网络7层协议详解——Network layer protocol
  19. sdau启航第二次作业
  20. 我的读者我来宠 | MS08067邀请你来写新书推荐语

热门文章

  1. shell 字体颜色代码
  2. CF1294F 题解
  3. 使用内连接查询选修了Java程序基础_使用内连接 查询选修了“java程序基础”课程的学生学号、姓名、课程号、课程名和期末成绩_学小易找答案...
  4. 英属哥伦比亚大学教授发明电动汽车无线充电技术(为什么新技术总是国外先出来,我们copy?什么时候能反过来啊!)
  5. WS-DAN论文解读
  6. 惠普ubuntu安装bios设置
  7. 水桶服务器的作用,我的世界水桶服务器是什么 我的世界水桶服务器怎么制作...
  8. 靠谱的voip系统解决方案
  9. 网吧加油站_“天下加油站”更名为“天下网吧加油站”
  10. 比武招亲的java游戏,比武招亲百度版本下载