问题说明:

假设有一个背包的负重最多可达8公斤,而希望在背包中装入负重范围内可得之总价物
品,假设是水果好了,水果的编号、单价与重量如下所示:
0
李子
4KG
NT$4500
1
苹果
5KG
NT$5700
2
橘子
2KG
NT$2250
3
草莓
1KG
NT$1100
解法背包问题是关于最佳化的问题,要解最佳化问题可以使用「动态规划」 (Dynamicprogramming) ,从空集合开始,每增加一个元素就先求出该阶段的最佳解,直到所有的元素加入至集合中,最后得到的就是最佳解。

下面我们看下代码:

  1. /*
  2. 问题:
  3. 假设有一个背包的负重最多可达8公斤,而希望在背包中装入负重范围内可得之总价物品
  4. 算法说明:
  5. 采用动态规划,在当前阶段求解出最好的解,如此反复
  6. 日期:2013/8/18
  7. 张威
  8. */
  9.  
  10. #include <iostream>
  11. #include <time.h>
  12. using namespace std;
  13.  
  14. #define MAXSIZE 8
  15.  
  16. //定义全局变量
  17. char name[][] = {"李子","苹果","橘子","草莓","甜瓜"};//水果名称
  18. int wight[] = {,,,,};//单个水果所占斤数
  19. int price[] = {,,,,};//单个水果的价值
  20. int perkg_price[];//每斤水果的价钱
  21. int perkg_num[] = {,,,,};
  22.  
  23. void GetNmae(int num)
  24. {
  25. for (int i = ;i <= ;i++)
  26. {
  27. cout<<name[num][i];
  28. }
  29. }
  30.  
  31. void GetBestAnswer(int currentwigh)
  32. {
  33. //判断递归终止条件
  34. if (currentwigh >= MAXSIZE)
  35. {
  36. cout<<"包裹已经满了,无法再装进东西"<<endl;
  37. }
  38. else
  39. {
  40. //check用来表证到底剩下来的物品里面还有没有能装进去背包里的
  41. bool check = true;
  42. int i = ;
  43. for (;i <= ;i++)
  44. {
  45. //若是没有进入到这个条件内,说明剩下来的物品的重量都超过了背包剩余重量,到此结束.否则i就代表当前所能选中的最优解
  46. if (wight[perkg_num[i]] <= MAXSIZE-currentwigh)
  47. {
  48. check = false;
  49. break;
  50. }
  51. }
  52. if (check == true)
  53. {
  54. cout<<"已经装不进去任何水果了"<<endl;
  55. }
  56. else
  57. {
  58. //得到最优解,并且将当前重量增加,进入下一次递归
  59. currentwigh += wight[perkg_num[i]];
  60. cout<<"购买了";
  61. GetNmae(perkg_num[i]);
  62. cout<<endl;
  63. GetBestAnswer(currentwigh);
  64. }
  65. }
  66. }
  67.  
  68. int main()
  69. {
  70. //计算出每斤水果的价钱,便于动态规划时求出当前最佳解
  71. for (int i = ;i <= ;i++)
  72. {
  73. perkg_price[i] = price[i] / wight[i];
  74. }
  75. //对perkg_num进行排序,同时保证单价和perkg_num之间的一一对应关系.即两个数组要同时变化
  76. //采用的是冒泡排序,在元素进行交换时perkg_num和perkg_price同时变化
  77. for (int i = ;i <= ;i++)
  78. {
  79. for (int j = i;j <= ;j++)
  80. {
  81. if (perkg_price[j] < perkg_price[j+])
  82. {
  83. int temp1 = perkg_price[j];
  84. int temp2 = perkg_num[j];
  85. perkg_price[j] = perkg_price[j+];
  86. perkg_price[j+] = temp1;
  87. perkg_num[j] = perkg_num[j+];
  88. perkg_num[j+] = temp2;
  89. }
  90. }
  91. }
  92. //开始计算求解
  93. GetBestAnswer();
  94. return ;
  95. }

背包问题

在这里,算法的主要思想有两个:1.通过冒泡排序得到一个单价表,并将物品的ID与之配对起来.这样我们在每次的递归中通过ID找到物品的相应属性,筛选出当前步骤的最优解出来

2.通过递归,传递当前的重量,得到还剩余的重量,根据前面的单价表,筛选出可选的最优解,然后将重量变化进入下一次递归.

这是最大空间为8的运行结果:                                              这是最大空间为29的运行结果:

下面附上指导书上面的代码:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define LIMIT 8
  4. // 重量限制
  5. #define N 5
  6. // 物品种类
  7. #define MIN 1
  8. // 最小重量
  9. struct body {
  10. char name[];
  11. int size;
  12. int price;
  13. };



  14.  
  15. valu
  16. e
  17.  
  18. item
  19.  
  20.  



  21.  
  22. valu
  23. e
  24.  
  25. item
  26.  
  27.  
  28. typedef struct body object;
  29. int main(void) {
  30. int item[LIMIT+] = {};
  31. int value[LIMIT+] = {};
  32. int newvalue, i, s, p;
  33. object a[] = {{"李子", , },
  34. {"苹果", , },
  35. {"橘子", , },
  36. {"草莓", , },
  37. {"甜瓜", , }};
  38. for(i = ; i < N;i++) {
  39. for(s = a[i].size; s <= LIMIT;s++) {
  40. p = s - a[i].size;
  41. newvalue = value[p] + a[i].price;
  42. if(newvalue > value[s]) {// 找到阶段最佳解
  43. value[s] = newvalue;
  44. item[s] = i;
  45. }
  46. }
  47. }
  48. printf("物品\t价格\n");
  49. for(i = LIMIT;i >= MIN;i = i - a[item[i]].size) {
  50. printf("%s\t%d\n",
  51. a[item[i]].name, a[item[i]].price);
  52. }
  53. printf("合计\t%d\n", value[LIMIT]);
  54. return ;
  55. }
  56. Java
  57. class Fruit {
  58. private String name;
  59. private int size;
  60. private int price;
  61. public Fruit(String name,int size, int price){
  62. this.name = name;
  63. this.size = size;
  64. this.price = price;
  65. }
  66. public String getName(){
  67. return name;
  68. }
  69. public int getPrice(){
  70. return price;
  71. }
  72. public int getSize() {
  73. return size;
  74. }
  75. }
  76. public class Knapsack {
  77. public static void main(String[] args){
  78. final int MAX = ;
  79. final int MIN = ;
  80. int[] item = new int[MAX+];
  81. int[] value = new int[MAX+];
  82. Fruit fruits[] = {
  83. new Fruit("李子", , ),
  84. new Fruit("苹果", , ),
  85. new Fruit("橘子", , ),
  86. new Fruit("草莓", , ),
  87. new Fruit("甜瓜", , )};
  88. for(int i = ; i < fruits.length;i++) {
  89. for(int s = fruits[i].getSize(); s <= MAX;s++){
  90. int p = s - fruits[i].getSize();
  91. int newvalue = value[p] +
  92. fruits[i].getPrice();
  93. if(newvalue > value[s]) {// 找到阶段最佳解
  94. value[s] = newvalue;
  95. item[s] = i;
  96. }
  97. }
  98. }
  99. System.out.println("物品\t价格");
  100. for(int i = MAX;
  101. i >= MIN;
  102. i = i - fruits[item[i]].getSize()) {
  103. System.out.println(fruits[item[i]].getName()+
  104. "\t" + fruits[item[i]].getPrice());
  105. }
  106. System.out.println("合计\t" + value[MAX]);
  107. }
  108. }

指导书上面的代码

我居然没想到使用结构体,失策失策,都没用什么高级点的数据结构,看起来貌似很复杂的样子.明天再看

背包问题(Knapsack problem)采用动态规划求解的更多相关文章

  1. 对背包问题(Knapsack Problem)的算法探究

    对背包问题(Knapsack Problem)的算法探究 至繁归于至简,这次自己仍然用尽可能易理解和阅读的解决方式. 1.问题说明: 假设有一个背包的负重最多可达8公斤,而希望在背包中装入负重范围内可 ...

  2. 【优化算法】变邻域搜索算法解决0-1背包问题(Knapsack Problem)代码实例 已

    01 前言 经过小编这几天冒着挂科的风险,日日修炼,终于赶在考试周中又给大家更新了一篇干货文章.关于用变邻域搜索解决0-1背包问题的代码.怎样,大家有没有很感动? 02 什么是0-1背包问题? 0-1 ...

  3. 动态规划-背包问题 Knapsack

    2018-03-15 13:11:12 背包问题(Knapsack problem)是一种组合优化的NP完全问题.问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何 ...

  4. knapsack problem 背包问题 贪婪算法GA

    knapsack problem 背包问题贪婪算法GA 给点n个物品,第j个物品的重量,价值,背包的容量为.应选哪些物品放入包内使物品总价值最大? 规划模型 max s.t. 贪婪算法(GA) 1.按 ...

  5. 动态规划法(四)0-1背包问题(0-1 Knapsack Problem)

      继续讲故事~~   转眼我们的主人公丁丁就要离开自己的家乡,去大城市见世面了.这天晚上,妈妈正在耐心地帮丁丁收拾行李.家里有个最大能承受20kg的袋子,可是妈妈却有很多东西想装袋子里,已知行李的编 ...

  6. 0-1背包问题——动态规划求解【Python】

    动态规划求解0-1背包问题: 问题:背包大小 w,物品个数 n,每个物品的重量与价值分别对应 w[i] 与 v[i],求放入背包中物品的总价值最大. 动态规划核心:计算并存储小问题的最优解,并将这些最 ...

  7. 0-1背包问题(0-1 knapsack problem)

    0-1背包问题描述:一个正在抢劫商店的小偷发现了n个商品,第i个商品价值 vi 美元,重 wi 磅,vi 和 wi 都是整数.这个小偷希望拿走价值尽量高的商品,但他的背包最多能容纳 S 磅重的商品,S ...

  8. FZU 2214 Knapsack problem 01背包变形

    题目链接:Knapsack problem 大意:给出T组测试数据,每组给出n个物品和最大容量w.然后依次给出n个物品的价值和体积. 问,最多能盛的物品价值和是多少? 思路:01背包变形,因为w太大, ...

  9. [DP] The 0-1 knapsack problem

    Give a dynamic-programming solution to the 0-1 knapsack problem that runs in O(nW) time, where n is ...

随机推荐

  1. Estimating Project Costs

    The Wideman Comparative Glossary of Common Project Management Terms describes estimating cost as, &q ...

  2. imx6 MFG TOOL 分析

    之前分析过mfgtool的内容,最近从官网下载,返现新版的mfgtool工具将imx6各种版本的linux/android都使用一个工具进行烧录.所以从新分析一下. 新版与旧版的一个区别是烧写使用的u ...

  3. Spring AOP 实现原理与 CGLIB 应用

    https://www.ibm.com/developerworks/cn/java/j-lo-springaopcglib/ AOP(Aspect Orient Programming),也就是面向 ...

  4. hibernate一对多注解

    package net.zmcheng.model; import java.util.HashSet;import java.util.Set; import javax.persistence.C ...

  5. glusterFS安装维护文档

    .规划: .依赖包 yum install libibverbs librdmacm xfsprogs nfs-utils rpcbind libaio liblvm2app lvm2-devel l ...

  6. 从 Vue 1.x 迁移

    FAQ 哇,非常长的一页!是否意味着 Vue2.0 已经完全不同了呢,是否需要从头学起呢,Vue1.0 的项目是不是没法迁移了? 非常开心地告诉你,并不是! 几乎90%的 API 和核心概念都没有变. ...

  7. javascript设计模式学习之九——命令模式

    一.命令模式使用场景及定义 命令模式常见的使用场景是:有时候需要向某些对象发送请求,但是并不知道请求的接受者是谁,也不知道请求的具体操作是什么.此时希望用一种松耦合的方式来设计程序,使得请求的发送者和 ...

  8. Windows 7 / Windows 10 安装 IPX/SPX

    以我的系统为例: Windows 7/10 x64 首先下载 NWLINK IPX/SPX 驱动(这是 Microsoft 对 IPX/SPX 的实现.) http://pan.baidu.com/s ...

  9. nsstring基本数据类型的包装类

    // //  main.m //  10-基本数据类型的包装类 // //  Created by apple on 14-3-20. //  Copyright (c) 2014年 apple. A ...

  10. 离线下载Windows 调试符号 Symbols

    公司开发机没有不能连接到互联网.调试程序时那些Windows模块(如ntdll.dll)不能加载符号,而程序总是崩在这些模块里.想看一眼到底崩在了什么地方. 需要把对应的符号下载下来. 使用工具sym ...