1.问题描述

有一个容量为V的背包,还有n个物体。现在忽略物体实际几何形状,我们认为只要背包的剩余容量大于等于物体体积,那就可以装进背包里。每个物体都有两个属性,即体积w和价值v。使物品装入背包的价值最大。

        2.解决思路与分析

I.枚举法,首先想到最简单的枚举法,通过列举所有结果,从中筛选出满足题意的结果。

II.回溯法,在枚举法的基础上进行约束剪枝和限界剪枝。

III.动态规划,运用动态规划思想,动态规划与分治法类似,都是把大问题拆分成小问题,通过寻找大问题与小问题的递推关系,使用递归和递推算法解决一个个小问题,最终达到解决原问题的效果。

如果装不下当前物品,那么前n个物品的最佳组合和前n-1个物品的最佳组合是一样的。

如果装得下当前物品。
假设1 :装当前物品,在给当前物品预留了相应空间的情况下,前n-1个物品的最佳组合加上当前物品的价值就是总价值。
假设2:不装当前物品,那么前n个物品的最佳组合和前n-1个物品的最佳组合是一样
选取假设1和假设2中较大的价值,为当前最佳组合的价值。

枚举法代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
const int N=10;//全局变量,物品数量
const int bag=N;//全局变量,背包承重量
int max_value=0;//全局变量,记录能获得的最大价值
int backpack(int a[],int v[],int w[],int n,int t)
{int max_v=0,max_w=0;//背包累积的最大价值和最大重量 if(t>n-1)//递归结束的条件 {printf("找到一个方案");for(int i=0;i<n;i++){//遍历数组a根据其记录的0、1值进行背包价值和重量计算printf("%d",a[i]);max_v=max_v+v[i]*a[i];max_w=max_w+w[i]*a[i];}if(max_w>bag)//根据max_w判断该方案是否超重printf("\n该方案总价%d,总重%d,超重!不可行!!!\n",max_v,max_w);else{//如果不超重if(max_v>max_value)//比较该方案所获得的价值是不是比全局最优解更优max_value=max_v;//更新最优解printf("\n该方案总价%d,总重%d,可行\n",max_v,max_w);}}else{for(int i=1;i>=0;i--)//只取值1或0 {a[t]=i;//记录当前物品选1或不选0backpack(a,v,w,n,t+1);//递归到下一层}}return max_value;//返回最大价值
}
int main()
{int a[N],v[N],w[N],i,start,end;printf("背包最大承重%d公斤\n",bag);for(i=0;i<N;i++)//随机生成价值和重量{v[i]=rand()%5+1;w[i]=rand()%5+1;printf("物品%d,价值%d,重量%d\n",i,v[i],w[i]);}start=clock();printf("能获得的最大价值为:%d\n",backpack(a,v,w,N,0));end=clock();printf("耗时:%dms\n",end-start);return 0;
}

回溯法代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
const int N=10;//全局变量,物品数量
const int bag=N;//全局变量,背包承重量
int max_value=0;//全局变量,记录能获得的最大价值
int count=0;//全局变量,用于记录到达叶节点的次数
int a[N],v[N],w[N],r[N+1];//全局变量,分别保存0-1方案,物品价值,物品重量,剩余总价值
int backpack(int t,int now_v,int now_w)
{//t表示递归层数,now_v表示当前层所累积的价值,now_w表示当前层所累积的重量int i;if(t>N-1)//当递归到达叶子节点时{printf("找到一个方案");for(i=0;i<N;i++){printf("%d",a[i]);}if(now_w>bag)//判断方案是否超重{printf("\n该方案总价%d,总重%d,超重!不可行!!!\n",now_v,now_w);}else//如果不超重{if(now_v>max_value)//判断该方案所获得的价值是不是更优{max_value=now_v;//更新最优解}printf("\n该方案总价%d,总重%d,可行\n",now_v,now_w);}count++;}else{for(i=0;i<=1;i++){a[t]=i;//记录当前物品选或不选now_v=now_v+v[t]*i;//根据0-1值累加价值now_w=now_w+w[t]*i;//根据0-1值累加重量if(now_w<=bag&&now_v+r[t+1]>max_value) // (限件减枝 约束减枝)backpack(t+1,now_v,now_w);//递归到下一层}}return max_value;//返回最大价值
}
int main()
{int i,start,end;printf("背包最大承重%d公斤\n",bag);for(i=0;i<N;i++)//随机生成价值和重量范围1-5{v[i]=rand()%5+1;w[i]=rand()%5+1;printf("物品%d,价值%d,重量%d\n",i,v[i],w[i]);}r[N]=0;for(i=N-1;i>=0;i--)//计算所有情况下剩余物品的总价值(约束减枝){r[i]=r[i+1]+v[i];}start=clock();printf("能获得的最大价值为:%d\n",backpack(0,0,0));end=clock();printf("检查方案%d个,",count);printf("耗时:%dms\n",end-start);return 0;
}

动态规划代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
const int N=1000;//全局变量,物品数量
const int bag=N;//全局变量,背包承重量
int max_value=0;//全局变量,记录能获得的最大价值
int a[N],v[N],w[N],r[N+1];//全局变量,分别保存0-1方案,物品价值,物品重量,剩余总价值
int dp[N][bag+1]={0},fa[N]={0};
int max(int a,int b);
void Find(int N,int bag);
int backpack()
{for(int i=1;i<N;i++){    for(int j=1;j<=bag;j++){if(w[i]>j)dp[i][j]=dp[i-1][j];elsedp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);}}return dp[N-1][bag];//返回最大价值
}
void Find(int i,int j)
{if(i==0){for(int i=0;i<N;i++)printf("%d",fa[i]);}if(dp[i][j]==dp[i-1][j]){fa[i]=0;Find(i-1,j);}else if(dp[i][j]==dp[i-1][j-w[i]]+v[i]){fa[i]=1;Find(i-1,j-w[i]);}}
int main()
{int i,start,end;printf("背包最大承重%d公斤\n",bag);for(i=0;i<N;i++)//随机生成价值和重量范围1-5{v[i]=rand()%5+1;w[i]=rand()%5+1;printf("物品%d,价值%d,重量%d\n",i,v[i],w[i]);}r[N]=0;start=clock();printf("能获得的最大价值为:%d\n",backpack());end=clock();Find(N-1,bag-1);printf("耗时:%dms\n",end-start);return 0;
}
int max(int a,int b)
{
if(a>b) return a;
else return b;
}

0-1背包问题的多种算法求解(C语言)相关推荐

  1. 贪心算法 背包问题 java_贪心算法求解背包问题

    一.贪心算法 1.贪心算法概念 贪婪算法(Greedy algorithm)是一种对某些求最优解问题的更简单.更迅速的设计技术.用贪婪法设计算法的特点是一步一步地进行,常以当前情况为基础根据某个优化测 ...

  2. TSP问题-多种算法求解

    目录 前言 问题及思路 1.问题概述 2.设计思路 源码及测试 1.输入 2.代码 前言 算法大作业,综合应用8种算法解决TSP问题,分别是: 蛮力法(顺序查找) 分治法(快速排序) 贪心法(求上界) ...

  3. 线性规划问题的单纯形算法求解

    关于线性规划问题是什么已经有很多人早就说明过了,我也小抄一波给大家预热预热,线性规划问题是运筹学中研究较早.发展较快.应用广泛.方法较成熟的一个重要分支,它是辅助人们进行科学管理的一种数学方法. 在一 ...

  4. 动态规划算法据序偶原理求解0/1背包问题(C++实现)

    可程序根据序偶原理,应用动态规划算法求解. Code   1//说明:本程序有一定代码冗余,若分割为多个函数的形式会使程序简洁明了.   2#include <iostream>   3u ...

  5. 0/1背包问题-----回溯法求解

    问题描述 有n个物品和一个容量为c的背包,从n个物品中选取装包的物品.物品i的重量为w[i],价值为p[i].一个可行的背包装载是指,装包的物品总重量不超过背包的重量.一个最佳背包装载是指,物品总价值 ...

  6. 背包问题贪心算法求解

    题目 有一个背包,背包容量是M=150.有7个物品,物品可以分割成任意大小. 要求尽可能让装入背包中的物品总价值最大,但不能超过总容量. 思路 具有最优子结构性质和贪心选择性质.只要是所有物品的总重量 ...

  7. 贪心算法 背包问题代码 c语言,用贪心算法求解普通背包问题的C++代码

    用贪心算法求解普通背包问题的C++代码 2019年3月6日 125次阅读 来源: 贪心算法 #include #define  M  100 void display(int &n,doubl ...

  8. 算法设计与分析实验二:动态规划法实现TSP问题和0/1背包问题

    [实验目的] 1.熟练掌握动态规划思想及教材中相关经典算法. 2.使用动态规划法编程,求解0/1背包问题和TSP问题. TSP问题 一.实验内容: TSP问题是指旅行家要旅行n个城市,要求每个城市经历 ...

  9. 用滚动数组求解0/1背包问题

    用滚动数组求解0/1背包问题(此处仅求装入背包的最大价值) // 由于第i个阶段(考虑物品i)的解dp[i][ * ]只与第i-1个阶段(考虑物品i-1)的解dp[i-1][ * ]有关,这种情况下保 ...

最新文章

  1. 阿里云、浙江大学成立“智云实验室” 打造中国高校数字化样本
  2. 难点电路详解之负反馈放大器电路(1)
  3. mac shell命令连接mongo
  4. 为什么借钱要上央行征信?
  5. ArcGIS升级地理数据库
  6. python特征匹配 查找_特征匹配+单纯形查找对象
  7. mysql 视图sql_SQL的视图
  8. MyBatis直接执行SQL查询及批量插入数据
  9. matplotlib图表显示中文三种办法
  10. eclipse-java-2018-09-win32-x86_64配置tomcat(内含更新eclipse,如何解决添加时找不到最新tomcat版本)...
  11. Yii 2.0.3 Advanced版控制器不能包含大写字母的Bug
  12. Java下载及环境配置
  13. 全国计算机等级考试二级Web程序设计考试大纲(2018年版)
  14. 【禁止套娃】用PPSSPP模拟PSP模拟Neogeo模拟SNK拳皇97
  15. Java - Timestamp cannot be cast to String
  16. 狼人杀游戏 数据库设计
  17. 【网络】抓包tcpdump
  18. 噩梦射手 安装包资源包提供下载 Unity官方教程 Survival Shooter 资源已经失效了!? Unity3D休闲射击类游戏《Survival Shooter》完整源码
  19. 魔百盒CM311-1a免拆机卡刷固件加+刷armbian装docker运行青龙面板
  20. [Python3] 008 列表内涵,“满腹经纶”

热门文章

  1. 2023第十三届中国数字营销与电商创新峰会
  2. WPF九宫格图片自定义皮肤(新博速读2.0)
  3. 锡兰肉桂与决明子肉桂——不是所有的肉桂都一样
  4. 【Qt图书管理系统】4.完整版源码及下载地址
  5. 对“师德”的一点体会
  6. 树莓派 | 串口01 - 在系统上修改串口的映射关系
  7. java程序设计基础_陈国君版第五版_第三章习题
  8. 8图教你如何配置 SNMP
  9. 基于大数据平台的毕业设计01:基于Docker的HDP集群搭建
  10. 《机器视觉算法与应用》第3章 机器视觉算法之相机标定——学习笔记