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

这篇具有很好参考价值的文章主要介绍了0-1背包问题的多种算法求解(C语言)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        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或不选0
			backpack(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;
}

动态规划代码:文章来源地址https://www.toymoban.com/news/detail-495252.html

#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];
			else
				dp[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语言)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 算法设计与分析实验二:动态规划法求解TSP问题和01背包问题

    【实验内容】 (1)tsp问题:利用动态规划算法编程求解TSP问题,并进行时间复杂性分析。 输入:n个城市,权值,任选一个城市出发; 输出:以表格形式输出结果,并给出向量解和最短路径长度。 (2)01背包问题:利用动态规划算法编程求解0-1背包问题,并进行时间复杂性分

    2024年02月03日
    浏览(58)
  • 贪心算法解决背包问题和动态规划解决0-1背包问题(c语言)

    运行结果如下: 运行结果如下: 总结: 贪心算法: 每一步都做出当时看起来最佳的选择,也就是说,它总是做出局部最优的选择。 贪心算法的设计步骤: 对其作出一个选择后,只剩下一个子问题需要求解。 证明做出贪心选择后,原问题总是存在最优解,即贪心选择总是安

    2024年02月04日
    浏览(56)
  • (C语言贪心算法)0/1背包问题

    已知一个载重为M的背包和n件物品,物品编号从0到n-1。第i件物品的重量为 wi,若将第i种物品装入背包将获益pi,这里,wi0,pi0,0=in。所谓0/1背包问题是指在物品不能分割,只能整件装入背包或不装入的情况下,求一种最佳装载方案使得总收益最大。 第 1 行中有 2 个正整

    2024年02月08日
    浏览(41)
  • 动态规划算法解决背包问题,算法分析与C语言代码实现,时间效率解析

    🎊【数据结构与算法】专题正在持续更新中,各种数据结构的创建原理与运用✨,经典算法的解析✨都在这儿,欢迎大家前往订阅本专题,获取更多详细信息哦🎏🎏🎏 🪔本系列专栏 -  数据结构与算法_勾栏听曲_0 🍻欢迎大家  🏹  点赞👍  评论📨  收藏⭐️ 📌个人主

    2023年04月16日
    浏览(50)
  • 基于回溯法求解0-1背包问题

    一、实验目的 1.掌握基于回溯的算法求解0-1背包问题的原理。 2.掌握编写回溯法求解0-1背包问题函数的具体步骤并理解回溯法的核心思想以及其求解过程。 3.掌握子集树以及其他几种解空间树的回溯方法并具备运用回溯算法的思想设计算法并用于求解其他实际应用问题的能力

    2024年02月08日
    浏览(46)
  • 《数据结构、算法与应用C++语言描述》-列车车厢重排问题

    完整可编译运行代码见:Github::Data-Structures-Algorithms-and-Applications/_10Train_carriages_rearrangement/ 一列货运列车有 n 节车厢,每节车厢要停靠在不同的车站。假设 n个车站从 1 到n 编号,而且货运列车按照从n到1的顺序经过车站。车厢的编号与它们要停靠的车站编号相同。为了便于从

    2024年04月10日
    浏览(67)
  • HJ16 购物单 - 分组背包问题求解

    题目链接参考 HJ16 购物单_牛客题霸_牛客网 这道题需要通过动态规划来求解,首先先通过 ChatGPT 了解下如何 利用动态规划求解01背包问题和完全背包问题 ,以下是 ChatGPT 的答案 动态规划是什么? 动态规划(Dynamic Programming,DP)是一种常用的算法思想,用于解决多阶段决策问

    2023年04月21日
    浏览(40)
  • 数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。

    最短路径的算法有两个, Dijkstra算法 和 Floyd算法 。 Dijkstra算法 解决的是 单源 最短路径问题 。 Floyd算法解决的是 多源 最短路径问题,并且可以处理负权图 。 今天要讲的就是Dijkstra算法。 加: feng--Insist (大写的i),进java交流群讨论互联网+技术。可索要PPT等资料。 其他资料

    2024年02月11日
    浏览(58)
  • 数据结构学习记录——图应用实例-拯救007(问题描述、解题思路、伪代码解读、C语言算法实现)

    目录 问题描述  解题思路 伪代码  总体算法 DFS算法 伪代码解读 总体算法 DFS算法 具体实现(C语言) 在老电影“007之生死关头”(Live and Let Die)中有一个情节,007被毒贩抓到一个鳄鱼池中心的小岛上,他用了一种极为大胆的方法逃脱 —— 直接踩着池子里一系列鳄鱼的大脑

    2024年02月05日
    浏览(78)
  • 回溯法,分支限界法,动态规划法求解0-1背包问题(c++)

    问题描述 给定n种物品和一背包。物品i的重量是wi0,其价值为vi0,背包的容量为c。问应如何选择装入背包中的物品,使得装入背包中物品的总价值最大? 搜索空间: 子集树(完全二叉树) 约束函数(进包用): 如果当前背包中的物品总重量是cw,前面k-1件物品都已经决定是否进包,那

    2024年02月10日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包