第5章 回溯法,0-1背包问题

回溯法:0-1背包问题(C++实现) 概念: 回溯法是一种非常有效的方法,有“通用的解题法”之称。它有点像穷举法,但是更带有跳跃性和系统性,他可以系统性的搜索一个问题的所有的解和任一解。回溯法采用的是深度优先策略。 回溯法按深度优先策略搜索问题的解空间树。首先从根节点出发搜索解空间树,当算法搜索至解空间树的某一节点时,先利用剪枝函数判断该节点是否可行(即能得到问题的解)。如果不可行,则跳过对该节点为根的子树的搜索,逐... 阅读详情
#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

#define MAXN 10

struct Goods_Info
{
	int v;		//价值
	int w;		//重量
	double vw;	//价值重量比
}goods[MAXN];

int n;
int maxValue;
bool solu[MAXN];
bool optimalSolu[MAXN];

bool Cmp(const Goods_Info a, const Goods_Info b)
{
	return a.vw > b.vw;
}

//可装入一部分物品时,取得的最优价值
double Bound(int i, double v, int c)
{
	//以物品的价值重量比递减将物品装入背包
	while (i <= n && goods[i].w <= c)
	{
		v += goods[i].v;
		c -= goods[i].w;
		i++;
	}
	//将背包装满
	if (i <= n)
	{
		v += (goods[i].vw * c);
	}
	return v;
}

void Backtrack(int k, int cv, int rc)
{
	if (k > n)
	{
		if (cv > maxValue)
		{
			maxValue = cv;
			int i;
			for (i = 1; i <= n; i++)
			{
				optimalSolu[i] = solu[i];
			}
		}
	}
	else
	{
		if (goods[k].w <= rc) //当前物品能否装入背包
		{
			solu[k] = true;
			Backtrack(k+1, cv+goods[k].v, rc-goods[k].w);
		}
		if (Bound(k+1, cv, rc) > maxValue) //剩余物品的最优价值是否更优
		{
			solu[k] = false;
			Backtrack(k+1, cv, rc);
		}
	}
}

int main(void)
{
	int c;
	while (scanf("%d%d", &n, &c) != EOF)
	{
		int i;
		for (i = 1; i <= n; i++)
		{
			scanf("%d%d", &goods[i].v, &goods[i].w);
			goods[i].vw = (double)goods[i].v / goods[i].w;
		}

		//将物品按照价值重量比递减排序
		sort(goods+1, goods+n+1, Cmp);

		maxValue = 0;
		Backtrack(1, 0, c);

		printf("%d\n", maxValue); //最优值
		
		/*
		//最优解
		printf("value:");
		for (i = 1; i <= n; i++)
		{
			printf("\t%d", goods[i].v);
		}
		printf("\nweight:");
		for (i = 1; i <= n; i++)
		{
			printf("\t%d", goods[i].w);
		}
		printf("\nstatus:");
		for (i = 1; i <= n; i++)
		{
			printf("\t%d", optimalSolu[i]);
		}
		printf("\n");
		*/
	}
	return 0;
}

/*
5 27
8 3
12 7
10 5
8 4
15 9

5 27
8 8
12 12
10 10
8 8
15 15

5 26
8 8
12 12
10 10
8 8
15 15

5 28
8 8
12 12
10 10
8 8
15 15

5 29
8 8
12 12
10 10
8 8
15 15
*/

回溯法 —— 求解0/1背包问题(剪枝) 0/1背包问题 题目描述: 有n个重量分别为w1,w2,…,wn的物品(物品编号为1~n),它们的价值分别为v1,v2,…,vn,给定一个容量为W的背包。设计从这些物品中选取一部分物品放入该背包的方案,每个物品要么选中要么选不中,要求选中的物品不仅能够放到背包中,而且具有最大价值,并对下表所示4个物品求出W=6时的所有解和最佳解。 分析思路:回溯法 设n件物品重量分别为w1,w2,…,wn的物品,用数组w[1 … n]存放,物品的价值分别为v1,v2,…,vn,用数组v[n]存放;限制重量用W表示。用x[ 阅读详情

相关推荐

回溯法——利用解空间树解决0-1背包问题

一、简介 01背包典型的解法是动态规划,之前的博客也有介绍,这里就不再赘述。 https://blog.youkuaiyun.com/Jayphone17/article/details/102553763 这里有一些回溯法相关的基础理论知识: https://blog.youkuaiyun.com/Jayphone17/article/details/102910824 二、算法设计 (1)定义问题解...

Jayphone17的博客 3万+

回溯法解0-1背包问题(王晓东算法例题)

给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为C。问应如何选择装入背包的物品,使得装入背包中物品的总价值最大? 整个解的空间相当于一个二叉树,左边是0,代表不取这个物品,右边是1,代表取这个物品,然后进行dfs,回溯的时候修改。 注意,这里应该有两个剪枝,我这里只写了一个。 #include #include #include using namespace std;

NK_test的博客 7834

0027算法笔记——【回溯法】回溯法与装载问题

1、回溯法      (1)描述:回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法。      (2)原理: 回溯法在问题的解空间树中,按深度优先策略,从根结点出发搜索解空间树。算法搜索至解空间树的任意一点时,先判断该结点是否包含问题的解。如果肯定不包含,则跳过对该结点为根的子树的

liufeng_king的专栏 4万+

算法分析与设计--0/1背包问题(回溯法)

算法分析与设计--0/1背包问题(回溯法) 问题描述: 给定n种物品和一个容量为C的背包,物品i的重量是wi,其价值为vi,0/1背包问题是如何选择装入背包的物品(物品不可分割),使得装入背包中物品的总价值最大? #include&lt;iostream&gt; using namespace std; const int n = 3; //物品个数 const int C...

runfeel 835

01背包问题【回溯法求解】通俗易懂,适合小白

本人此时还是一名研一的小菜鸡,刚学会了这个算法的基本概念,来总结一下,谁知道今后的我再看到这篇自己写的博客的时候会不会笑出来,哈哈哈哈哈哈哈哈,所以吗,错了的化大佬们评论指正就好了。 还有系列文章动态规划法解01背包问题,分支限界法解01背包问题哈,需要的化以下是链接: 动态规划法:https://blog.youkuaiyun.com/qq_29051107/article/details/103394...

CcBC的博客 7404

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

问题描述 有n个物品和一个容量为c的背包,从n个物品中选取装包的物品。物品i的重量为w[i],价值为p[i]。一个可行的背包装载是指,装包的物品总重量不超过背包的重量。一个最佳背包装载是指,物品总价值最高的可行的背包装载。 我们要求出x[i]的值。x[i] == 1表示物品i装入背包,x[i] == 0表示物品i没有装入背包。 问题的公式描述是: //总价值最高的可能的背包装载,x

一个程序渣渣的小后院 4673

0-1背包问题-回溯法

算法描述  0-1背包问题是子集选取问题。一般情况下,0-1背包问题是NP难得。0-1背包问题的解空间可用子集树 表示。在搜索解空间的时,只要其左儿子节点是一个可行节点,搜索就进去其左子树(约束条件)。当右子树中可能包含最优解时才进入右子树搜索(限界函数)。否则就将右子树剪去。  计算右子树中解的上界的更好方法是将剩余物品依其单位重量价值排序,然后依次装入物品,直至装不下时,再装入物品的一部分而装满背包。由此得到的价值是右子树中解的上界。 例如,对于0-1背包问题的一个实例,n = 4, c = 7, p

迷雾总会解 1万+

背包问题的回溯算法

结合0-1背包问题介绍了回溯法的基本思想和解题步骤,并在VC++6.0环境下验证了回溯法可以有效地解决0-1背包问题。

回溯法----0-1背包问题

[算法描述] 0-1背包问题是子集选取问题。一般情况下,0-1背包问题是NP完全问题。0-1背包问题的解空间可以用子集树表示。解0-1背包问题的回溯法与解装载问题的回溯法十分相似。在搜索解空间树时,只要其左儿子节点是一个可行的节点,搜索就进入其左子树;而当右子树中有可能包含最优解时才进入右子树搜索,否则将右子树剪去。设r是当前剩余物品价值总和;cp是当前价值;bestp是当前最优价值。当cp+r<=bestp时,可剪去右子树。计算右子树中解的上界的更好的办法是,将剩余物品依其单位重量价值排序,然后依

qq_54809548的博客 5万+

java算法 0-1 背包问题回溯算法解决 netbeans

用回溯算法解决背包问题,和我上传的另一个资源一样的只不过哪个用贪心算法解决,大家可以下来对比学习,用netbeans做的。百分百下载就可以直接运行。有WORD文档实验报告,和 JAVA 源文件。

回溯算法0-1背包问题

回溯算法0-1背包问题代码实现。算法backtrack在最坏情况下可能需要更新当前最优解O(n-1)!)次,每次更新bestx需计算时间O(n),从而整个算法的计算时间复杂性为O(n!)。

回溯法-------0-1背包问题(DFS、剪枝函数)

一 回溯法概述 回溯法的思路主要可以概述为以下2点: (1)把问题的解空间转化成了图或者树的结构 (2)使用深度优先搜索策略进行遍历,遍历的过程中记录和寻找所有可行解或者最优解。 二 深度优先搜索策略(DFS) 深度优先遍历一般只在图和树中涉及,当然,树是图的一种特殊结构。DFS简要来说就是对每一个可能的分支路径深入到不能再深入为止,且不能重复遍历,即每个节点只能遍历一次。 下边举两个例子 说明一下DFS,帮助理解。 1 树中的深度优先遍历 如图所示:是一个二叉树,其深度遍历的顺序为:.

zr147258369的博客 2万+

0-1背包问题,背包中物品的总重量不能超过背包的容量,最佳装载是指所装入的物品价值最高。

0-1背包问题 在0 / 1背包问题中,需对容量为c 的背包进行装载。从n 个物品中选取装入背包的物品,每件物品i 的重量为wi ,价值为pi 。对于可行的背包装载,背包中物品的总重量不能超过背包的容量,最佳装载是指所装入的物品价值最高。

0-1背包问题(回溯法)

0-1背包问题是动态规划、贪心策略的一个子问题。回溯算法同样可以适用于0-1背包问题。下面使用回溯算法解0-1背包问题。 文章目录一、问题描述二、算法设计三、实例1、输入:2、2个可行解:3、最优解:<0,1,1,1>四、搜索空间1、子集树的运行2、实例:V={12,11,9,8}, W={8,6,4,3}, B=133、搜索空间:子集树,2^n片树叶4、可行解50、最优解五、代码实现 一、问题描述 有n种物品,每种物品只有1个。 第i种物品价值为vi , 重量为wi, i=1,2,…, n。问

极客园地 2万+

0-1背包问题-递归算法 c语言实现

0-1背包问题 递归算法 c语言实现,已通过编译,可以直接使用

0-1背包问题需对容量为c 的背包进行装载。从n 个物品中选取装入背包的物品,每件物品i 的重量为wi ,价值为pi 。对于可行的背包装载,背包中物品的总重量不能超过背包的容量,最佳装载是指所装入的物品价值最高。

输入: 多个测例,每个测例的输入占三行。第一行两个整数:n(n<=10)和c,第二行n个整数分别是w1到wn,第三行n个整数分别是p1到pn。 n 和 c 都等于零标志输入结束。 输出: 每个测例的输出占一行,输出一个整数,即最佳装载的总价值。 输入样例: 1 2 1 1 2 3 2 2 3 4 0 0 输出样例: 1 4

回溯法,分支限界法,动态规划法求解0-1背包问题(c++)

0-1背包问题 1、问题描述 给定n种物品和一背包。物品i的重量是wi>0,其价值为vi>0,背包的容量为c。问应如何选择装入背包中的物品,使得装入背包中物品的总价值最大? 搜索空间: 子集树(完全二叉树) 约束函数(进包用): 如果当前背包中的物品总重量是cw,前面k-1件物品都已经决定是否进包,那么第k件物品进包的条件是:cw +w:≤M。 上界函数(不进包用): 设cp是当前价值,r是将剩余物品的价值之和.cp十r为对应装包方案集的上界。 上界函数(不进包用): 设cp是当前价值,r是将剩

weixin_53522240的博客 8235

回溯法和分支界限法解01背包问题(C++完整)

C++写的回溯法和分支界限法解01背包问题的代码,在VC6.0上运行成功。 代码规范,良好风格,注释十分详细,文件中还包含测试数据。学算法设计的朋友可以下载参考。 2024.02.04注:学生时代的作业,现已不确定代码正确性,改为免费下载,仅供学习参考。

上一篇: 第5章 回溯法,n皇后问题
下一篇: 第3章 动态规划,算法分析题3-3 漂亮打印
庞老板
博客等级 码龄15年 127粉丝 66原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

庞老板

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值