组合贪心
1.背包问题
相关文章:背包九讲
问题描述:给定n个物品和一个容量为C的背包,物品i的重量是 w i {w_i} wi,价值为 v i {v_i} vi,背包问题就是如何选择装入背包的物品,使得装入背包中物品的总价值最大。在背包问题中可以将某种物品的一部分装入背包中,但不可以重复装入。
w[i]表示第i个物品的所占据的容量,v[i]是第i个物品的价值,用x[i]表示第i个物品放入了多少到背包里面(初始化为0,加入为0.5表示放了50%到背包里面)
算法过程如下:
初始化x[i]=0,i在1~n之间
将物品按照v[i]/w[i]降序排列
如果w[i]<=C就执行下面的步骤:
C-=w[i],x[i]=1,i++
循环结束后,x[i]=C/w[i](最后缺的部分补上)
由于期末忙碌等考试结束补上代码。
算法分析:贪心策略是把单位价值高的先放。算法复杂度:排序使用堆排序,复杂度为O(nlogn)
2.活动安排
问题描述:设有n个活动的集合E={1,2,3,4,…,n},其中每个活动都要求使用同一资源(如演讲会场),在同一时间内只有一个活动能使用这一资源,每个活动i都有一个要求使用该资源的起始 s i {s_i} si与终止时间 f s {f_s} fs,且 s i < f i {s_i<f_i} si<fi.如果选择了活动i,那么他在区间 [ s i , f i ) {[s_i,f_i)} [si,fi)内占用资源。若区间 [ s i , f i ) {[s_i,f_i)} [si,fi)与 [ s j , f j ) {[s_j,f_j)} [sj,fj)不相交那么称i与j是相容的。也就是说,当 s i > = f j {s_i>=f_j} si>=fj或者 s j > = f i {s_j>=f_i} sj>=fi,两者相容,二活动安排问题则是要求选出最大的相容活动子集。
由于期末忙碌等考试结束补上代码。
算法过程如下:
将这n个活动按照 f i {f_i} fi非递减的顺序来排列
初始化为B(B是最后解的活动集合)={1}(即把第一个活动加进来)
循环i=2~n
找出与B中活动相容的最小活动,加入B中
算法分析:贪心策略是尽快把早点结束的做完留出更多的时间来做其他的,排序需要O(nlogn),遍历需要O(n),那么该算法的时间复杂度是O(nlogn);在第四小节我会讲一下该贪心算法为何可以获得最优解。
3.多机调度
问题描述:设有n个独立的作业{1,2,…,n},由m台相同的机 M 1 , M 2 , M 3 , . . . , M m {{M_1,M_2,M_3,...,M_m}} M1,M2,M3,...,Mm进行加工处理,作业i需要处理的时间是 t i {t_i} ti,每个作业可由任何一台机器上加工处理,但不可间断拆分.多机调度问题要求给出一种作业调度方案,是所给的n个作业在尽可能短的时间内由m台机器加工完成处理。
由于期末忙碌等考试结束补上代码。
S[i]表示第i台机器处理的作业(是一个集合),d[i]表示第i台机器的的空闲时间,t[i]表示作业i的处理时间
算法过程如下:
把活动按照t[i]降序排列,对应的序号放到p[i]中
如果m>=n,那么直接把n个作业分别分给前n个机器即可,同时S[i]={p[i]}
如果m<n,那么先把前m个作业分别分给m台机器,即:
for(int i=1;i<=m;i++)
S[i]={i};d[i]=t[i];
接下来对剩下的作业进行分配:
for(int i=m+1;i<=n;i++)
1.找到d[m]中最小的那个,他的下标为j
2.S[j]+={p[i]}
3.d[j]+=t[i]
算法分析:该算法贪心策略就是把作业时间最长的作业交给最先空闲的机器。一般m<<n,开始排序需要O(nlogn),接下来对前m个作业放到m台机器里面,需要O(m),接下来对循环n-m次,每次蛮力查找(没有排序,好的查找算法不好用)需要m次,故需要O(m+(n-m)*m)---->O(n*m),那么最后需要的时间复杂度为O(n*m)(一般logn<m)
4.贪心证明
在第三小节我们讲解了活动安排的问题。现在我们来证明算法为何可以获得最优解。那么:
首先我们先按照 f i {f_i} fi非递减的顺序来排序。假设集合A是我们最后的其中一个最优解(最优解不一定只有一个),如果A的第一个活动是活动1,那么说明我们的贪心选择是合理的,如果不是活动1,假设是活动k,那么我们把活动k替换为活动1,得到集合B,那么由于 f 1 < f k {f_1}<f_k f1<fk,那么B也是一个最优解,故而我们证明了第一步选择活动1是合理的,满足贪心选择性质,那么接下来的选择方式自然是从与活动1相容的子活动中继续选择了,这相当于求解有同样性质的子问题而已,满足贪心选择性质,就这样一步一步下去使用数学归纳法,发现该算法是可以获得整体最优解的。