首页 > 其他分享 >蛮力法 解决0/1背包问题

蛮力法 解决0/1背包问题

时间:2024-05-25 19:12:32浏览次数:7  
标签:arr 背包 int len 物品 depth 蛮力 key 解决

实验项目1 蛮力法

实验题目 使用蛮力法解决0/1背包问题。

问题描述:给定n个重量(weight)为{w1, w2, … ,wn}价值(key)为{v1, v2, … ,vn}的物品和一个容量为C(contain)的背包,求这些物品中的一个最有价值的子集,且要能够装到背包中。
eg:示例:
背包容量C=15kg
物品1:重量2kg,价值2$
物品2:重量12kg,价值4$
物品3:重量1kg,价值2$
物品4:重量1kg,价值1$
物品5:重量4kg,价值10$

img

实验目的

  1. 理解算法的时间复杂度;
  2. 熟练设计和生成问题的解空间:设计一种穷举策略将物品装入背包的各种装法都找出来,并能够在计算机中存储和表示。
  3. 理解蛮力法的局限性;
  4. 实验要求
  5. 掌握用递归或循环生成n个元素的全部子集的算法设计方法;

按上图示例数据求解出问题的一个最优解:装入哪几个物品价值最大,总重量和总价值各是多少?

蛮力法的主要框架

// 辅助数组,防止递归死循环
int visited[5] = { 0 };
// w容量,key价值,len:weight数组长度 depth 深度
void backpack(int w, int* weight, int* key, int len, int depth, int tempSum) {
    // 如果到达物品数组的末尾 地柜出口
    if (depth == len) {
        return;
    }
    // 不选择当前物品
    visited[depth] = 0;
    backpack(w, weight, key, len, depth + 1, tempSum);
    // 如果能选择当前物品(背包容量足够)
    visited[depth] = 1; // 选择当前物品
    backpack(w - arr[depth], weight, key, len, depth + 1, tempSum + key[depth]); // 递归调用
}

不难看出使用的是递归的方式

算法代码

#include<stdio.h>

// 辅助数组,防止递归死循环
int visited[5] = { 0 };
// 寻找最大值
int sumMax = 0;
//
int weightSum = 0;
// 寻找最大值对应装填方式
int method[5] = { 0 };
int capacity = 15; // 背包容量
int count = 0;
//判断容量是否合理
int LessCapacity(int len,const int* arr){
    int sumWeight = 0;
    for (int i = 0; i < len; ++i) {
        if(visited[i] == 1)
        sumWeight += arr[i];
    }
//    满足小于等于15 为 1
    return sumWeight<=capacity ? 1:0;
}
// 遍历当前状态,更新最大价值和装填方式
void Traverse(int* arr,  int len, int tempSum, int depth) {
    printf("--------------------------------------------\n");
    int weight = 0;
    // 打印当前状态
    printf("重量: ");
    for (int i = 0; i < len; ++i) {
        printf("%d  ", arr[i]);
    }
    printf("\n");
    printf("选择: ");
    for (int i = 0; i < len; i++) {
        printf("%d  ", visited[i]);
        if(visited[i]){
            weight+=arr[i];
        }
    }
    printf("\n");
    printf("当前总重量: %d\n", weight);
    printf("当前总价值: %d\n", tempSum);
    if(weight>capacity){
        printf("该情况不符合要求!\n");
    }else{
        printf("该情况符合要求!\n");
    }
    printf("--------------------------------------------\n\n");
    // 如果当前价值大于已知的最大价值,则更新最大价值和method数组
    if (tempSum > sumMax && LessCapacity(len,arr)) {
        sumMax = tempSum;
//        更新选择方法
        for (int i = 0; i < len; i++) {
            method[i] = visited[i];
        }
    }

}

// 背包问题的递归函数
void backpack(int w, int* arr, int* key, int len, int depth, int tempSum) {
    // 如果到达物品数组的末尾或背包容量已满,则遍历当前状态
    if (depth == len) {
        count++;
        Traverse(arr, len, tempSum, depth);
        return;
    }
    // 不选择当前物品
    visited[depth] = 0;
    backpack(w, arr, key, len, depth + 1, tempSum);

    // 如果能选择当前物品(背包容量足够)
    visited[depth] = 1; // 选择当前物品
    backpack(w - arr[depth], arr, key, len, depth + 1, tempSum + key[depth]); // 递归调用
}
// 判断重量<=15

int main() {
    // 重量
    int weight[] = { 2, 12, 1, 1, 4 };
    // 重量对应的价值
    int key[] = { 2, 4, 2, 1, 10 };

    backpack(capacity, weight, key, 5, 0, 0); // 调用背包问题的递归函数

    printf("----------------------------------分隔符----------------------------------\n");
    printf("总共有%d种情况\n",count);
    printf("重量: ");
    for (int i = 0; i < sizeof(weight)/sizeof (int); ++i) {
        printf("%d  ", weight[i]);
    }
    printf("\n");
    printf("选择: ");
    for (int i = 0; i < sizeof(weight)/sizeof (int); i++) {
        printf("%d  ", method[i]);
        if(method[i] == 1){
            weightSum+=weight[i];
        }
    }
    printf("\n 最终重量:%d",weightSum);
    printf("\n 最终最优金额:%d",sumMax);
    return 0;
}

标签:arr,背包,int,len,物品,depth,蛮力,key,解决
From: https://www.cnblogs.com/cwyYYDS/p/18212880

相关文章

  • 面试题剖析:Netty编解码如何解决拆包沾包问题?
    今天我们要聊的主题是Netty的编解码机制,特别是如何解决TCP的拆包和沾包问题。如果你曾在处理网络数据传输时遇到数据包混乱的情况,那么你已经体验过拆包和沾包的“乐趣”了。别担心,Netty提供了一系列强大的解码器,帮助我们轻松应对这些问题。本文将详细介绍这些解码器的工作原......
  • 大模型最新黑书:大模型应用解决方案: 基于GPT-3、ChatGPT、GPT-4等Transformer架构的自
    今天给大家推荐一本丹尼斯·罗斯曼(DenisRothman)编写的关于大语言模型(LLM)权威教程<<大模型应用解决方案>基于GPT-3、ChatGPT、GPT-4等Transformer架构的自然语言处理>!Google工程总监AntonioGulli作序,这含金量不用多说,在这里给大家强烈推荐一下这本黑书,下面直接开始介绍!......
  • Xfce4桌面背景和桌面图标消失问题解决@FreeBSD
    问题:Xfce4桌面背景和桌面图标消失以前碰到过好几次桌面背景和桌面图标消失,整个桌面除了上面一条和下面中间的工具条,其它地方全是黑色的问题,但是这次重启之后也没有修复,整个桌面乌黑一片,啥都没有,用起来特别不得劲,于是开始修复。修复过程咨询文心,建议这样设置:检查壁纸设置:......
  • Content-Type 'application/json;charset=UTF-8' is not supported异常解决
    Content-Type'application/json;charset=UTF-8'isnotsupported异常解决前提:确定不是因为Content-Type导致的异常,controller层有注解@RequestBody。报错详情:确定不是因为缺少Jackson依赖或者版本过低:注意到报错信息上边有一条警告日志:.c.j.MappingJackson2HttpMessageCo......
  • pycharm找不到conda可执行文件解决办法
    解决办法1、第一种按照以下步骤,找到condabin文件下面,conda.bat文件,把路径给复制下来,粘贴到Conda可执行文件,即可。然后再点击加载环境,我这里是已经汉化了pycharm,如何汉化,可见其他文章。这样所创建的虚拟环境就可以用起来了。第二种解决办法 只需要在‘Conda......
  • Qt - Qt6中QTextStream类的setCodec方法没有了,怎么解决写中文文本乱码
    简介场景:程序在linux下运行,将中英文写入文本,将文本在windows上打开时,中文出现乱码 原Qt5中:QFilefile;file.open(QIODevice::WriteOnly|QIODevice::Text);QTextStreamtextStream(&file);textStream.setCodec("GBK");使用 QTextStream类的 setCodec方法即可解决上......
  • 抄表系统厂家:创新技术与解决方案的引领者
    1.技术创新:智能化抄表系统的兴起随着时代的发展,传统式手动抄水表方法已慢慢被智能化抄表系统所替代。抄表系统厂家在这一领域扮演了重要角色,她们产品研发智能抄表系统运用物联网技术、大数据和云计算等先进技术,完成了远程控制智能抄表,大大的提高了效率并降低了人为失误。这类......
  • 系统卡顿?Mac怎么清理缓存?轻松解决!
    我们日常使用Mac电脑的过程中,时常会遇到系统运行缓慢或卡顿的情况,这不仅影响工作效率,也大大降低了使用体验。那么,Mac运行缓慢的原因究竟是什么呢?事实上,原因有很多,包括硬盘空间不足、系统资源占用过高、启动项目过多等。其中,缓存文件积累过多是一个常被忽视,但实际上对系统性能影......
  • 前端 用账号密码登录的时候 对密码进行加密 【最佳解决方案】用bcrypt.js 或者 crypto
    1、在后台管理的项目中或者其他项目用到账号密码登录的功能,我们需要对密码进行一个密码的操作 2、我们可以使用第三方的库去实现登录密码加密的功能有两个JS库 bcrypt.js或者crypto-js3、方案一使用了bcrypt.js库对密码进行加密。首先,生成一个salt,它是一个随......
  • 关于怎样解决pycharm中编码格式的问题
            首先,需要清楚pycharm中它自行默认设置的格式是GBK或是UTF-8,而GBK解释器可能会因为文件的信息写入与读取而返回错误。        在PyCharm中修改编码格式可以通过以下步骤实现:打开需要修改编码格式的文件点击菜单栏中的File--->Settings(或者快捷......