当前位置: 首页 > news >正文

蛮力法0/1背包问题实验

实验项目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 为 1return 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]); // 递归调用
}
// 判断重量<=15int 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;
}

相关文章:

  • Python 渗透测试:Redis 数据库 弱密码测试.(6379端口)
  • python-数据分析与可视化基础
  • 已有yarn集群部署spark
  • hot100 -- 回溯(上)
  • 利用Python去除PDF水印
  • 前端基础入门三大核心之HTML篇:深入理解重绘与重排 —— 概念、区别与实战演练
  • vue 纵向滚动菜单, 点击滚动到选中菜单
  • 【项目托管git】本地项目托管到 Gitee
  • 机器学习-决策树算法
  • IDEA连接MySQL后如何管理数据库
  • JavaSE——类和对象(二)~~封装
  • 光耦合器的特性和应用概述
  • Mac电脑太卡了怎么办 Mac电脑常见问题 cleanmymacX有必要买吗
  • tensorflow下载
  • 编一个自己的万年历
  • [rust! #004] [译] Rust 的内置 Traits, 使用场景, 方式, 和原因
  • Android 架构优化~MVP 架构改造
  • CSS 专业技巧
  • Java 23种设计模式 之单例模式 7种实现方式
  • java第三方包学习之lombok
  • React Native移动开发实战-3-实现页面间的数据传递
  • React 快速上手 - 07 前端路由 react-router
  • vue自定义指令实现v-tap插件
  • Zepto.js源码学习之二
  • 测试如何在敏捷团队中工作?
  • 读懂package.json -- 依赖管理
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 巧用 TypeScript (一)
  • 如何抓住下一波零售风口?看RPA玩转零售自动化
  • 深度学习中的信息论知识详解
  • 原生js练习题---第五课
  • 源码之下无秘密 ── 做最好的 Netty 源码分析教程
  • HanLP分词命名实体提取详解
  • 如何用纯 CSS 创作一个货车 loader
  • ​如何使用ArcGIS Pro制作渐变河流效果
  • #{}和${}的区别?
  • #NOIP 2014# day.1 T3 飞扬的小鸟 bird
  • #stm32整理(一)flash读写
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • (07)Hive——窗口函数详解
  • (27)4.8 习题课
  • (4)通过调用hadoop的java api实现本地文件上传到hadoop文件系统上
  • (补充):java各种进制、原码、反码、补码和文本、图像、音频在计算机中的存储方式
  • (二)构建dubbo分布式平台-平台功能导图
  • (回溯) LeetCode 46. 全排列
  • (论文阅读23/100)Hierarchical Convolutional Features for Visual Tracking
  • (三)elasticsearch 源码之启动流程分析
  • (四)JPA - JQPL 实现增删改查
  • (一)u-boot-nand.bin的下载
  • (转)Android中使用ormlite实现持久化(一)--HelloOrmLite
  • .naturalWidth 和naturalHeight属性,
  • .NET C# 使用 iText 生成PDF
  • .NET Core工程编译事件$(TargetDir)变量为空引发的思考
  • .NET MVC 验证码
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter