背包问题(Knapsack problem)采用动态规划求解

时间:2022-05-21 01:12:56

问题说明:

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

下面我们看下代码:

/*
问题:
假设有一个背包的负重最多可达8公斤,而希望在背包中装入负重范围内可得之总价物品
算法说明:
采用动态规划,在当前阶段求解出最好的解,如此反复
日期:2013/8/18
张威
*/ #include <iostream>
#include <time.h>
using namespace std; #define MAXSIZE 8 //定义全局变量
char name[][] = {"李子","苹果","橘子","草莓","甜瓜"};//水果名称
int wight[] = {,,,,};//单个水果所占斤数
int price[] = {,,,,};//单个水果的价值
int perkg_price[];//每斤水果的价钱
int perkg_num[] = {,,,,}; void GetNmae(int num)
{
for (int i = ;i <= ;i++)
{
cout<<name[num][i];
}
} void GetBestAnswer(int currentwigh)
{
//判断递归终止条件
if (currentwigh >= MAXSIZE)
{
cout<<"包裹已经满了,无法再装进东西"<<endl;
}
else
{
//check用来表证到底剩下来的物品里面还有没有能装进去背包里的
bool check = true;
int i = ;
for (;i <= ;i++)
{
//若是没有进入到这个条件内,说明剩下来的物品的重量都超过了背包剩余重量,到此结束.否则i就代表当前所能选中的最优解
if (wight[perkg_num[i]] <= MAXSIZE-currentwigh)
{
check = false;
break;
}
}
if (check == true)
{
cout<<"已经装不进去任何水果了"<<endl;
}
else
{
//得到最优解,并且将当前重量增加,进入下一次递归
currentwigh += wight[perkg_num[i]];
cout<<"购买了";
GetNmae(perkg_num[i]);
cout<<endl;
GetBestAnswer(currentwigh);
}
}
} int main()
{
//计算出每斤水果的价钱,便于动态规划时求出当前最佳解
for (int i = ;i <= ;i++)
{
perkg_price[i] = price[i] / wight[i];
}
//对perkg_num进行排序,同时保证单价和perkg_num之间的一一对应关系.即两个数组要同时变化
//采用的是冒泡排序,在元素进行交换时perkg_num和perkg_price同时变化
for (int i = ;i <= ;i++)
{
for (int j = i;j <= ;j++)
{
if (perkg_price[j] < perkg_price[j+])
{
int temp1 = perkg_price[j];
int temp2 = perkg_num[j];
perkg_price[j] = perkg_price[j+];
perkg_price[j+] = temp1;
perkg_num[j] = perkg_num[j+];
perkg_num[j+] = temp2;
}
}
}
//开始计算求解
GetBestAnswer();
return ;
}

背包问题

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

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

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

背包问题(Knapsack problem)采用动态规划求解背包问题(Knapsack problem)采用动态规划求解

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

#include <stdio.h>
#include <stdlib.h>
#define LIMIT 8
// 重量限制
#define N 5
// 物品种类
#define MIN 1
// 最小重量
struct body {
char name[];
int size;
int price;
};



重 valu
e item 0 背


重 valu
e item 0 typedef struct body object;
int main(void) {
int item[LIMIT+] = {};
int value[LIMIT+] = {};
int newvalue, i, s, p;
object a[] = {{"李子", , },
{"苹果", , },
{"橘子", , },
{"草莓", , },
{"甜瓜", , }};
for(i = ; i < N;i++) {
for(s = a[i].size; s <= LIMIT;s++) {
p = s - a[i].size;
newvalue = value[p] + a[i].price;
if(newvalue > value[s]) {// 找到阶段最佳解
value[s] = newvalue;
item[s] = i;
}
}
}
printf("物品\t价格\n");
for(i = LIMIT;i >= MIN;i = i - a[item[i]].size) {
printf("%s\t%d\n",
a[item[i]].name, a[item[i]].price);
}
printf("合计\t%d\n", value[LIMIT]);
return ;
}
Java
class Fruit {
private String name;
private int size;
private int price;
public Fruit(String name,int size, int price){
this.name = name;
this.size = size;
this.price = price;
}
public String getName(){
return name;
}
public int getPrice(){
return price;
}
public int getSize() {
return size;
}
}
public class Knapsack {
public static void main(String[] args){
final int MAX = ;
final int MIN = ;
int[] item = new int[MAX+];
int[] value = new int[MAX+];
Fruit fruits[] = {
new Fruit("李子", , ),
new Fruit("苹果", , ),
new Fruit("橘子", , ),
new Fruit("草莓", , ),
new Fruit("甜瓜", , )};
for(int i = ; i < fruits.length;i++) {
for(int s = fruits[i].getSize(); s <= MAX;s++){
int p = s - fruits[i].getSize();
int newvalue = value[p] +
fruits[i].getPrice();
if(newvalue > value[s]) {// 找到阶段最佳解
value[s] = newvalue;
item[s] = i;
}
}
}
System.out.println("物品\t价格");
for(int i = MAX;
i >= MIN;
i = i - fruits[item[i]].getSize()) {
System.out.println(fruits[item[i]].getName()+
"\t" + fruits[item[i]].getPrice());
}
System.out.println("合计\t" + value[MAX]);
}
}

指导书上面的代码

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

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

  1. 对背包问题&lpar;Knapsack Problem&rpar;的算法探究

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

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

    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. &lbrack;DP&rsqb; 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. 从零开始山寨Caffe&&num;183&semi;伍:Protocol Buffer简易指南

    你为Class外访问private对象而苦恼嘛?你为设计序列化格式而头疼嘛? ——欢迎体验Google Protocol Buffer 面向对象之封装性 历史遗留问题 面向对象中最矛盾的一个特性,就是 ...

  2. 【转】Java并发编程注意事项

    保证线程安全的三种方法: 不要跨线程访问共享变量 使共享变量是final类型的 将共享变量的操作加上同步 一开始就将类设计成线程安全的, 比在后期重新修复它,更容易. 编写多线程程序, 首先保证它是正 ...

  3. java JSONObject&sol;JSONArray详解

    应用架包:json-lib-2.4-jdk15.jar.及相关依赖架包. 一.JSONObject和JSONArray对象 -------------------------------------- ...

  4. 浅谈ES6中的Proxy

    Proxy是一个很有趣的对象,它能够修改某些操作的默认行为,等同于在语言层面做出修改,属于一种‘元编程’,即对编程语言进行编程. Proxy其实很好理解,就是在目标对象之前架设一层拦截,外界的访问都得 ...

  5. CPU 材料学才是最*的学科

    cpu的物理组成3部分:逻辑部件.寄存器.控制部件 CPU具有以下4个方面的基本功能:数据通信,资源共享,分布式处理,提供系统可靠性 cpu处理4过程:提取.解码.执行.写回 http://baike ...

  6. TinyXml和tinyxml2

    C++操作xml没有标准库的支持,TinyXml是个不错的xml操作库,以前总是使用TinyXml读写xml,但是最近对大量xml进行读写时,速度真的是有点慢,特别是在调试时,每次启动读xml就要好长 ...

  7. ALTIUM DESIGNER怎么定义差分对布线

    方法一:第一步是在原理图中声明,这样做的目的是为了让差分对布线器清楚哪两个网络是属于同一组差分对,设计编译器将查找格式为NETNAME_N和NETNAME_P(即以_N和_P为后缀)的两个同名网络.这 ...

  8. 开源的API集成测试工具 v0&period;1&period;2 - 增强体验

    Hitchhiker 是一款开源的 Restful Api 集成测试工具,你可以在轻松部署到本地,和你的team成员一起管理Api. 详细介绍请看: http://www.cnblogs.com/br ...

  9. Django1&period;10主题指南—模型

    模型是你的数据的唯一的.权威的信息源.它包含你所储存数据的必要字段和操作行为.通常,每个模型都对应着数据库中的唯一一张表. 基础认识: 每个model都是一个继承 django.db.models.M ...

  10. Tomcat服务器的Web安全的解决方法

    .概述 在任何一种WEB应用开发中,不论大中小规模的,每个开发者都会遇到一些需要保护程序数据的问题,涉及到用户的LOGIN ID和PASSWORD.那么如何执行验证方式更好呢?实际上,有很多方式来实现 ...