我在当前情况下,我把我做到最好。我也不管全局如何,整体如何。我就考虑我现在的这一个,或者这一小部分怎样最好。
打个比方,我现在有几种选择:
学编程、打游戏、读书、去外面玩、去兼职、……
如果我的目的是提高自己的知识水平,那起码对于现在的这些选择来说,我选择“学编程”或者“读书”就是最优的。
只是说当前这一步怎么走是最优的,也并没有去管后面的路怎么走。
比如你说选择“打游戏”,后面可能也会更成功,但是不管这个。
例如:
d 1 = 25 c , d 2 = 10 c , d 3 = 5 c , d 4 = 1 c ,而且 n = 48 c d_1=25c,d_2=10c,d_3=5c,d_4=1c,而且n=48c d1=25c,d2=10c,d3=5c,d4=1c,而且n=48c。
我们可能想,要使得硬币数目最少,那简单啊。
先紧着面额最大的来凑就行了。
先拿个25c的、再拿两个10c的,5c的没法拿,于是再拿3个1c的。
于是得到贪婪解:
<1,2,0,3>
。我们这个策略就是,很简单,先紧着最大的拿。
但是我们虽然这样做了,而且貌似可行。
但是实际上,它对于大多数情况而言,这样可能是没问题的;但是没法保证所有情况啊,你没法保证对于所有情况、任意某一种情况,这样都没问题。
有一些情况,你这样做,可能就压根不是最优解了。
但是:
例如:
d 1 = 25 c , d 2 = 10 c , d 3 = 1 c 而且 n = 30 c d_1=25c,d_2=10c,d_3=1c而且n=30c d1=25c,d2=10c,d3=1c而且n=30c。
那么你还按照上面的规则,
先拿个25c的,然后拿五个1c的。——此时是6个硬币。
但实际上我们可以看出,直接拿三个10c的就够了,而且只用3个硬币。
所以可见,我们刚才的那种简单的想法:先紧着大面额的拿。
这种方法,可能在某些情况下没毛病,但是在有些情况下就不对了、不是最优解了。
**那咋办呢。**是不是我的想法、我的策略设计的有问题呢?
那到底咋样弄,才能对于所有情况都能得到最优解呢?
我们可以用回溯法。(不是讲贪心吗,咋又说回溯了?——后面再说这个问题)
就像人生中的一些选择一样,就是贪心算法么,每次选的是局部最优,而且选了之后就没法取消了。
在每一步中,它要求“贪婪”地选择最佳操作,并希望通过一系列局部的最优选择,能够产生一个整个问题的(全局的)最优解。
给定n种物品和一个背包。物品i
的重量是 W i W_i Wi,其价值为 V i V_i Vi,背包的容量为C
。应如何选择装入背包的物品,使得装入背包中物品的总价值最大?
0-1背包问题,对于一个物品,0就是不拿它,1就是拿它。
在选择装入背包的物品时,对每种物品只有两种选择,要么装入背包、要么不装入背包。不能将一个物品装入背包多次,也不能只装入某物品的一部分。
与0-1背包问题类似,所不同的是,在选择物品i
装入背包时,可以选择物品i的一部分,而不一定要全部装入背包,1≤i≤n
。
背包问题,也叫“分数背包问题”,对于一个物品,物品太大了,背包剩余空间不够了,此时我可以把物品拆下来、把一部分放进去。
m a x ∑ i ∈ A p i , s u b j e c t t o ∑ i ∈ A w i ≤ C max\sum_{i∈A}p_i,subject\ to\ \sum_{i∈A}w_i≤C maxi∈A∑pi,subject to i∈A∑wi≤C
有以下几种贪心选择准则:
紧着最值钱的先往上放。
紧着最小体积的先放,想装的多。
想着一般大的东西都比较值钱?所以先紧着大件先放?
这四个规则都有一定道理,那我们该选哪种呢?选最大价值优先?选最大单位价值优先?
最大价值优先
(lb
是重量单位,上面是价钱)
可见,最大价值优先,放进来的不一定是最优解。
最小体积优先
可见,最小体积优先,放进来的也不一定是最优解。
最大体积优先
可见,最大体积优先得到的也不一定是最优解。
最大单位价值优先
可见,这个也不一定能得到最优解。
i
个物品的一部分放入背包。这个就没啥好犹豫的了,我先紧着最大单位价值的往里面放,放不下整个物品的时候,我把当前最大单位价值的物品切出来一块往里面放。
这样最后包里放的肯定是价值最大的情况。
最优解证明
我们首先假设我们有一个最优解 A 1 A_1 A1,那么我们首先找到 A 1 A_1 A1里面平均价值最高的物品 a m a_m am,然后我们将用商品里面平均价值最高的物品 a 1 a_1 a1将 a m a_m am进行全部替换或者部分替换得到解 A 2 A_2 A2,又因为 v 1 w 1 ≥ v m w m \frac{v_1}{w_1}≥\frac{v_m}{w_m} w1v1≥wmvm,所以 A 2 A_2 A2的总价值高于 A 1 A_1 A1的总价值,这与 A 1 A_1 A1是最优解矛盾,于是得到 A 1 A_1 A1里面包含平均价值最高的物品。
3,5,6,10,11,14,15,18,20
如果只有一个处理器,那就没啥说的,每个任务看看按照什么规则往里放就行了,反正最后总时间是一样的。
但是如果有多个处理器呢?
当然,对于贪心而言,我们对这一问题也可以有很多种贪心策略。
每次把当前需要运行最长时间的任务,分配给当前任务时间最短的处理器。
因此,三个处理器执行这些任务,花费35分钟时间。
这个解决方法不错,但是我们可能还可以有更好的策略。
这个方式还不如刚才那个,这个需要花费40分钟。
最优解
折腾半天都不是最好的,那我们看看最优解到底是什么样的,如上图所示。
很明显么。因为三个处理器刚好平均分了所有任务的总时长,没有任何的浪费。
但是,可见,若想得到这样的一种解。你要付出的代价就会很高了。
有必要么,实际解决一个问题来说,这样去搞,可能没这个必要。你找到最优解了之后,最优解固然能够帮你节约时间;但是不要忽视了,你寻找这个最优解也要花时间。你为了找一个最优解去节约那一点点时间,然后你花了大量的时间在寻找到最优解上,得不偿失。
类似上图中这个最优解,是咋找到的?可能是暴力穷举吧,或者是什么方法。总之很耗时间才能找出来的。
实际上我就用一种贪心策略,去做,就拉倒了。虽然可能不是最优,但是接近最优差不多就行了。
对于一些特殊的问题,贪心算法能直接找出其最优解,能直接获取最优解那当然更好了。
总之贪心算法可能找到的不是最优解,而只是局部最优解;但是它的实现是很简单的,不会耗费太多时间。
同时,我们在贪心,贪的过程中,也可以利用回溯法的思想,对一些没必要继续探讨下去的情况进行剪枝,而没必要全部贪到底、再去排除。也就是贪心法配合回溯法进行使用。