python 回溯法 子集树模板 系列 —— 3、0-1背包问题

简介: 问题给定N个物品和一个背包。物品i的重量是Wi,其价值位Vi ,背包的容量为C。问应该如何选择装入背包的物品,使得放入背包的物品的总价值为最大?分析显然,放入背包的物品,是N个物品的所有子集的其中之一。

问题

给定N个物品和一个背包。物品i的重量是Wi,其价值位Vi ,背包的容量为C。问应该如何选择装入背包的物品,使得放入背包的物品的总价值为最大?

分析

显然,放入背包的物品,是N个物品的所有子集的其中之一。N个物品中每一个物品,都有选择不选择两种状态。因此,只需要对每一个物品的这两种状态进行遍历。

解是一个长度固定的N元0,1数组。

套用回溯法子集树模板,做起来不要太爽!!!

代码

'''0-1背包问题'''

n = 3            # 物品数量
c = 30           # 包的载重量
w = [20, 15, 15] # 物品重量
v = [45, 25, 25] # 物品价值

maxw = 0  # 合条件的能装载的最大重量
maxv = 0  # 合条件的能装载的最大价值
bag = [0,0,0] # 一个解(n元0-1数组)长度固定为n
bags = []     # 一组解
bestbag = None # 最佳解


# 冲突检测
def conflict(k):
    global bag, w, c
    
    # bag内的前k个物品已超重,则冲突
    if sum([y[0] for y in filter(lambda x:x[1]==1, zip(w[:k+1], bag[:k+1]))]) > c:
        return True
    
    return False


# 套用子集树模板
def backpack(k): # 到达第k个物品
    global bag, maxv, maxw, bestbag
    
    if k==n: # 超出最后一个物品,判断结果是否最优
        cv = get_a_pack_value(bag)
        cw = get_a_pack_weight(bag)
        
        if cv > maxv : # 价值大的优先
            maxv = cv
            bestbag = bag[:]
            
        if cv == maxv and cw < maxw: # 价值相同,重量轻的优先
            maxw = cw
            bestbag = bag[:]
    else:
        for i in [1,0]: # 遍历两种状态 [选取1, 不选取0] 
            bag[k] = i  # 因为解的长度是固定的
            if not conflict(k): # 剪枝
                backpack(k+1)


# 根据一个解bag,计算重量
def get_a_pack_weight(bag):
    global w
    
    return sum([y[0] for y in filter(lambda x:x[1]==1, zip(w, bag))])
    
    
# 根据一个解bag,计算价值
def get_a_pack_value(bag):
    global v
    
    return sum([y[0] for y in filter(lambda x:x[1]==1, zip(v, bag))])
    
    
# 测试
backpack(0)
print(bestbag, get_a_pack_value(bestbag))

效果图

img_46d23876aff7049a31713f01c72e2df3.jpg

目录
相关文章
|
Python
python 回溯法 记录
一直不是太理解回溯法,这几天集中学习了一下,记录如下。 回溯法有“通用的解题法”之称。 1.定义:  也叫试探法,它是一种系统地搜索问题的解的方法。 2.基本思想:  从一条路往前走,能进则进,不能进则退回来,换一条路再试。
3243 0
|
8月前
|
数据采集 机器学习/深度学习 人工智能
Python:现代编程的首选语言
Python:现代编程的首选语言
1407 102
|
8月前
|
数据采集 机器学习/深度学习 算法框架/工具
Python:现代编程的瑞士军刀
Python:现代编程的瑞士军刀
478 104
|
8月前
|
人工智能 自然语言处理 算法框架/工具
Python:现代编程的首选语言
Python:现代编程的首选语言
371 103
|
8月前
|
机器学习/深度学习 人工智能 数据挖掘
Python:现代编程的首选语言
Python:现代编程的首选语言
392 82
|
7月前
|
Python
Python编程:运算符详解
本文全面详解Python各类运算符,涵盖算术、比较、逻辑、赋值、位、身份、成员运算符及优先级规则,结合实例代码与运行结果,助你深入掌握Python运算符的使用方法与应用场景。
486 3
|
7月前
|
数据处理 Python
Python编程:类型转换与输入输出
本教程介绍Python中输入输出与类型转换的基础知识,涵盖input()和print()的使用,int()、float()等类型转换方法,并通过综合示例演示数据处理、错误处理及格式化输出,助你掌握核心编程技能。
710 3
|
7月前
|
并行计算 安全 计算机视觉
Python多进程编程:用multiprocessing突破GIL限制
Python中GIL限制多线程性能,尤其在CPU密集型任务中。`multiprocessing`模块通过创建独立进程,绕过GIL,实现真正的并行计算。它支持进程池、队列、管道、共享内存和同步机制,适用于科学计算、图像处理等场景。相比多线程,多进程更适合利用多核优势,虽有较高内存开销,但能显著提升性能。合理使用进程池与通信机制,可最大化效率。
516 3
|
7月前
|
Java 调度 数据库
Python threading模块:多线程编程的实战指南
本文深入讲解Python多线程编程,涵盖threading模块的核心用法:线程创建、生命周期、同步机制(锁、信号量、条件变量)、线程通信(队列)、守护线程与线程池应用。结合实战案例,如多线程下载器,帮助开发者提升程序并发性能,适用于I/O密集型任务处理。
728 0