动态规划--C#求解01背包
2018-01-01 22:34
148 查看
背包问题(Knapsack problem)是一种组合优化的NP完全问题。
给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。
应用:
背包问题出现在各种领域的现实世界的决策过程中,例如寻找最少浪费的方式来削减原材料, 选择投资和投资组合,选择资产支持资产证券化 ,和生成密钥为Merkle-Hellman 和其他背包密码系统
1,穷举法(把所有情况列出来,比较得到 总价值最大的情况):
求解思路:先不想其他的,求最高价格,那么对于每种物体来说,都有两种状态,要么装进背包,要么不装,有n种物品,就会是n的2次方种,装背包的方式,(如果容量增大,物品增多,这个方法的运行时间将成指数增长),我用二进制的01的形式表示物品是否在背包中,代码如下:
动态规划算法
我们要求得i个物体放入容量为m(kg)的背包的最大价值(记为 c[i,m])。在选择物品的时候,对于每种物品i只有两种选择,即装入背包或不装入背包。某种物品不能装入多次(可以认为每种物品只有一个),因此该问题被称为0-1背包问题
对于c[i,m]有下面几种情况:
c[i,0]=c[0,m]=0
当w[i]>m 时 c[i,m]=c[i-1,m] 最后一个物品的重量大于容量,直接舍弃不用)
当w[i]<=m的时候有两种情况,一种是放入i,一种是不放入i
a, 不放入i c[i,m]=c[i-1,m]
b, 放入i c[i,m]=c[i-1,m-w[i]]+p[i]
上面a,b做比较,取得较大的值记录: c[i,m]=max(不放入i,放入i)
递归解决01背包:
动态规划算法:::
给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。
应用:
背包问题出现在各种领域的现实世界的决策过程中,例如寻找最少浪费的方式来削减原材料, 选择投资和投资组合,选择资产支持资产证券化 ,和生成密钥为Merkle-Hellman 和其他背包密码系统
1,穷举法(把所有情况列出来,比较得到 总价值最大的情况):
求解思路:先不想其他的,求最高价格,那么对于每种物体来说,都有两种状态,要么装进背包,要么不装,有n种物品,就会是n的2次方种,装背包的方式,(如果容量增大,物品增多,这个方法的运行时间将成指数增长),我用二进制的01的形式表示物品是否在背包中,代码如下:
using System; namespace _4_2_1动态规划_01背包_穷举 { class Program { static void Main(string[] args) { //包的最大容纳量 ; int m = 10; //物品重量 int[] weight = {0, 3, 4, 5 }; //和上面所对应物品的价值 int[] value = { 0, 4, 5, 6 }; //输出的结果是11 Console.WriteLine(Exhausttiity(m,weight,value)); Console.ReadKey(); } public static int Exhausttiity(int m,int[] w,int[] p) { int num = w.Length - 1; //物品的个数 int maxPrice = 0; //物品最大价值 for (int i = 0; i < Math.Pow(2,m); i++) { //取得i上第一个位置上的二进制值 int weihght = 0; int price = 0; for (int j = 1; j <= num; j++) { int result = Get2(i, j); if(result == 1) { weihght += w[j]; price += p[j]; } } if(weihght <= m && price > maxPrice) { maxPrice = price; } } return maxPrice; } //取得i上number位 上的二进制值,是1还是0 public static int Get2(int i,int number) { int A = i; int B = (int)Math.Pow(2, number - 1); //二进制的与运算 int result = A & B; if (result == 0) { return 0; }else{ return 1; } } } }
动态规划算法
我们要求得i个物体放入容量为m(kg)的背包的最大价值(记为 c[i,m])。在选择物品的时候,对于每种物品i只有两种选择,即装入背包或不装入背包。某种物品不能装入多次(可以认为每种物品只有一个),因此该问题被称为0-1背包问题
对于c[i,m]有下面几种情况:
c[i,0]=c[0,m]=0
当w[i]>m 时 c[i,m]=c[i-1,m] 最后一个物品的重量大于容量,直接舍弃不用)
当w[i]<=m的时候有两种情况,一种是放入i,一种是不放入i
a, 不放入i c[i,m]=c[i-1,m]
b, 放入i c[i,m]=c[i-1,m-w[i]]+p[i]
上面a,b做比较,取得较大的值记录: c[i,m]=max(不放入i,放入i)
递归解决01背包:
using System; namespace _4_2_3动态规划_01背包_递归优化 { class Program { //11 是 最大可拿的方案有12种,4 是 最大可拿物品的个数 public static int[,] result = new int[11,4]; static void Main(string[] args) { //包的最大容纳量 int m = 10; //物品重量 int[] weight = { 0, 3, 4, 5 }; //和上面所对应物品的价值 int[] value = { 0, 4, 5, 6 }; Console.WriteLine(UpDown(m, 3, weight, value)); Console.ReadKey(); } //m是背包容量,i是物品个数,wp是物品的重量和价值数组 public static int UpDown(int m, int i, int[] w, int[] p) { //物品个数为0或者背包容量为0时,最大利润为0 if (i == 0 || m == 0) { return 0; } //若不为0则表示求解过 if (result[m,i] != 0) { return result[m, i]; } if (w[i] > m) { result[m,i] = UpDown(m, i - 1, w, p); return result[m, i]; } else { int maxValue1 = UpDown(m - w[i], i - 1, w, p) + p[i]; int maxValue2 = UpDown(m, i - 1, w, p); if (maxValue1 > maxValue2) { result[m, i] = maxValue1; } else { result[m, i] = maxValue2; } return result[m, i]; } } } }
动态规划算法:::
using System; namespace _4_2_3动态规划_01背包_自底向上法 { class Program { //足够大 public static int[,] result = new int[11, 4]; static void Main(string[] args) { //包的最大容纳量 int m = 10; //物品重量 int[] weight = { 0, 3, 4, 5 }; //和上面所对应物品的价值 int[] value = { 0, 4, 5, 6 }; Console.WriteLine(BottomUp(m, 3, weight, value)); Console.ReadKey(); } public static int BottomUp(int m,int i, int[] w,int[] p) { for (int a = 1; a <= m; a++) { //已经求出最大价值 if (result[m,i] != 0) { return result[m, i]; } for (int b = 1; b <= i; b++) { if (result[a, b] != 0) continue; if (w[b] > a) { result[a, b] = result[a, b - 1]; } else { //放入i int maxValue1 = result[a-w[b],b-1] + p[b]; //不放入i int maxValue2 = result[a, b - 1]; if (maxValue1>maxValue2) { result[a, b] = maxValue1; } else { result[a, b] = maxValue2; } } } } return result[m, i]; } } }
相关文章推荐
- 动态规划求解01背包相关的基本问题
- 蓝桥杯 ALGO-30算法训练 入学考试(01背包,动态规划)
- 夕拾算法进阶篇:18)装箱问题 (01背包_动态规划DP)
- 数据结构(C#)--利用动态规划解决0-1背包问题
- 动态规划:01背包问题的浅谈
- 01背包问题 动态规划 c语言实现
- 01背包基础详解(附求解选择的物品)
- 蓝桥杯 ALGO-31算法训练 开心的金明(01背包,动态规划)
- (1)01背包问题____动态规划
- 物件捆绑 背包问题 动态规划 求解
- 动态规划求解0-1背包
- 动态规划求解背包问题(java版本)
- POJ3624 - Charm Bracelet - 动态规划之01背包
- 0-1背包问题,动态规划求解
- 动态规划(0-1背包问题)---C#版
- NYOJ - 49 - 开心的小明(01背包变形+动态规划)
- 动态规划之01背包详解【解题报告】
- [算法与数据结构] - No.12 动态规划之01背包以及01背包一维数组优化
- Uva-562 Dividing coins (转换成01背包求解)
- 用动态规划求解0-1背包问题