贪婪算法
用一句话来说这个算法
- 站在此时此刻使得我们做出的选择是最好的,即局部最优的。
这样每步的局部最优虽然并不能保证我们的总体是最优的,但是对于很多中情况,发现贪婪算法的这种局部最优导致的就是最优解,例如:我们熟悉的工作的调度问题。以及Kruskal算法和Prim算法等都是基于贪婪算法。
下面关于贪婪算法的实现,我们以工作调度为例
已知条件如下:
- 假定我们一天的时间里有n个工作,每个工作都有起始时间和结束时间,且我们同一时间内只能做一份工作
例如:int s=[1,3,6,8,10]
int f=[2,4,9,9,11];这两个数组表示的是5个工作的起始时间和结束时间
我们的目标:
- 一天内尽可能完成更多的工作
解决的思路
- 第一步:将工作按结束时间从小到大排序(这样才能保证我们的局部最优,使得我们每步选择都是此次此刻最早结束的工作)
- 第二步:选择我们已经排好序的第一个工作,然后在排好序的工作中依次选择起始时间大于等于前一个工作的结束时间的工作,直至不能选择为止
java实现的代码如下:
package org.wrh.algorithmimplements;
import java.util.Arrays;
//贪婪算法:工作调度的实现
public class GreedyAlgorithmSchedule {
public static void main(String[] args) {
/*
* 下面为5个工作的起始时间和结束时间,为方便起见,我们已经按结束时间排好序了
* */
int []s={1,1,3,6,6,8,10};
int []f={2,3,4,8,9,9,11};
interalSchedualing(s,f,s.length);
}
private static void interalSchedualing(int[] s, int[] f, int length) {
int []select=new int[length];//记录我们选择的工作的下标,为"1"表示下标对应的工作被选择了
int i=0;
select[i]=1;//将第一个工作加入
for(int j=1;j<length;j++){
if(s[j]>=f[i]){//如果当前工作的起始时间大于前一个被选中的工作的结束时间,则其应该被选中
i=j;
select[i]=1;
}
}
System.out.println("工作调度的情况:"+Arrays.toString(select));
}
}
代码比较简单,这里就不再解释
接下来,我会陆续将贪婪算法的其他的一些例子以及基于贪婪算法的一些算法也将会用java代码实现。
最后,关于更多的贪婪算法的知识,请点击这里;我的很多知识也是从上面学习到的,在此表示感谢