分枝定界法解0/1背包问题

分枝定界法解0/1背包问题

关键词:分支定界、0-1背包

分枝定界法简介

分枝定界法按照树形结构来组织解空间,展开节点后,有两种策略:

策略一、把节点加入 FIFO 队列当中;

策略二、把节点加入到堆中,按照最小消耗或者最大消耗来选择下一个展开节点

感悟

分枝定界法是一类能确保搜索到全部可行解的解空间的一类方法。得到全部的解以后,再由后续程序自行觉得。

分枝定界法与回溯法的区别

分枝定界法 回溯法
搜索解空间的方法是 BFS(广度优先) 搜索解空间的方法是 DFS(深度优先)
算法搜索的解空间大,消耗的内存多 算法搜索的解空间大,消耗的内存少

0/1背包问题

有背包问题形式化描述如下:

n=3weights=[20,15,15]values=[40,25,25]constraint=30

用分枝定界法,代码实现如下:

# -*- coding:utf8 -*-
import copy
from collections import deque


# 用分枝定界法解决0/1背包问题
def brunch_bound(w, p, c):
    plan = list()
    buffer = deque([[copy.copy(w), [], []]])  # [waiting, explored, values]
    while len(buffer):
        cur = buffer.popleft()
        for i in range(0, len(cur[0])):
            weight = cur[0][i]
            n = copy.deepcopy(cur)
            n[0].remove(weight)
            n[1].append(weight)
            n[2].append(p[i])
            if sum(n[1]) > c:
                continue  # overloaded
            buffer.append(copy.deepcopy(n))
        plan.append(cur)
    return plan


if __name__ == '__main__':
    w = [20, 15, 15]
    p = [40, 25, 25]
    c = 30

    plan = brunch_bound(w,p,c)

    l = sorted(plan, key=lambda x:sum(x[2]), reverse=True)  # l[0] is the most value plan
    for e in l:
        print(e)

输出:

[[20], [15, 15], [25, 25]]  #显然,这是最优方案
[[20], [15, 15], [25, 25]]
[[15, 15], [20], [40]]
[[20, 15], [15], [25]]
[[20, 15], [15], [25]]
[[20, 15, 15], [], []]

解释

copy.copy 是浅拷贝,子对象不会被拷贝

copy.deepcopy 是深拷贝

posted @   健康平安快乐  阅读(964)  评论(2编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示