QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2692|回复: 0
打印 上一主题 下一主题

python代码解决0-1背包问题

[复制链接]
字体大小: 正常 放大

1189

主题

4

听众

2934

积分

该用户从未签到

跳转到指定楼层
1#
发表于 2023-11-7 11:17 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
一、首先介绍一下0-1背包问题:
; Q( M$ M; N/ _5 t2 W/ i
        0-1背包问题(0-1 Knapsack Problem)是一个经典的组合优化问题,通常在计算机科学和运筹学中讨论。这个问题涉及到一个背包和一组物品,每个物品都有一个特定的重量和价值。问题的目标是在给定背包的最大容量下,选择一组物品放入背包,以使得所选物品的总重量不超过背包的容量,同时最大化这些物品的总价值。- n( S( [, C; k* c& O3 ~
         0-1背包问题的名称中的“0-1”表示每个物品要么完全放入背包(选择)要么完全不放入背包(不选择),不能部分放入。这是问题的一个关键特征,与分数背包问题不同,分数背包问题允许部分放入物品。. n8 M% C% p( U
问题的形式描述如下:

0 z7 L" z3 L; l; A' t- F                 1.给定一个固定容量的背包,通常表示为一个正整数W(背包的最大承载重量)。2 s5 D) F6 z7 x" H4 E) Q7 ?. ~
                 2.给定一组物品,每个物品都有两个属性:重量(weight)和价值(value)。8 |; u" L  {; y/ m1 n- I
                 3.对每个物品,你可以选择将其放入背包(选择)或不放入背包(不选择)。
1 D8 m  }! z9 o8 `* A" G                 4.每个物品只能选择一次,即要么放入背包,要么不放入。
$ l/ g7 s+ |3 J6 m, ~                 5.目标是选择一个物品组合,使得它们的总重量不超过背包容量W,同时使它们的总价值最大化。# Z$ C: F3 Q* V" X! s
6 R+ C0 }$ o, y* E8 V% {! t
解决0-1背包问题的一种常见方法是使用动态规划(Dynamic Programming)算法。这个问题有广泛的应用,包括资源分配、排程问题、投资组合优化等领域。它还是计算复杂性理论中的一个经典问题,通常被用来说明NP难问题的概念。  y6 U' e6 K3 n/ S& e7 O; J! Z

1 [( g+ F1 Z6 t& V6 g. `& Y; V) Z& Y
. ?5 ^5 Z. s- y+ V8 e  |二、 介绍代码
) J8 g' g) R: c) ?这段代码是一个Python实现的0-1背包问题的解决方法,使用了动态规划算法来找到最优解。以下是对代码的详细解释:
  1. def knapsack(v, w, n, capacity):
    1 j# U6 ?0 `; }' E
  2.     i = 0/ r  H( x8 u3 u
  3.     capacity = capacity + 1  # 初始化背包容量最大值& z! Q\" o1 i7 o! {. }
  4.     m = np.zeros((n, capacity))  # 初始化9 i* c& |0 `+ M
  5.     x = np.zeros(n)
复制代码
1.v 是一个长度为 n 的列表,表示每个物品的价值。
0 S: j" ?$ N) x1 \* G$ I2.w 是一个长度为 n 的列表,表示每个物品的重量。, u/ X) T, W% J) m  o. g$ F2 P7 g+ @
3.n 表示物品的数量。
* t9 C7 ], }# K( f6 b/ O7 o2 u& Z4.capacity 表示背包的容量。
! v1 e3 Y- l  Z- c* @  E. F. C4 P1 `1 o) L+ U4 e
代码首先初始化了一个二维数组 m 作为动态规划表,其中 m[j] 表示在考虑前 i 个物品时,背包容量为 j 时可以获得的最大总价值。数组 x 用来存储最终的解,x 表示是否选择第 i 个物品。
  1.     for i in range(n):
    ! [. Z% k5 t& N; ?  H' F4 @5 Z\" A
  2.         for j in range(capacity):$ }% L3 r/ X( H: t
  3.             if (j >= w[i]):2 M. y: H  r8 ?) ^& X
  4.                 m[i][j] = max(m[i - 1][j], m[i - 1][j - w[i]] + v[i])
    ( a* D: E& u/ W1 M
  5.             else:
    0 j/ ~( Y* ^4 i7 c& v
  6.                 m[i][j] = m[i - 1][j]
复制代码
在这个部分,代码使用了一个嵌套的循环,遍历了所有物品和不同的背包容量。对于每个物品 i 和容量 j,代码计算了两种情况下的最大总价值:
& @+ P8 f  r. Z+ N0 u/ K0 g2 v5.如果当前物品的重量 w 小于等于当前容量 j,那么可以选择将第 i 个物品放入背包,此时总价值为 m[i-1][j-w] + v,或者选择不放入,此时总价值为 m[i-1][j]。代码选择其中较大的值作为 m[j]。$ u# F: _9 P8 p
6.如果当前物品的重量 w 大于当前容量 j,则无法放入物品,所以总价值等于上一行的值 m[i-1][j]。" m2 ^& m+ |3 }# V' Q+ ]

1 z7 J1 p0 W: [1 y# j9 `这个循环填充了动态规划表 m,最终 m[n-1][capacity] 包含了问题的最优解,即在给定容量下可以获得的最大总价值。
  1.     capacity = capacity - 1. M5 k* V% X1 v
  2.     for i in range(n - 1, 0, -1):
    . X3 O+ m  p4 S- T7 {
  3.         if (m[i][capacity] == m[i - 1][capacity]):
    - l/ N+ m7 f\" h
  4.             x[i] = 0) w5 ^7 ]4 A% p8 K# O
  5.         else:
    6 V9 Y4 q/ x9 T: D3 @% `) w/ h) g  x
  6.             x[i] = 1) ~7 ]$ f1 ^% ^\" f% p$ ~
  7.             capacity -= w[i]
    , ]( {$ F# J: H8 P5 [: R
  8.     x[0] = 1 if (m[1][capacity] > 0) else 0
复制代码
在这一部分,代码反向遍历动态规划表,从最后一行向前找到解的路径。如果 m[capacity] 等于 m[i-1][capacity],表示第 i 个物品没有放入背包,否则放入背包,并更新剩余容量 capacity。
  1.     weight = 0, \$ {6 ~# P\" s, z2 X
  2.     value = 0
    , T2 R/ b: D9 F$ t* n
  3.     print('装载的物品编号为:')2 i) e5 @* [0 d( _
  4.     for i in range(len(x)):
    ! {' h  V( N* y
  5.         if (x[i] == 1):$ F2 [/ g9 c1 V% G
  6.             weight = weight + w[i]
    / A2 j- X6 S' e( r) C, K
  7.             value = value + v[i]
    \" I3 L& g. L$ F+ V. S$ s
  8.             print(' ', i + 1)\" E9 P& Y: t2 V5 X3 k9 X7 m
  9.     print('装载的物品重量为:')
    / k& H! H$ L2 r; X. E; ~; D4 r2 s
  10.     print(weight): \& a5 q4 V) L, w' g; h8 @! }
  11.     print('装入的物品价值为:')
    6 b/ S6 M( ]* l) a) _& x
  12.     print(value)
    : b\" ^$ ~$ j. G9 Z% [7 ~) t# z
  13.     return m
复制代码
最后,代码计算了被选择的物品的总重量和总价值,并将它们打印出来。函数返回动态规划表 m。
' X' w7 ?2 m1 O5 A% S3 }/ h8 W这段代码实现了0-1背包问题的解决方法,它通过动态规划算法找到最优解,即在给定背包容量下可以获得的最大总价值,以及选择哪些物品放入背包。- R6 `2 o* h! f3 A# p* k/ o# F
+ X9 x4 H# b9 P; C
最后在函数的输入文件中,如下例,第一行物品数量为:5 背包载重量为:10物品的重量列表为:[2, 2, 6, 5, 4] 物品的价值列表为: [6, 3, 5, 4, 6]
6 D6 S' O2 Z# j7 U. Y1 R
VeryCapture_20231107110045.jpg
5 F0 E" P$ J* C1 ?4 U! R  R
  x/ K  h) `% V  N) |$ \
接下来展示我们的输出结果:

/ B* ]; Z# U5 {5 J- V0 r
VeryCapture_20231107110508.jpg
3 \" O  |7 E9 ~* F# [
3 |  M7 J6 C! [

# {0 C6 \1 q7 I4 B) U( ]9 g* D
具体代码如下:
+ ]& j/ c1 \* i0 J/ e% P9 [
' D' n+ H: j8 _  x* E

) {) u- m7 h& p3 b; d; O# I2 i8 u
! B9 s- `& T6 c& q4 `% F' s4 G

* R% |. M6 `9 V9 }" b2 V- s( v: Z, [6 H% `

基础0-1背包问题(动态规划).rar

3.58 KB, 下载次数: 0, 下载积分: 体力 -2 点

售价: 2 点体力  [记录]  [购买]

zan
转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
您需要登录后才可以回帖 登录 | 注册地址

qq
收缩
  • 电话咨询

  • 04714969085
fastpost

关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

手机版|Archiver| |繁體中文 手机客户端  

蒙公网安备 15010502000194号

Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

GMT+8, 2026-7-10 15:10 , Processed in 0.679829 second(s), 55 queries .

回顶部