算法学习 【第二周】贪心算法实例 Ⅱ
创始人
2024-04-01 12:32:22
0

算法学习 【第二周】贪心算法实例 Ⅱ

文章目录

  • 算法学习 【第二周】贪心算法实例 Ⅱ
    • 一、前言
    • 二、背包问题
      • 1、问题分析
      • 2、算法设计
      • 3、算法解析
      • 4、算法详解
      • 5、算法分析
      • 6、整体代码
    • 三、最后我想说

一、前言

在前面一期博客中,我们解析了贪心算法实例中的最优装载问题,本期博客我们紧接着来解析贪心算法中另一个经典的背包问题。

二、背包问题

有一天,阿里巴巴赶着一头毛驴上山砍柴。砍好柴准备下山时,远处突然出现一股烟尘,弥漫着向上空飞扬,朝他这儿卷过来,而且越来越近。阿里巴巴心里害怕,担心碰到的是一伙儿强盗,他赶紧把毛驴赶到丛林的小道里,自己爬到一棵大树上躲了起来,这棵大树生长在一个大石头旁边。靠近以后,他才看清原来是一支马队,他们共有四十人,一个个年轻力壮、行动敏捷。一个首领模样的人背负沉重的鞍袋,他从丛林中来到那个大石头跟前,喃喃地说道:“芝麻,开门吧! "随着那个头目的喊声,大石头前突然出现一道宽阔的门路,于是强盗们鱼贯而入。阿里巴巴躲在树上观察他们,直到他们走得无影无踪之后,才从树上下来。他大声喊道:“芝麻,开门吧! ”他的喊声刚落,洞门立刻打开了。他小心翼翼地走了进去,一下子惊呆了,洞中堆满了财物,还有多得无法计数的金银珠宝,有的散堆在地上,有的盛在皮袋中。突然看见这么多的金银财宝,阿里巴巴深信这肯定是强盗们数代经营、掠夺所积累起来的宝窟。为了让乡亲们开开眼界,见识一下这些宝物,他想一种宝物只拿一个,如果太重就用锤子凿开,但毛驴的运载能力是有限的,怎么才能用毛驴运走价值最大的财宝分给乡亲们呢?

1、问题分析

这是书中的原作者给我们的设置的具体场景的背包问题,我们简化一下问题就是有n种物品,每种物品只有一个,第种物品的重量为wi,价值为vi,背包的容量为W,物品可以分割。如何放置物品,使装入背包的物品价值之和最大?

我们假定所有物品的重量和价格都是非负的。背包所能承受的最大重量为W。如果物品可分割,则问题称为背包问题,如果限定每种物品只能选择0个或1个,则问题称为0-1背包问题

我们可以用公式表示为:

在这里插入图片描述

如果限定物品j最多只能选择bj个,则问题称为有界背包问题

我们可以用公式表示为:

在这里插入图片描述

如果不限定每种物品的数量,则问题称为无界背包问题

各类复杂的背包问题总可以变换为简单的0-1背包问题进行求解。

我们回到上面的题目,如果我们要使装入背包的物品价值之和最大,按照贪心策略的话我们应该每次选择单位重量价值最大的物品装入背包。

2、算法设计

  • 确定合适的数据结构并初始化,我们首先将物品的重量、价值和单位重量价值定义为一种结构体类型,然后对物品按单位重量价值从大到小进行排序。
  • 然后根据贪心策略,我们按照单位重量价值从大到小选取物品,直到达到背包的最大容量,如果在装入第i个物品时超出背包容量,则取该物品的一部分装入背包。

3、算法解析

我们在这里假设背包容量W=30,然后列出物品的价值和重量表:

物品i12345678910
重量w[i]4295585455
价值v[i]3818682056715

我们现在按照贪心策略每次选单位重量价值(价值/重量)大的物品,因此我们可以按单位重量价值对物品进行降序排序,排序后结果如下:

物品i21063589471
重量w[i]2589545554
价值v[i]8152018867653
单位重量价值p[i]432.521.61.51.41.210.75

然后我们按照安心策略每次选择单位重量价值最大的物品装入背包。

物品ID背包剩余容量当前已装入物品的最大价值
230-2=288
1028-5=238+15=23
623-8=1523+20=43
315-9=643+18=61
56-5=161+8=69
8剩余容量为1,8号物品重量为4,无法全部装入69+1×1.5=70.5

我们按照上面表格依次装入物品,到第八装入的时候背包就被装满了。

由上述表格可知,这个问题的最优解就是物品ID组成的(2,10,6,3,5,8),其中最后一个物品是部分装入,只装入了1/4,最后装入物品的最大价值是70.5。

4、算法详解

根据之前的分析结果,我们首先定义一个结构体:

struct node{double w;	//每种物品的重量double v;	//每种物品的价值double p;	//每种物品的耽误重量价值
}

然后我们对物品按单位重量价值进行排序,我们仍然利用之前讲过的排序函数sort最物品按单位重量价值从大到小进行排序,在对结构体类型的数据进行排序时,如果没有自定义比较函数,sort函数将不知道按照结构体的哪个成员进行排序,因此我们自定义比较函数cmp,指定按照物品的单位重量价值进行降序排列:

bool cmp(node a,node b){	//自定义比较函数cmpreturn a.p>b.p;			//指定按照物品的单位重量价值进行降序排序
}
sort(s,s+n,cmp);			//前两个参数分别为待排序数组的首地址和尾地址,cmp为比较函数

然后我们使用贪心算法求解问题,在单位重量价值排序的基础上,如果当前物品的重量小于或等于剩余容量,则可以装入,将剩余容量减去当前物品的重量,同时将已装入物品的价值加上当前物品的价值。如果当前物品的重量大于剩余容量,则表示不可以全部装入,但可以部分装入,直到背包装满,将剩余容量乘以当前物品的单位重量价值,与已装入物品的价值相加,即为已装入物晶的最大价值。

double solve(int n,double W){double sum=0.0;				//sum表示已装入物品的价值之和double cleft=W;				//背包的剩余容量for(int i=0;i

5、算法分析

  • 时间复杂度:时间主要耗费在对物品按单位重量价值进行排序上,一般采用快速排序法,时间复杂度是O(nlognnlognnlogn)。
  • 空间复杂度:空间主要耗费在存储物品的单位重量价值上,空间复杂度是O(n)。

6、整体代码

以下代码是随书附带的源码,大家可以看看:

//program 2.3 背包问题 
#include
#include
using namespace std;
const int M=10005;
struct node{double w;//每个物品的重量double v;//每个物品的价值double p;//性价比
}s[M];bool cmp(node a,node b){//自定义比较函数 return a.p>b.p;//根据物品的单位价值从大到小排序
}double solve(int n,double W){double sum=0.0;//sum表示示装入物品的价值之和double cleft=W;//背包剩余容量 for(int i=0;i>t;while(t--){cin>>n>>W;for(int i=0;i>s[i].w>>s[i].v;s[i].p=s[i].v/s[i].w;//每个宝物单位价值}sort(s,s+n,cmp);cout<

三、最后我想说

本期博客就到这里结束了,目前举例了两个贪心算法实例,还有很多实例,我后续也会进行更新了,这个14天阅读挑战赛我应该只能更新五篇博客了,不过算法这方面我肯定不会断更的,因为算法很重要,必须要好好的提升自己这方面的知识。

谢谢大家!

相关内容

热门资讯

男子举报山西襄汾一镇干部酒后上... 12月29日,山西临汾市襄汾县新城镇上庄村的温先生向纵览新闻反映,其父亲在家中遭到镇干部曹某某酒后殴...
实力坑夫?律师社交账号简介称老... 12月28日,天津一名刑辩何姓律师的社交平台账号在介绍中称自己是“警嫂”,“爱人是市局经侦办案警官”...
盘州市南湖社区:打造法律“服务... 近年来,为破解基层法律服务“最后一公里”难题,推进社区矛盾纠纷法治化实质性化解,贵州省盘州市以“精准...
内乡法院:彩礼纠纷引诉讼 法院... 大象新闻记者 魏广宝 通讯员 聂传青 张航/文图 近日, 内乡县人民法院灌涨法庭成功调解一起因婚姻关...
税费服务“主动敲门” 政策红利... “税务部门的主动提醒和精准辅导真是太及时了,不仅帮我们规避了因政策理解偏差可能引发的风险,更让我们实...
民政部:会同有关部门建立最低生... 据新华社,记者12月30日在全国民政工作会议上获悉,民政部将会同有关部门建立最低生活保障标准备案制度...
肯尼亚投资:税务及法律合规指引 一、肯尼亚的外国直接投资 肯尼亚无疑是非洲吸引外国直接投资(FDI)最多的国家之一。根据《2025年...
大同多部门联动打击生态环境违法... 本报讯(通讯员刘美 陈俊宏)近日,大同市中级人民法院联合大同市人民检察院、大同市公安局、大同市司法局...
南阳宛城检察:让道争执酿祸端 ... 大象新闻记者 张定有 通讯员 魏颖 张婷/文图 一桩因乡间小道通行引发的争执,险些酿成极端事件。南阳...
寻找靠谱征地律师,孙侠律师 在征地相关法律事务中,找到一位靠谱且成功率高的征地律师至关重要。随着城市化进程的加速,征地纠纷日益增...