教室调度问题
假设有如下课程表,你希望将尽可能多的课程安排在某间教室上
你没法让这些课都在这间教室上,因为有些课的上课时间有冲突。
如何选出尽可能多且时间不冲突的课程呢?
具体做法如下。
(1) 选出结束最早的课,它就是要在这间教室上的第一堂课。
(2) 接下来,必须选择第一堂课结束后才开始的课。同样,你选择结束最早的课,这将是要
在这间教室上的第二堂课。
(3)每当一节可结束就找到下一节课结束最早的那节,以此循环。
就可以找出最优的结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZdwKOR9y-1585219671741)(9F8EDA2854A242A2BB76AB39BA6B184D)]
经过这个示例我们发现贪心算法其实就是找出局部问题的最优解,最终就是全局的最优解。
算法思路
活动安排问题的贪心算法设计思路如下:
- 预处理把所有的活动按照结束时间进行升序排列,有f’[1] < f[2] < … < f[n]
- 选择第一个活动选择结束时间最早的活动E[l],当前决策selected =1
- 贪心选择后续活动 依次扫描后续的每个活动E,如果E[i]的开始时间晚于上个选择的活动E[selected]的结束时间,则安排当前活动E[i],令selected = i;否则放弃E[i]。
算法实现(伪代码)
int greedyEventSchedul(int n,int *timeStart,int *timeFinish){
int i,j,selected,count=0;
for(i=0;i<n;i++)
for(j=0;j+1<n;j++) //冒泡排序使。结束时间按先后顺序排列
if(timeFinish[j]>timeFinish[j+1]){
swap(timeFinish[j],timeFinish[j+1]);
swap(timeStart[j],timeStart[j+1]); //开始时间与结束时间都需要重新排列
}
selected=0;//选择第一个活动
count=1;
for(i=1;i<n;i++)
if(timeStart[i]>=tmeFinish[selected]){//上一个课结束,同时下一节课开始
selected=i;
count++;
}//选择相容的最早活动
return count;
}
public class ActivitiesDemo {
public static int greedySelector(int[] s, int[] f, boolean[] a) {
int n = s.length - 1;
//安排第一个活动,标记为true
a[1] = true;
int j = 1;
int count = 1;
for (int i = 2; i <= n; i++) {
//检验当前最早结束的活动的开始时间是否晚于前一个活动的结束结束时间
if (s[i] >= f[j]) {
//如果晚于,则表示两个活动相互兼容,将活动标记为true
a[i] = true;
j = i;
//记已经安排活动的个数
count++;
} else {
//与已安排活动不兼容,标记此活动未安排
a[i] = false;
}
}
return count;
}
public static void main(String[] args) {
//初始化数据s数组记录活动开始时间;f数组记录活动结束时间
int[] s = { 1, 3, 0, 5, 3, 5, 6, 8, 8, 2, 12 };
int[] f = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
//声明一个boolean型数组
boolean[] a = new boolean[s.length];
int result = greedySelector(s, f, a);
System.out.println("Result is: " + result);
for (int i = 1; i <= s.length - 1; i++) {
if (a[i]) {
System.out.println("第" + i + "活动被选中,其开始时间为:" + s[i] + ",结束时间为:" + f[i]);
}
}
}
private void sort(){
int tmp;
int n= s . length ;
for ( int i=0;i<n;i++){
for ( int j=0;j<n;j++){
if (j<n-1 && f [j]> f [j+1]){
tmp= f [j];
f [j]= f [j+1];
f [j+1]=tmp;
tmp= s [j];
s [j]= s [j+1];
s [j+1]=tmp;